Add untracked harmony tests.

This has been deduped against :

libcore/luni/src/test/java/org/apache/harmony/luni/tests
libcore/luni/src/test/java/tests/api/
libcore/harmony-tests/src/test/java/tests/api

This is a minimal change that builds the entire test suite.
Many tests don't pass yet, they will be fixed in follow ups.

Notable tests that haven't been moved:
- ExcludedProxyTest: Might make requests to (now defunct)
  external servers. All of this code is tested in okhttp.
- URLClassLoaderTest: Has a dependency on jetty, tested in
  okhttp.

Notable test cases that haven't been moved:
- URLTest: overlap with okhttp, might make requests to
  external servers.
- ServerSocketTest#test_init: Uses Support_execJava, which
  we don't support yet. Isn't testing anything useful.
- FileTest#testDeleteOnExist: Uses Support_execJava which we don't
  support yet. This is a useful test and we must ressurect it if
  at all possible.

bug: 11650799

Change-Id: Ib277eb0bad465ea72b090168490a1a633611b3f3
diff --git a/luni/src/test/java/tests/api/internal/net/www/protocol/file/FileURLConnectionTest.java b/luni/src/test/java/tests/api/internal/net/www/protocol/file/FileURLConnectionTest.java
new file mode 100644
index 0000000..8ba38a0
--- /dev/null
+++ b/luni/src/test/java/tests/api/internal/net/www/protocol/file/FileURLConnectionTest.java
@@ -0,0 +1,100 @@
+/*
+ *  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.internal.net.www.protocol.file;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+
+import junit.framework.TestCase;
+
+import libcore.net.url.FileURLConnection;
+
+/**
+ * Tests for <code>FileURLConnection</code> class constructors and methods.
+ */
+public class FileURLConnectionTest extends TestCase {
+
+    static String getContentType(String fileName) throws IOException {
+        String resourceName = "org/apache/harmony/luni/tests/" + fileName;
+        URL url = ClassLoader.getSystemClassLoader().getResource(resourceName);
+        assertNotNull("Cannot find test resource " + resourceName, url);
+        return new FileURLConnection(url).getContentType();
+    }
+
+    public void testGetContentType() throws IOException {
+        // Regression for HARMONY-4699
+        assertEquals("application/rtf", getContentType("test.rtf"));
+        assertEquals("text/plain", getContentType("test.java"));
+        // RI would return "content/unknown"
+        assertEquals("application/msword", getContentType("test.doc"));
+        assertEquals("text/html", getContentType("test.htx"));
+        assertEquals("application/xml", getContentType("test.xml"));
+        assertEquals("text/plain", getContentType("."));
+    }
+
+    public void testGetInputStream() throws IOException {
+        // Regression for Harmony-5737
+        String resourceName = "org/apache/harmony/luni/tests/" + "test.rtf";
+        URL url = ClassLoader.getSystemClassLoader().getResource(resourceName);
+        URL anchorUrl = new URL(url, "#anchor");
+        assertNotNull("Cannot find test resource " + resourceName, anchorUrl);
+
+        FileURLConnection conn = new FileURLConnection(anchorUrl);
+        assertNotNull(conn.getInputStream());
+
+        // Regression for Harmony-5779
+        String localURLString = "file://localhost/" + url.getFile();
+        URL localURL = new URL(localURLString);
+        conn = new FileURLConnection(localURL);
+        assertNotNull(conn.getInputStream());
+        assertEquals("file", conn.getURL().getProtocol());
+    }
+
+    public void testHeaderFunctions() throws IOException {
+        String resourceName = "org/apache/harmony/luni/tests/";  //folder name
+        URL url = ClassLoader.getSystemClassLoader().getResource(resourceName);
+        FileURLConnection conn = new FileURLConnection(url);
+        assertNotNull(conn.getInputStream());
+        assertEquals(conn.getContentType(), conn.getHeaderField("content-type"));
+
+        resourceName = "org/apache/harmony/luni/tests/" + "test.rtf";
+        ;  //folder name
+        url = ClassLoader.getSystemClassLoader().getResource(resourceName);
+        conn = new FileURLConnection(url);
+        assertNotNull(conn.getInputStream());
+        assertEquals(conn.getContentType(), conn.getHeaderField("content-type"));
+        assertEquals(Integer.toString(conn.getContentLength()), conn.getHeaderField("content-length"));
+        assertEquals(conn.getHeaderField(0), conn.getHeaderField("content-type"));
+        assertEquals(conn.getHeaderField(1), conn.getHeaderField("content-length"));
+        assertEquals(conn.getHeaderField(2), conn.getHeaderField("last-modified"));
+        assertEquals("last-modified", conn.getHeaderFieldKey(2));
+        assertEquals("content-length", conn.getHeaderFieldKey(1));
+        assertEquals("content-type", conn.getHeaderFieldKey(0));
+    }
+
+    public void testHeader_BoundaryCheck() throws IOException {
+        String resourceName = "org/apache/harmony/luni/tests/";
+        URL url = ClassLoader.getSystemClassLoader().getResource(resourceName);
+        URLConnection urlConnection = url.openConnection();
+        assertNull(urlConnection.getHeaderField(Integer.MIN_VALUE));
+        assertNull(urlConnection.getHeaderField(Integer.MAX_VALUE));
+        assertNull(urlConnection.getHeaderFieldKey(Integer.MIN_VALUE));
+        assertNull(urlConnection.getHeaderFieldKey(Integer.MAX_VALUE));
+        assertNull(urlConnection.getHeaderField(null));
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/BufferedInputStreamTest.java b/luni/src/test/java/tests/api/java/io/BufferedInputStreamTest.java
new file mode 100644
index 0000000..3d16e74
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/BufferedInputStreamTest.java
@@ -0,0 +1,524 @@
+/*
+ *  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.io;
+
+import junit.framework.TestCase;
+import tests.support.Support_PlatformFile;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+
+public class BufferedInputStreamTest extends TestCase {
+
+    public String fileName;
+
+    private BufferedInputStream is;
+
+    private FileInputStream isFile;
+
+    private static final String INPUT = "Test_All_Tests\nTest_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";
+
+    /*
+     * java.io.BufferedInputStream(InputStream)
+     */
+    public void test_ConstructorLjava_io_InputStream() {
+        try {
+            BufferedInputStream str = new BufferedInputStream(null);
+            str.read();
+            fail("Expected an IOException");
+        } catch (IOException e) {
+            // Expected
+        }
+    }
+
+    /*
+     * java.io.BufferedInputStream(InputStream)
+     */
+    public void test_ConstructorLjava_io_InputStreamI() throws IOException {
+        try {
+            BufferedInputStream str = new BufferedInputStream(null, 1);
+            str.read();
+            fail("Expected an IOException");
+        } catch (IOException e) {
+            // Expected
+        }
+
+        // Test for method java.io.BufferedInputStream(java.io.InputStream, int)
+
+        // Create buffer with exact size of file
+        is = new BufferedInputStream(isFile, this.INPUT.length());
+        // Ensure buffer gets filled by evaluating one read
+        is.read();
+        // Close underlying FileInputStream, all but 1 buffered bytes should
+        // still be available.
+        isFile.close();
+        // Read the remaining buffered characters, no IOException should
+        // occur.
+        is.skip(this.INPUT.length() - 2);
+        is.read();
+        try {
+            // is.read should now throw an exception because it will have to
+            // be filled.
+            is.read();
+            fail("Exception should have been triggered by read()");
+        } catch (IOException e) {
+            // Expected
+        }
+
+        // regression test for harmony-2407
+        new MockBufferedInputStream(null);
+        assertNotNull(MockBufferedInputStream.buf);
+        MockBufferedInputStream.buf = null;
+        new MockBufferedInputStream(null, 100);
+        assertNotNull(MockBufferedInputStream.buf);
+    }
+
+    static class MockBufferedInputStream extends BufferedInputStream {
+        static byte[] buf;
+
+        MockBufferedInputStream(InputStream is) throws IOException {
+            super(is);
+            buf = super.buf;
+        }
+
+        MockBufferedInputStream(InputStream is, int size) throws IOException {
+            super(is, size);
+            buf = super.buf;
+        }
+    }
+
+    /**
+     * java.io.BufferedInputStream#available()
+     */
+    public void test_available() throws IOException {
+        assertTrue("Returned incorrect number of available bytes", is
+                .available() == INPUT.length());
+
+        // Test that a closed stream throws an IOE for available()
+        BufferedInputStream bis = new BufferedInputStream(
+                new ByteArrayInputStream(new byte[] { 'h', 'e', 'l', 'l', 'o',
+                        ' ', 't', 'i', 'm' }));
+        int available = bis.available();
+        bis.close();
+        assertTrue(available != 0);
+
+        try {
+            bis.available();
+            fail("Expected test to throw IOE.");
+        } catch (IOException ex) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.BufferedInputStream#close()
+     */
+    public void test_close() throws IOException {
+        new BufferedInputStream(isFile).close();
+
+        // regression for HARMONY-667
+        BufferedInputStream buf = new BufferedInputStream(null, 5);
+        buf.close();
+
+        InputStream in = new InputStream() {
+            Object lock = new Object();
+
+            @Override
+            public int read() {
+                return 1;
+            }
+
+            @Override
+            public int read(byte[] buf, int offset, int length) {
+                synchronized (lock) {
+                    try {
+                        lock.wait(3000);
+                    } catch (InterruptedException e) {
+                        // Ignore
+                    }
+                }
+                return 1;
+            }
+
+            @Override
+            public void close() {
+                synchronized (lock) {
+                    lock.notifyAll();
+                }
+            }
+        };
+        final BufferedInputStream bufin = new BufferedInputStream(in);
+        Thread thread = new Thread(new Runnable() {
+            public void run() {
+                try {
+                    Thread.sleep(1000);
+                    bufin.close();
+                } catch (Exception e) {
+                    // Ignored
+                }
+            }
+        });
+        thread.start();
+        try {
+            bufin.read(new byte[100], 0, 99);
+            fail("Should throw IOException");
+        } catch (IOException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.io.BufferedInputStream#mark(int)
+     */
+    public void test_markI() throws IOException {
+        byte[] buf1 = new byte[100];
+        byte[] buf2 = new byte[100];
+        is.skip(3000);
+        is.mark(1000);
+        is.read(buf1, 0, buf1.length);
+        is.reset();
+        is.read(buf2, 0, buf2.length);
+        is.reset();
+        assertTrue("Failed to mark correct position", new String(buf1, 0,
+                buf1.length).equals(new String(buf2, 0, buf2.length)));
+
+        byte[] bytes = new byte[256];
+        for (int i = 0; i < 256; i++) {
+            bytes[i] = (byte) i;
+        }
+        InputStream in = new BufferedInputStream(
+                new ByteArrayInputStream(bytes), 12);
+        in.skip(6);
+        in.mark(14);
+        in.read(new byte[14], 0, 14);
+        in.reset();
+        assertTrue("Wrong bytes", in.read() == 6 && in.read() == 7);
+
+        in = new BufferedInputStream(new ByteArrayInputStream(bytes), 12);
+        in.skip(6);
+        in.mark(8);
+        in.skip(7);
+        in.reset();
+        assertTrue("Wrong bytes 2", in.read() == 6 && in.read() == 7);
+
+        BufferedInputStream buf = new BufferedInputStream(
+                new ByteArrayInputStream(new byte[] { 0, 1, 2, 3, 4 }), 2);
+        buf.mark(3);
+        bytes = new byte[3];
+        int result = buf.read(bytes);
+        assertEquals(3, result);
+        assertEquals("Assert 0:", 0, bytes[0]);
+        assertEquals("Assert 1:", 1, bytes[1]);
+        assertEquals("Assert 2:", 2, bytes[2]);
+        assertEquals("Assert 3:", 3, buf.read());
+
+        buf = new BufferedInputStream(new ByteArrayInputStream(new byte[] { 0,
+                1, 2, 3, 4 }), 2);
+        buf.mark(3);
+        bytes = new byte[4];
+        result = buf.read(bytes);
+        assertEquals(4, result);
+        assertEquals("Assert 4:", 0, bytes[0]);
+        assertEquals("Assert 5:", 1, bytes[1]);
+        assertEquals("Assert 6:", 2, bytes[2]);
+        assertEquals("Assert 7:", 3, bytes[3]);
+        assertEquals("Assert 8:", 4, buf.read());
+        assertEquals("Assert 9:", -1, buf.read());
+
+        buf = new BufferedInputStream(new ByteArrayInputStream(new byte[] { 0,
+                1, 2, 3, 4 }), 2);
+        buf.mark(Integer.MAX_VALUE);
+        buf.read();
+        buf.close();
+    }
+
+    /**
+     * java.io.BufferedInputStream#markSupported()
+     */
+    public void test_markSupported() {
+        assertTrue("markSupported returned incorrect value", is.markSupported());
+    }
+
+    /**
+     * java.io.BufferedInputStream#read()
+     */
+    public void test_read() throws IOException {
+        InputStreamReader isr = new InputStreamReader(is);
+        int c = isr.read();
+        assertTrue("read returned incorrect char", c == INPUT.charAt(0));
+
+        byte[] bytes = new byte[256];
+        for (int i = 0; i < 256; i++) {
+            bytes[i] = (byte) i;
+        }
+        InputStream in = new BufferedInputStream(
+                new ByteArrayInputStream(bytes), 12);
+        assertEquals("Wrong initial byte", 0, in.read()); // Fill the
+        // buffer
+        byte[] buf = new byte[14];
+        in.read(buf, 0, 14); // Read greater than the buffer
+        assertTrue("Wrong block read data", new String(buf, 0, 14)
+                .equals(new String(bytes, 1, 14)));
+        assertEquals("Wrong bytes", 15, in.read()); // Check next byte
+    }
+
+    /**
+     * java.io.BufferedInputStream#read(byte[], int, int)
+     */
+    public void test_read$BII_Exception() throws IOException {
+        BufferedInputStream bis = new BufferedInputStream(null);
+        try {
+            bis.read(null, -1, -1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bis.read(new byte[0], -1, -1);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            bis.read(new byte[0], 1, -1);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            bis.read(new byte[0], 1, 1);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        bis.close();
+
+        try {
+            bis.read(null, -1, -1);
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.BufferedInputStream#read(byte[], int, int)
+     */
+    public void test_read$BII() throws IOException {
+        byte[] buf1 = new byte[100];
+        is.skip(3000);
+        is.mark(1000);
+        is.read(buf1, 0, buf1.length);
+        assertTrue("Failed to read correct data", new String(buf1, 0,
+                buf1.length).equals(INPUT.substring(3000, 3100)));
+
+        BufferedInputStream bufin = new BufferedInputStream(new InputStream() {
+            int size = 2
+                    ,
+                    pos = 0;
+
+            byte[] contents = new byte[size];
+
+            @Override
+            public int read() throws IOException {
+                if (pos >= size) {
+                    throw new IOException("Read past end of data");
+                }
+                return contents[pos++];
+            }
+
+            @Override
+            public int read(byte[] buf, int off, int len) throws IOException {
+                if (pos >= size) {
+                    throw new IOException("Read past end of data");
+                }
+                int toRead = len;
+                if (toRead > available()) {
+                    toRead = available();
+                }
+                System.arraycopy(contents, pos, buf, off, toRead);
+                pos += toRead;
+                return toRead;
+            }
+
+            @Override
+            public int available() {
+                return size - pos;
+            }
+        });
+        bufin.read();
+        int result = bufin.read(new byte[2], 0, 2);
+        assertTrue("Incorrect result: " + result, result == 1);
+    }
+
+    /**
+     * java.io.BufferedInputStream#reset()
+     */
+    public void test_reset() throws IOException {
+        byte[] buf1 = new byte[10];
+        byte[] buf2 = new byte[10];
+        is.mark(2000);
+        is.read(buf1, 0, 10);
+        is.reset();
+        is.read(buf2, 0, 10);
+        is.reset();
+        assertTrue("Reset failed", new String(buf1, 0, buf1.length)
+                .equals(new String(buf2, 0, buf2.length)));
+
+        BufferedInputStream bIn = new BufferedInputStream(
+                new ByteArrayInputStream("1234567890".getBytes()));
+        bIn.mark(10);
+        for (int i = 0; i < 11; i++) {
+            bIn.read();
+        }
+        bIn.reset();
+    }
+
+    /**
+     * java.io.BufferedInputStream#reset()
+     */
+    public void test_reset_Exception() throws IOException {
+        BufferedInputStream bis = new BufferedInputStream(null);
+
+        // throws IOException with message "Mark has been invalidated"
+        try {
+            bis.reset();
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+
+        // does not throw IOException
+        bis.mark(1);
+        bis.reset();
+
+        bis.close();
+
+        // throws IOException with message "stream is closed"
+        try {
+            bis.reset();
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.BufferedInputStream#reset()
+     */
+    public void test_reset_scenario1() throws IOException {
+        byte[] input = "12345678900".getBytes();
+        BufferedInputStream buffis = new BufferedInputStream(
+                new ByteArrayInputStream(input));
+        buffis.read();
+        buffis.mark(5);
+        buffis.skip(5);
+        buffis.reset();
+    }
+
+    /**
+     * java.io.BufferedInputStream#reset()
+     */
+    public void test_reset_scenario2() throws IOException {
+        byte[] input = "12345678900".getBytes();
+        BufferedInputStream buffis = new BufferedInputStream(
+                new ByteArrayInputStream(input));
+        buffis.mark(5);
+        buffis.skip(6);
+        buffis.reset();
+    }
+
+    /**
+     * java.io.BufferedInputStream#skip(long)
+     */
+    public void test_skipJ() throws IOException {
+        byte[] buf1 = new byte[10];
+        is.mark(2000);
+        is.skip(1000);
+        is.read(buf1, 0, buf1.length);
+        is.reset();
+        assertTrue("Failed to skip to correct position", new String(buf1, 0,
+                buf1.length).equals(INPUT.substring(1000, 1010)));
+
+        // regression for HARMONY-667
+        try {
+            BufferedInputStream buf = new BufferedInputStream(null, 5);
+            buf.skip(10);
+            fail("Should throw IOException");
+        } catch (IOException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.io.BufferedInputStream#skip(long)
+     */
+    public void test_skip_NullInputStream() throws IOException {
+        BufferedInputStream buf = new BufferedInputStream(null, 5);
+        assertEquals(0, buf.skip(0));
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    @Override
+    protected void setUp() throws IOException {
+        fileName = System.getProperty("user.dir");
+        String separator = System.getProperty("file.separator");
+        if (fileName.charAt(fileName.length() - 1) == separator.charAt(0)) {
+            fileName = Support_PlatformFile.getNewPlatformFile(fileName,
+                    "input.tst");
+        } else {
+            fileName = Support_PlatformFile.getNewPlatformFile(fileName
+                    + separator, "input.tst");
+        }
+        OutputStream fos = new FileOutputStream(fileName);
+        fos.write(INPUT.getBytes());
+        fos.close();
+        isFile = new FileInputStream(fileName);
+        is = new BufferedInputStream(isFile);
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    @Override
+    protected void tearDown() {
+        try {
+            is.close();
+        } catch (Exception e) {
+        }
+        try {
+            File f = new File(fileName);
+            f.delete();
+        } catch (Exception e) {
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/BufferedOutputStreamTest.java b/luni/src/test/java/tests/api/java/io/BufferedOutputStreamTest.java
new file mode 100644
index 0000000..12cb0d7
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/BufferedOutputStreamTest.java
@@ -0,0 +1,849 @@
+/*
+ *  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.io;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class BufferedOutputStreamTest extends junit.framework.TestCase {
+
+    private java.io.OutputStream os;
+
+    java.io.ByteArrayOutputStream baos;
+
+    java.io.ByteArrayInputStream bais;
+
+    public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_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";
+
+    /**
+     * java.io.BufferedOutputStream#BufferedOutputStream(java.io.OutputStream)
+     */
+    public void test_ConstructorLjava_io_OutputStream() throws IOException {
+        baos = new java.io.ByteArrayOutputStream();
+        os = new java.io.BufferedOutputStream(baos);
+        os.write(fileString.getBytes(), 0, 500);
+    }
+
+    /**
+     * java.io.BufferedOutputStream#BufferedOutputStream(java.io.OutputStream,
+     *int)
+     */
+    public void test_ConstructorLjava_io_OutputStreamI() throws IOException {
+        baos = new java.io.ByteArrayOutputStream();
+        os = new java.io.BufferedOutputStream(baos, 1024);
+        os.write(fileString.getBytes(), 0, 500);
+    }
+
+    public void test_flush_Constructor_NullStream() throws IOException {
+        BufferedOutputStream buffos = new java.io.BufferedOutputStream(null);
+        try {
+            buffos.flush();
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            buffos.close();
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        buffos = new java.io.BufferedOutputStream(null, 10);
+        try {
+            buffos.flush();
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            buffos.close();
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            new java.io.BufferedOutputStream(null, 0);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            new java.io.BufferedOutputStream(null, -1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.io.BufferedOutputStream#flush()
+     */
+    public void test_flush() throws IOException {
+        baos = new ByteArrayOutputStream();
+        os = new java.io.BufferedOutputStream(baos, 600);
+        os.write(fileString.getBytes(), 0, 500);
+        os.flush();
+        assertEquals("Bytes not written after flush", 500,
+                ((ByteArrayOutputStream) baos).size());
+    }
+
+    private static class MockOutputStream extends OutputStream {
+        byte[] written;
+        int count;
+
+        public MockOutputStream(int size) {
+            written = new byte[size];
+            count = 0;
+        }
+
+        public void write(int b) {
+            written[count++] = (byte) b;
+        }
+
+        public String getWritten() {
+            return new String(written, 0, count);
+        }
+    }
+
+    /**
+     * java.io.BufferedOutputStream#write(byte[], int, int)
+     */
+    public void test_write$BII() throws IOException {
+        os = new BufferedOutputStream(baos = new ByteArrayOutputStream(), 512);
+        os.write(fileString.getBytes(), 0, 500);
+        bais = new ByteArrayInputStream(baos.toByteArray());
+        assertEquals("Bytes written, not buffered", 0, bais.available());
+        os.flush();
+        bais = new ByteArrayInputStream(baos.toByteArray());
+        assertEquals("Bytes not written after flush", 500, bais.available());
+        os.write(fileString.getBytes(), 500, 513);
+        bais = new ByteArrayInputStream(baos.toByteArray());
+        assertTrue("Bytes not written when buffer full",
+                bais.available() >= 1000);
+        byte[] wbytes = new byte[1013];
+        bais.read(wbytes, 0, 1013);
+        assertEquals("Incorrect bytes written", new String(wbytes, 0,
+                wbytes.length), fileString.substring(0, 1013));
+
+        // regression test for HARMONY-4177
+        MockOutputStream mos = new MockOutputStream(5);
+        BufferedOutputStream bos = new BufferedOutputStream(mos, 3);
+        bos.write("a".getBytes());
+        bos.write("bcde".getBytes());
+        assertEquals("Large data should be written directly", "abcde", mos
+                .getWritten());
+        mos = new MockOutputStream(4);
+        bos = new BufferedOutputStream(mos, 3);
+        bos.write("ab".getBytes());
+        bos.write("cd".getBytes());
+        assertEquals("Should flush before write", "ab", mos.getWritten());
+    }
+
+    /**
+     * java.io.BufferedOutputStream#write(byte[], int, int)
+     */
+    public void test_write_$BII_Exception() throws IOException {
+        OutputStream bos = new BufferedOutputStream(new ByteArrayOutputStream());
+        byte[] nullByteArray = null;
+        byte[] byteArray = new byte[10];
+
+        try {
+            bos.write(nullByteArray, -1, -1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, -1, 0);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, -1, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, 0, -1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, 0, 0);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, 0, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, 1, -1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, 1, 0);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, 1, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(byteArray, -1, -1);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            bos.write(byteArray, -1, 0);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            bos.write(byteArray, -1, 1);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            bos.write(byteArray, 0, -1);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            bos.write(byteArray, 0, byteArray.length + 1);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            bos.write(byteArray, 1, byteArray.length);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            bos.write(byteArray, -1, byteArray.length);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            bos.write(byteArray, byteArray.length, -1);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        bos.write(byteArray, byteArray.length, 0);
+        try {
+            bos.write(byteArray, byteArray.length, 1);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        bos.write(byteArray, 0, 0);
+        bos.write(byteArray, 0, 1);
+        bos.write(byteArray, 1, byteArray.length - 1);
+        bos.write(byteArray, 0, byteArray.length);
+
+        try {
+            bos.write(byteArray, 1, -1);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        bos.write(byteArray, 1, 0);
+        bos.write(byteArray, 1, 1);
+
+        bos.write(byteArray, byteArray.length, 0);
+
+        try {
+            bos.write(byteArray, byteArray.length + 1, 0);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            bos.write(byteArray, byteArray.length + 1, 1);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        bos.close();
+
+        try {
+            bos.write(byteArray, -1, -1);
+            fail();
+        } catch (IOException expected) {
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        try {
+            bos.write(null, -1, -1);
+            fail();
+        } catch (IOException expected) {
+        } catch (NullPointerException expected) {
+        }
+
+        try {
+            bos.write(null, 0, 1);
+            fail();
+        } catch (IOException expected) {
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    /**
+     * java.io.BufferedOutputStream#write(byte[], int, int)
+     */
+    public void test_write_$BII_NullStream_NullArray() throws IOException {
+        OutputStream bos = new BufferedOutputStream(null);
+        byte[] nullByteArray = null;
+
+        try {
+            bos.write(nullByteArray, -1, -1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, 0, -1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, 1, -1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, -1, 0);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, 0, 0);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, 1, 0);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, -1, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, 0, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, 1, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.BufferedOutputStream#write(byte[], int, int)
+     */
+    public void test_write_$BII_NullStream_NullArray_Size() throws IOException {
+        OutputStream bos = new BufferedOutputStream(null, 1);
+        byte[] nullByteArray = null;
+
+        try {
+            bos.write(nullByteArray, -1, -1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, 0, -1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, 1, -1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, -1, 0);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, 0, 0);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, 1, 0);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, -1, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, 0, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(nullByteArray, 1, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.BufferedOutputStream#write(byte[], int, int)
+     */
+    public void test_write_$BII_NullStream() throws IOException {
+        BufferedOutputStream bos = new BufferedOutputStream(null);
+        byte[] byteArray = new byte[10];
+
+        try {
+            bos.write(byteArray, -1, -1);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            bos.write(byteArray, 0, -1);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            bos.write(byteArray, 1, -1);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            bos.write(byteArray, -1, 0);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        bos.write(byteArray, 0, 0);
+
+        bos.write(byteArray, 1, 0);
+
+        bos.write(byteArray, byteArray.length, 0);
+
+        try {
+            bos.write(byteArray, byteArray.length + 1, 0);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            bos.write(byteArray, -1, 1);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        bos.write(byteArray, 0, 1);
+        bos.write(byteArray, 1, 1);
+
+        bos.write(byteArray, 0, byteArray.length);
+
+        try {
+            bos.write(byteArray, byteArray.length + 1, 1);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.BufferedOutputStream#write(byte[], int, int)
+     */
+    public void test_write_$BII_NullStream_Size() throws IOException {
+        BufferedOutputStream bos = new BufferedOutputStream(null, 1);
+        byte[] byteArray = new byte[10];
+
+        try {
+            bos.write(byteArray, -1, -1);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            bos.write(byteArray, 0, -1);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            bos.write(byteArray, 1, -1);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            bos.write(byteArray, -1, 0);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        bos.write(byteArray, 0, 0);
+
+        bos.write(byteArray, 1, 0);
+
+        bos.write(byteArray, byteArray.length, 0);
+
+        try {
+            bos.write(byteArray, byteArray.length + 1, 0);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            bos.write(byteArray, -1, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(byteArray, 0, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(byteArray, 0, byteArray.length);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(byteArray, 1, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bos.write(byteArray, byteArray.length + 1, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.BufferedOutputStream#write(int)
+     */
+    public void test_writeI() throws IOException {
+        baos = new java.io.ByteArrayOutputStream();
+        os = new java.io.BufferedOutputStream(baos);
+        os.write('t');
+        bais = new java.io.ByteArrayInputStream(baos.toByteArray());
+        assertEquals("Byte written, not buffered", 0, bais.available());
+        os.flush();
+        bais = new java.io.ByteArrayInputStream(baos.toByteArray());
+        assertEquals("Byte not written after flush", 1, bais.available());
+        byte[] wbytes = new byte[1];
+        bais.read(wbytes, 0, 1);
+        assertEquals("Incorrect byte written", 't', wbytes[0]);
+    }
+
+    public void test_write_Close() throws IOException {
+        BufferedOutputStream buffos = new BufferedOutputStream(
+                new ByteArrayOutputStream());
+        buffos.write(new byte[0]);
+        try {
+            buffos.write(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        byte[] buffer = "1234567890".getBytes();
+
+        buffos.write(Integer.MIN_VALUE);
+        buffos.write(Integer.MAX_VALUE);
+        buffos.write(buffer, 0, 10);
+        buffos.flush();
+
+        buffos.close();
+    }
+
+    public void test_write_Scenario1() throws IOException {
+        ByteArrayOutputStream byteArrayos = new ByteArrayOutputStream();
+        ByteArrayInputStream byteArrayis = null;
+        byte[] buffer = "1234567890".getBytes("UTF-8");
+
+        BufferedOutputStream buffos = new BufferedOutputStream(byteArrayos, 10);
+        buffos.write(buffer, 0, 10);
+        byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+        assertEquals("Bytes written, not buffered", 10, byteArrayis.available());
+        buffos.flush();
+        byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+        assertEquals("Bytes not written after flush", 10, byteArrayis
+                .available());
+        for (int i = 0; i < 10; i++) {
+            assertEquals(buffer[i], byteArrayis.read());
+        }
+
+        buffos.write(buffer, 0, 10);
+        byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+        assertEquals("Bytes written, not buffered", 20, byteArrayis.available());
+        buffos.flush();
+        byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+        assertEquals("Bytes not written after flush", 20, byteArrayis
+                .available());
+        for (int i = 0; i < 10; i++) {
+            assertEquals(buffer[i], byteArrayis.read());
+        }
+        for (int i = 0; i < 10; i++) {
+            assertEquals(buffer[i], byteArrayis.read());
+        }
+
+        buffos.write(buffer, 0, 10);
+        byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+        assertEquals("Bytes written, not buffered", 30, byteArrayis.available());
+        buffos.flush();
+        byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+        assertEquals("Bytes not written after flush", 30, byteArrayis
+                .available());
+        for (int i = 0; i < 10; i++) {
+            assertEquals(buffer[i], byteArrayis.read());
+        }
+        for (int i = 0; i < 10; i++) {
+            assertEquals(buffer[i], byteArrayis.read());
+        }
+        for (int i = 0; i < 10; i++) {
+            assertEquals(buffer[i], byteArrayis.read());
+        }
+    }
+
+    public void test_write_Scenario2() throws IOException {
+        ByteArrayOutputStream byteArrayos = new ByteArrayOutputStream();
+        ByteArrayInputStream byteArrayis = null;
+        byte[] buffer = "1234567890".getBytes("UTF-8");
+
+        BufferedOutputStream buffos = new BufferedOutputStream(byteArrayos, 20);
+        buffos.write(buffer, 0, 10);
+        byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+        assertEquals("Bytes written, not buffered", 0, byteArrayis.available());
+        buffos.flush();
+        byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+        assertEquals("Bytes not written after flush", 10, byteArrayis
+                .available());
+        for (int i = 0; i < 10; i++) {
+            assertEquals(buffer[i], byteArrayis.read());
+        }
+
+        byte[] buffer2 = new byte[] { 'a', 'b', 'c', 'd' };
+        buffos.write(buffer2, 0, 4);
+        byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+        assertEquals("Bytes written, not buffered", 10, byteArrayis.available());
+        buffos.flush();
+        byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+        assertEquals("Bytes not written after flush", 14, byteArrayis
+                .available());
+        for (int i = 0; i < 10; i++) {
+            assertEquals(buffer[i], byteArrayis.read());
+        }
+        for (int i = 0; i < 4; i++) {
+            assertEquals(buffer2[i], byteArrayis.read());
+        }
+
+        byte[] buffer3 = new byte[] { 'e', 'f', 'g', 'h', 'i' };
+        buffos.write(buffer3, 0, 5);
+        byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+        assertEquals("Bytes written, not buffered", 14, byteArrayis.available());
+        buffos.flush();
+        byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+        assertEquals("Bytes not written after flush", 19, byteArrayis
+                .available());
+        for (int i = 0; i < 10; i++) {
+            assertEquals(buffer[i], byteArrayis.read());
+        }
+        for (int i = 0; i < 4; i++) {
+            assertEquals(buffer2[i], byteArrayis.read());
+        }
+        for (int i = 0; i < 5; i++) {
+            assertEquals(buffer3[i], byteArrayis.read());
+        }
+
+        buffos.write(new byte[] { 'j', 'k' });
+        byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+        assertEquals("Bytes written, not buffered", 19, byteArrayis.available());
+        buffos.flush();
+        byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+        assertEquals("Bytes not written after flush", 21, byteArrayis
+                .available());
+
+        buffos.close();
+    }
+
+    public void test_write_Scenario3() throws IOException {
+        ByteArrayOutputStream byteArrayos = new ByteArrayOutputStream();
+        ByteArrayInputStream byteArrayis = null;
+        byte[] buffer = "1234567890".getBytes("UTF-8");
+
+        BufferedOutputStream buffos = new BufferedOutputStream(byteArrayos, 5);
+        buffos.write(buffer, 0, 4);
+        byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+        assertEquals("Bytes written, not buffered", 0, byteArrayis.available());
+        buffos.flush();
+        byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+        assertEquals("Bytes not written after flush", 4, byteArrayis
+                .available());
+        for (int i = 0; i < 4; i++) {
+            assertEquals(buffer[i], byteArrayis.read());
+        }
+
+        buffos.write(buffer, 0, 5);
+        byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+        assertEquals("Bytes written, not buffered", 9, byteArrayis.available());
+        buffos.flush();
+        byteArrayis = new ByteArrayInputStream(byteArrayos.toByteArray());
+        assertEquals("Bytes not written after flush", 9, byteArrayis
+                .available());
+        for (int i = 0; i < 4; i++) {
+            assertEquals(buffer[i], byteArrayis.read());
+        }
+        for (int i = 0; i < 5; i++) {
+            assertEquals(buffer[i], byteArrayis.read());
+        }
+    }
+
+    // Regression test for flush on closed stream
+    public void test_flush_on_closed_stream() throws IOException {
+        BufferedOutputStream bos = new BufferedOutputStream(new ByteArrayOutputStream());
+        bos.close();
+        try {
+            bos.flush(); // RI does not throw exception
+        } catch (IOException expected) { // but Android does
+        }
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    protected void tearDown() throws IOException {
+        if (bais != null) {
+            bais.close();
+        }
+        if (os != null) {
+            os.close();
+        }
+        if (baos != null) {
+            baos.close();
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/BufferedWriterTest.java b/luni/src/test/java/tests/api/java/io/BufferedWriterTest.java
new file mode 100644
index 0000000..f4e2cdb
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/BufferedWriterTest.java
@@ -0,0 +1,302 @@
+/*
+ *  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.io;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+import tests.support.Support_StringWriter;
+
+public class BufferedWriterTest extends junit.framework.TestCase {
+
+    BufferedWriter bw;
+
+    Support_StringWriter sw;
+
+    public 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";
+
+    /**
+     * java.io.BufferedWriter#BufferedWriter(java.io.Writer)
+     */
+    public void test_ConstructorLjava_io_Writer() {
+        sw = new Support_StringWriter();
+        bw = new BufferedWriter(sw);
+        sw.write("Hi");
+        assertEquals("Constructor failed", "Hi", sw.toString());
+    }
+
+    /**
+     * java.io.BufferedWriter#BufferedWriter(java.io.Writer, int)
+     */
+    public void test_ConstructorLjava_io_WriterI() {
+        assertTrue("Used in tests", true);
+    }
+
+    private static class MockWriter extends Writer {
+        StringBuffer sb = new StringBuffer();
+        boolean flushCalled = false;
+
+        public void write(char[] buf, int off, int len) throws IOException {
+            for (int i = off; i < off + len; i++) {
+                sb.append(buf[i]);
+            }
+        }
+
+        public void close() throws IOException {
+            // Empty
+        }
+
+        public void flush() throws IOException {
+            flushCalled = true;
+        }
+
+        public String getWritten() {
+            return sb.toString();
+        }
+
+        public boolean isFlushCalled() {
+            return flushCalled;
+        }
+    }
+
+    /**
+     * java.io.BufferedWriter#close()
+     */
+    public void test_close() throws IOException {
+        try {
+            bw.close();
+            bw.write(testString);
+            fail("Writing to a closed stream should throw IOException");
+        } catch (IOException e) {
+            // Expected
+        }
+        assertTrue("Write after close", !sw.toString().equals(testString));
+
+        // Regression test for HARMONY-4178
+        MockWriter mw = new MockWriter();
+        BufferedWriter bw = new BufferedWriter(mw);
+        bw.write('a');
+        bw.close();
+
+        // flush should not be called on underlying stream
+        assertFalse("Flush was called in the underlying stream", mw
+                .isFlushCalled());
+
+        // on the other hand the BufferedWriter itself should flush the
+        // buffer
+        assertEquals("BufferdWriter do not flush itself before close", "a", mw
+                .getWritten());
+    }
+
+    /**
+     * @throws IOException
+     * java.io.BufferedWriter#close()
+     */
+    public void test_close2() throws IOException {
+        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new ByteArrayOutputStream()));
+        bw.close();
+    }
+
+    /**
+     * java.io.BufferedWriter#flush()
+     */
+    public void test_flush() throws Exception {
+        bw.write("This should not cause a flush");
+        assertTrue("Bytes written without flush", sw.toString().equals(""));
+        bw.flush();
+        assertEquals("Bytes not flushed", "This should not cause a flush", sw
+                .toString());
+    }
+
+    /**
+     * java.io.BufferedWriter#newLine()
+     */
+    public void test_newLine() throws Exception {
+        String separator = System.getProperty("line.separator");
+        bw.write("Hello");
+        bw.newLine();
+        bw.write("World");
+        bw.flush();
+        assertTrue("Incorrect string written: " + sw.toString(), sw.toString()
+                .equals("Hello" + separator + "World"));
+    }
+
+    /**
+     * java.io.BufferedWriter#write(char[], int, int)
+     */
+    public void test_write$CII() throws Exception {
+        char[] testCharArray = testString.toCharArray();
+        bw.write(testCharArray, 500, 1000);
+        bw.flush();
+        assertTrue("Incorrect string written", sw.toString().equals(
+                testString.substring(500, 1500)));
+    }
+
+    /**
+     * java.io.BufferedWriter#write(char[], int, int)
+     */
+    public void test_write_$CII_Exception() throws IOException {
+        BufferedWriter bWriter = new BufferedWriter(sw);
+        char[] nullCharArray = null;
+
+        try {
+            bWriter.write(nullCharArray, -1, -1);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (NullPointerException expected) {
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        try {
+            bWriter.write(nullCharArray, -1, 0);
+            fail();
+        } catch (NullPointerException expected) {
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        try {
+            bWriter.write(nullCharArray, 0, -1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            bWriter.write(nullCharArray, 0, 0);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        char[] testCharArray = testString.toCharArray();
+
+        bWriter.write(testCharArray, 0, 0);
+
+        bWriter.write(testCharArray, testCharArray.length, 0);
+
+        try {
+            bWriter.write(testCharArray, testCharArray.length + 1, 0);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        bWriter.close();
+
+        try {
+            bWriter.write(nullCharArray, -1, -1);
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.BufferedWriter#write(int)
+     */
+    public void test_writeI() throws Exception {
+        bw.write('T');
+        assertTrue("Char written without flush", sw.toString().equals(""));
+        bw.flush();
+        assertEquals("Incorrect char written", "T", sw.toString());
+    }
+
+    /**
+     * java.io.BufferedWriter#write(java.lang.String, int, int)
+     */
+    public void test_writeLjava_lang_StringII() throws Exception {
+        bw.write(testString);
+        bw.flush();
+        assertTrue("Incorrect string written", sw.toString().equals(testString));
+    }
+
+    /**
+     * java.io.BufferedWriter#write(java.lang.String, int, int)
+     */
+    public void test_write_LStringII_Exception() throws IOException {
+        BufferedWriter bWriter = new BufferedWriter(sw);
+
+        bWriter.write((String) null, -1, -1);
+        bWriter.write((String) null, -1, 0);
+        bWriter.write((String) null, 0, -1);
+        bWriter.write((String) null, 0, 0);
+
+        try {
+            bWriter.write((String) null, -1, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        bWriter.write(testString, 0, 0);
+        bWriter.write(testString, testString.length(), 0);
+        bWriter.write(testString, testString.length() + 1, 0);
+
+        try {
+            bWriter.write(testString, testString.length() + 1, 1);
+            fail("should throw StringIndexOutOfBoundsException");
+        } catch (StringIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        bWriter.close();
+
+        try {
+            bWriter.write((String) null, -1, -1);
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+
+        try {
+            bWriter.write((String) null, -1, 1);
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+
+        try {
+            bWriter.write(testString, -1, -1);
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() {
+        sw = new Support_StringWriter();
+        bw = new BufferedWriter(sw, 500);
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    protected void tearDown() {
+        try {
+            bw.close();
+        } catch (Exception e) {
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/ByteArrayInputStreamTest.java b/luni/src/test/java/tests/api/java/io/ByteArrayInputStreamTest.java
new file mode 100644
index 0000000..c10f9c5
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/ByteArrayInputStreamTest.java
@@ -0,0 +1,180 @@
+/*
+ *  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.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class ByteArrayInputStreamTest extends junit.framework.TestCase {
+
+    private InputStream is;
+
+    public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\n";
+
+    /**
+     * ByteArrayInputStream#ByteArrayInputStream(byte[])
+     */
+    public void test_Constructor$B() throws IOException {
+        InputStream bis = new ByteArrayInputStream(fileString.getBytes());
+
+        assertTrue("Unable to create ByteArrayInputStream",
+                bis.available() == fileString.length());
+    }
+
+    /**
+     * ByteArrayInputStream#ByteArrayInputStream(byte[], int, int)
+     */
+    public void test_Constructor$BII() throws IOException {
+        byte[] zz = fileString.getBytes();
+        InputStream bis = new ByteArrayInputStream(zz, 0, 100);
+
+        assertEquals("Unable to create ByteArrayInputStream", 100, bis
+                .available());
+
+        // Regression test for Harmony-2405
+        new SubByteArrayInputStream(new byte[] { 1, 2 }, 444, 13);
+        assertEquals(444, SubByteArrayInputStream.pos);
+        assertEquals(444, SubByteArrayInputStream.mark);
+        assertEquals(2, SubByteArrayInputStream.count);
+    }
+
+    static class SubByteArrayInputStream extends ByteArrayInputStream {
+        public static byte[] buf;
+
+        public static int mark, pos, count;
+
+        SubByteArrayInputStream(byte[] buf, int offset, int length)
+                throws IOException {
+            super(buf, offset, length);
+            buf = super.buf;
+            mark = super.mark;
+            pos = super.pos;
+            count = super.count;
+        }
+    }
+
+    /**
+     * ByteArrayInputStream#available()
+     */
+    public void test_available() throws IOException {
+        assertTrue("Returned incorrect number of available bytes", is
+                .available() == fileString.length());
+    }
+
+    /**
+     * ByteArrayInputStream#close()
+     */
+    public void test_close() throws IOException {
+        is.read();
+        is.close();
+        is.read(); // Should be able to read from a closed stream
+    }
+
+    /**
+     * ByteArrayInputStream#mark(int)
+     */
+    public void test_markI() throws IOException {
+        byte[] buf1 = new byte[100];
+        byte[] buf2 = new byte[100];
+        is.skip(3000);
+        is.mark(1000);
+        is.read(buf1, 0, buf1.length);
+        is.reset();
+        is.read(buf2, 0, buf2.length);
+        is.reset();
+        assertTrue("Failed to mark correct position", new String(buf1, 0,
+                buf1.length).equals(new String(buf2, 0, buf2.length)));
+    }
+
+    /**
+     * ByteArrayInputStream#markSupported()
+     */
+    public void test_markSupported() {
+        assertTrue("markSupported returned incorrect value", is.markSupported());
+    }
+
+    /**
+     * ByteArrayInputStream#read()
+     */
+    public void test_read() throws IOException {
+        InputStreamReader isr = new InputStreamReader(is);
+        int c = isr.read();
+        is.reset();
+        assertTrue("read returned incorrect char", c == fileString.charAt(0));
+    }
+
+    /**
+     * ByteArrayInputStream#read(byte[], int, int)
+     */
+    public void test_read$BII() throws IOException {
+        byte[] buf1 = new byte[20];
+        is.skip(50);
+        is.mark(100);
+        is.read(buf1, 0, buf1.length);
+        assertTrue("Failed to read correct data", new String(buf1, 0,
+                buf1.length).equals(fileString.substring(50, 70)));
+    }
+
+    /**
+     * ByteArrayInputStream#reset()
+     */
+    public void test_reset() throws IOException {
+        byte[] buf1 = new byte[10];
+        byte[] buf2 = new byte[10];
+        is.mark(200);
+        is.read(buf1, 0, 10);
+        is.reset();
+        is.read(buf2, 0, 10);
+        is.reset();
+        assertTrue("Reset failed", new String(buf1, 0, buf1.length)
+                .equals(new String(buf2, 0, buf2.length)));
+    }
+
+    /**
+     * ByteArrayInputStream#skip(long)
+     */
+    public void test_skipJ() throws IOException {
+        byte[] buf1 = new byte[10];
+        is.skip(100);
+        is.read(buf1, 0, buf1.length);
+        assertTrue("Failed to skip to correct position", new String(buf1, 0,
+                buf1.length).equals(fileString.substring(100, 110)));
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() {
+        is = new ByteArrayInputStream(fileString.getBytes());
+
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    protected void tearDown() {
+        try {
+            is.close();
+        } catch (Exception e) {
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/ByteArrayOutputStreamTest.java b/luni/src/test/java/tests/api/java/io/ByteArrayOutputStreamTest.java
new file mode 100644
index 0000000..cee1df4
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/ByteArrayOutputStreamTest.java
@@ -0,0 +1,213 @@
+/*
+ *  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.io;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+import junit.framework.TestCase;
+
+/**
+ * Automated Test Suite for class java.io.ByteArrayOutputStream
+ *
+ * @see java.io.ByteArrayOutputStream
+ */
+public class ByteArrayOutputStreamTest extends TestCase {
+
+    ByteArrayOutputStream bos = null;
+
+    public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_ByteArrayOutputStream\nTest_java_io_DataInputStream\n";
+
+    /**
+     * 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 {
+            bos.close();
+        } catch (Exception ignore) {
+        }
+        super.tearDown();
+    }
+
+    /**
+     * java.io.ByteArrayOutputStream#ByteArrayOutputStream(int)
+     */
+    public void test_ConstructorI() {
+        bos = new ByteArrayOutputStream(100);
+        assertEquals("Failed to create stream", 0, bos.size());
+    }
+
+    /**
+     * java.io.ByteArrayOutputStream#ByteArrayOutputStream()
+     */
+    public void test_Constructor() {
+        bos = new ByteArrayOutputStream();
+        assertEquals("Failed to create stream", 0, bos.size());
+    }
+
+    /**
+     * java.io.ByteArrayOutputStream#close()
+     */
+    public void test_close() {
+        // close() does nothing for this implementation of OutputSteam
+
+        // The spec seems to say that a closed output stream can't be written
+        // to. We don't throw an exception if attempt is made to write.
+        // Right now our implementation doesn't do anything testable but
+        // should we decide to throw an exception if a closed stream is
+        // written to, the appropriate test is commented out below.
+
+        /***********************************************************************
+         * java.io.ByteArrayOutputStream bos = new
+         * java.io.ByteArrayOutputStream(); bos.write (fileString.getBytes(), 0,
+         * 100); try { bos.close(); } catch (java.io.IOException e) {
+         * fail("IOException closing stream"); } try { bos.write
+         * (fileString.getBytes(), 0, 100); bos.toByteArray(); fail("Wrote to
+         * closed stream"); } catch (Exception e) { }
+         **********************************************************************/
+    }
+
+    /**
+     * java.io.ByteArrayOutputStream#reset()
+     */
+    public void test_reset() {
+        bos = new java.io.ByteArrayOutputStream();
+        bos.write(fileString.getBytes(), 0, 100);
+        bos.reset();
+        assertEquals("reset failed", 0, bos.size());
+    }
+
+    /**
+     * java.io.ByteArrayOutputStream#size()
+     */
+    public void test_size() {
+        bos = new java.io.ByteArrayOutputStream();
+        bos.write(fileString.getBytes(), 0, 100);
+        assertEquals("size test failed", 100, bos.size());
+        bos.reset();
+        assertEquals("size test failed", 0, bos.size());
+    }
+
+    /**
+     * java.io.ByteArrayOutputStream#toByteArray()
+     */
+    public void test_toByteArray() {
+        byte[] bytes;
+        byte[] sbytes = fileString.getBytes();
+        bos = new java.io.ByteArrayOutputStream();
+        bos.write(fileString.getBytes(), 0, fileString.length());
+        bytes = bos.toByteArray();
+        for (int i = 0; i < fileString.length(); i++) {
+            assertTrue("Error in byte array", bytes[i] == sbytes[i]);
+        }
+    }
+
+    /**
+     * java.io.ByteArrayOutputStream#toString(java.lang.String)
+     */
+    public void test_toStringLjava_lang_String() throws IOException {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+        bos.write(fileString.getBytes("UTF-8"), 0, fileString.length());
+        assertTrue("Returned incorrect 8859-1 String", bos.toString("8859_1")
+                .equals(fileString));
+
+        bos = new ByteArrayOutputStream();
+        bos.write(fileString.getBytes("UTF-8"), 0, fileString.length());
+        assertTrue("Returned incorrect 8859-2 String", bos.toString("8859_2")
+                .equals(fileString));
+    }
+
+    /**
+     * java.io.ByteArrayOutputStream#toString()
+     */
+    public void test_toString() {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        bos.write(fileString.getBytes(), 0, fileString.length());
+        assertTrue("Returned incorrect String", bos.toString().equals(
+                fileString));
+    }
+
+    /**
+     * java.io.ByteArrayOutputStream#toString(int)
+     */
+    @SuppressWarnings("deprecation")
+    public void test_toStringI() {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        bos.write(fileString.getBytes(), 0, fileString.length());
+        assertTrue("Returned incorrect String",
+                bos.toString(5).length() == fileString.length());
+    }
+
+    /**
+     * java.io.ByteArrayOutputStream#write(int)
+     */
+    public void test_writeI() throws UnsupportedEncodingException {
+        bos = new ByteArrayOutputStream();
+        bos.write('t');
+        byte[] result = bos.toByteArray();
+        assertEquals("Wrote incorrect bytes", "t", new String(result, 0,
+                result.length, "UTF-8"));
+    }
+
+    /**
+     * java.io.ByteArrayOutputStream#write(byte[], int, int)
+     */
+    public void test_write$BII() {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        bos.write(fileString.getBytes(), 0, 100);
+        byte[] result = bos.toByteArray();
+        assertTrue("Wrote incorrect bytes",
+                new String(result, 0, result.length).equals(fileString
+                        .substring(0, 100)));
+    }
+
+    /**
+     * java.io.ByteArrayOutputStream#write(byte[], int, int)
+     */
+    public void test_write$BII_2() {
+        // Regression for HARMONY-387
+        ByteArrayOutputStream obj = new ByteArrayOutputStream();
+        try {
+            obj.write(new byte[] { (byte) 0x00 }, -1, 0);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+    }
+
+    /**
+     * java.io.ByteArrayOutputStream#writeTo(java.io.OutputStream)
+     */
+    public void test_writeToLjava_io_OutputStream() throws Exception {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        ByteArrayOutputStream bos2 = new ByteArrayOutputStream();
+        bos.write(fileString.getBytes(), 0, 100);
+        bos.writeTo(bos2);
+        assertTrue("Returned incorrect String", bos2.toString().equals(
+                fileString.substring(0, 100)));
+
+        // Regression test for HARMONY-834
+        // no exception expected
+        new ByteArrayOutputStream().writeTo(new FileOutputStream(
+                new FileDescriptor()));
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/CharArrayReaderTest.java b/luni/src/test/java/tests/api/java/io/CharArrayReaderTest.java
new file mode 100644
index 0000000..71ea6e3
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/CharArrayReaderTest.java
@@ -0,0 +1,178 @@
+/*
+ *  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.io;
+
+import java.io.CharArrayReader;
+import java.io.IOException;
+
+public class CharArrayReaderTest extends junit.framework.TestCase {
+
+    char[] hw = { 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' };
+
+    CharArrayReader cr;
+
+    /**
+     * java.io.CharArrayReader#CharArrayReader(char[])
+     */
+    public void test_Constructor$C() throws IOException {
+        cr = new CharArrayReader(hw);
+        assertTrue("Failed to create reader", cr.ready());
+    }
+
+    /**
+     * java.io.CharArrayReader#CharArrayReader(char[], int, int)
+     */
+    public void test_Constructor$CII() throws IOException {
+        cr = new CharArrayReader(hw, 5, 5);
+        assertTrue("Failed to create reader", cr.ready());
+
+        int c = cr.read();
+        assertTrue("Created incorrect reader--returned '" + (char) c
+                + "' intsead of 'W'", c == 'W');
+    }
+
+    /**
+     * java.io.CharArrayReader#close()
+     */
+    public void test_close() {
+        cr = new CharArrayReader(hw);
+        cr.close();
+        try {
+            cr.read();
+            fail("Failed to throw exception on read from closed stream");
+        } catch (IOException e) {
+            // Expected
+        }
+
+        // No-op
+        cr.close();
+    }
+
+    /**
+     * java.io.CharArrayReader#mark(int)
+     */
+    public void test_markI() throws IOException {
+        cr = new CharArrayReader(hw);
+        cr.skip(5L);
+        cr.mark(100);
+        cr.read();
+        cr.reset();
+        assertEquals("Failed to mark correct position", 'W', cr.read());
+    }
+
+    /**
+     * java.io.CharArrayReader#markSupported()
+     */
+    public void test_markSupported() {
+        cr = new CharArrayReader(hw);
+        assertTrue("markSupported returned false", cr.markSupported());
+    }
+
+    /**
+     * java.io.CharArrayReader#read()
+     */
+    public void test_read() throws IOException {
+        cr = new CharArrayReader(hw);
+        assertEquals("Read returned incorrect char", 'H', cr.read());
+        cr = new CharArrayReader(new char[] { '\u8765' });
+        assertTrue("Incorrect double byte char", cr.read() == '\u8765');
+    }
+
+    /**
+     * java.io.CharArrayReader#read(char[], int, int)
+     */
+    public void test_read$CII() throws IOException {
+        char[] c = new char[11];
+        cr = new CharArrayReader(hw);
+        cr.read(c, 1, 10);
+        assertTrue("Read returned incorrect chars", new String(c, 1, 10)
+                .equals(new String(hw, 0, 10)));
+    }
+
+    /**
+     * java.io.CharArrayReader#ready()
+     */
+    public void test_ready() throws IOException {
+        cr = new CharArrayReader(hw);
+        assertTrue("ready returned false", cr.ready());
+        cr.skip(1000);
+        assertTrue("ready returned true", !cr.ready());
+        cr.close();
+
+        try {
+            cr.ready();
+            fail("No exception 1");
+        } catch (IOException e) {
+            // expected
+        }
+        try {
+            cr = new CharArrayReader(hw);
+            cr.close();
+            cr.ready();
+            fail("No exception 2");
+        } catch (IOException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.CharArrayReader#reset()
+     */
+    public void test_reset() throws IOException {
+        cr = new CharArrayReader(hw);
+        cr.skip(5L);
+        cr.mark(100);
+        cr.read();
+        cr.reset();
+        assertEquals("Reset failed to return to marker position", 'W', cr
+                .read());
+
+        // Regression for HARMONY-4357
+        String str = "offsetHello world!";
+        char[] data = new char[str.length()];
+        str.getChars(0, str.length(), data, 0);
+        int offsetLength = 6;
+        int length = data.length - offsetLength;
+
+        CharArrayReader reader = new CharArrayReader(data, offsetLength, length);
+        reader.reset();
+        for (int i = 0; i < length; i++) {
+            assertEquals(data[offsetLength + i], (char) reader.read());
+        }
+    }
+
+    /**
+     * java.io.CharArrayReader#skip(long)
+     */
+    public void test_skipJ() throws IOException {
+        cr = new CharArrayReader(hw);
+        long skipped = cr.skip(5L);
+
+        assertEquals("Failed to skip correct number of chars", 5L, skipped);
+        assertEquals("Skip skipped wrong chars", 'W', cr.read());
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    protected void tearDown() {
+        if (cr != null)
+            cr.close();
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/CharArrayWriterTest.java b/luni/src/test/java/tests/api/java/io/CharArrayWriterTest.java
new file mode 100644
index 0000000..407c286
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/CharArrayWriterTest.java
@@ -0,0 +1,233 @@
+/*
+ *  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.io;
+
+import java.io.CharArrayReader;
+import java.io.CharArrayWriter;
+import java.io.IOException;
+import java.io.StringWriter;
+
+public class CharArrayWriterTest extends junit.framework.TestCase {
+
+    char[] hw = { 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' };
+
+    CharArrayWriter cw;
+
+    CharArrayReader cr;
+
+    /**
+     * java.io.CharArrayWriter#CharArrayWriter()
+     */
+    public void test_Constructor() {
+        cw = new CharArrayWriter(90);
+        assertEquals("Created incorrect writer", 0, cw.size());
+    }
+
+    /**
+     * java.io.CharArrayWriter#CharArrayWriter(int)
+     */
+    public void test_ConstructorI() {
+        cw = new CharArrayWriter();
+        assertEquals("Created incorrect writer", 0, cw.size());
+    }
+
+    /**
+     * java.io.CharArrayWriter#close()
+     */
+    public void test_close() {
+        cw.close();
+    }
+
+    /**
+     * java.io.CharArrayWriter#flush()
+     */
+    public void test_flush() {
+        cw.flush();
+    }
+
+    /**
+     * java.io.CharArrayWriter#reset()
+     */
+    public void test_reset() throws IOException {
+        cw.write("HelloWorld", 5, 5);
+        cw.reset();
+        cw.write("HelloWorld", 0, 5);
+        cr = new CharArrayReader(cw.toCharArray());
+        char[] c = new char[100];
+        cr.read(c, 0, 5);
+        assertEquals("Reset failed to reset buffer", "Hello", new String(c, 0,
+                5));
+    }
+
+    /**
+     * java.io.CharArrayWriter#size()
+     */
+    public void test_size() {
+        assertEquals("Returned incorrect size", 0, cw.size());
+        cw.write(hw, 5, 5);
+        assertEquals("Returned incorrect size", 5, cw.size());
+    }
+
+    /**
+     * java.io.CharArrayWriter#toCharArray()
+     */
+    public void test_toCharArray() throws IOException {
+        cw.write("HelloWorld", 0, 10);
+        cr = new CharArrayReader(cw.toCharArray());
+        char[] c = new char[100];
+        cr.read(c, 0, 10);
+        assertEquals("toCharArray failed to return correct array",
+                "HelloWorld", new String(c, 0, 10));
+    }
+
+    /**
+     * java.io.CharArrayWriter#toString()
+     */
+    public void test_toString() {
+        cw.write("HelloWorld", 5, 5);
+        cr = new CharArrayReader(cw.toCharArray());
+        assertEquals("Returned incorrect string", "World", cw.toString());
+    }
+
+    /**
+     * java.io.CharArrayWriter#write(char[], int, int)
+     */
+    public void test_write$CII() throws IOException {
+        cw.write(hw, 5, 5);
+        cr = new CharArrayReader(cw.toCharArray());
+        char[] c = new char[100];
+        cr.read(c, 0, 5);
+        assertEquals("Writer failed to write correct chars", "World",
+                new String(c, 0, 5));
+    }
+
+    /**
+     * java.io.CharArrayWriter#write(char[], int, int)
+     */
+    public void test_write$CII_2() {
+        // Regression for HARMONY-387
+        CharArrayWriter obj = new CharArrayWriter();
+        try {
+            obj.write(new char[] { '0' }, 0, -1);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+    }
+
+    /**
+     * java.io.CharArrayWriter#write(int)
+     */
+    public void test_writeI() throws IOException {
+        cw.write('T');
+        cr = new CharArrayReader(cw.toCharArray());
+        assertEquals("Writer failed to write char", 'T', cr.read());
+    }
+
+    /**
+     * java.io.CharArrayWriter#write(java.lang.String, int, int)
+     */
+    public void test_writeLjava_lang_StringII() throws IOException {
+        cw.write("HelloWorld", 5, 5);
+        cr = new CharArrayReader(cw.toCharArray());
+        char[] c = new char[100];
+        cr.read(c, 0, 5);
+        assertEquals("Writer failed to write correct chars", "World",
+                new String(c, 0, 5));
+    }
+
+    /**
+     * java.io.CharArrayWriter#write(java.lang.String, int, int)
+     */
+    public void test_writeLjava_lang_StringII_2()
+            throws StringIndexOutOfBoundsException {
+        // Regression for HARMONY-387
+        CharArrayWriter obj = new CharArrayWriter();
+        try {
+            obj.write((String) null, -1, 0);
+            fail("NullPointerException expected");
+        } catch (NullPointerException t) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.io.CharArrayWriter#writeTo(java.io.Writer)
+     */
+    public void test_writeToLjava_io_Writer() throws IOException {
+        cw.write("HelloWorld", 0, 10);
+        StringWriter sw = new StringWriter();
+        cw.writeTo(sw);
+        assertEquals("Writer failed to write correct chars", "HelloWorld", sw
+                .toString());
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() {
+        cw = new CharArrayWriter();
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    protected void tearDown() {
+        if (cr != null) {
+            cr.close();
+        }
+        cw.close();
+    }
+
+    /**
+     * java.io.CharArrayWriter#append(char)
+     */
+    public void test_appendChar() throws IOException {
+        char testChar = ' ';
+        CharArrayWriter writer = new CharArrayWriter(10);
+        writer.append(testChar);
+        writer.flush();
+        assertEquals(String.valueOf(testChar), writer.toString());
+        writer.close();
+    }
+
+    /**
+     * java.io.CharArrayWriter#append(CharSequence)
+     */
+    public void test_appendCharSequence() {
+        String testString = "My Test String";
+        CharArrayWriter writer = new CharArrayWriter(10);
+        writer.append(testString);
+        writer.flush();
+        assertEquals(testString, writer.toString());
+        writer.close();
+    }
+
+    /**
+     * java.io.CharArrayWriter#append(CharSequence, int, int)
+     */
+    public void test_appendCharSequenceIntInt() {
+        String testString = "My Test String";
+        CharArrayWriter writer = new CharArrayWriter(10);
+        writer.append(testString, 1, 3);
+        writer.flush();
+        assertEquals(testString.substring(1, 3), writer.toString());
+        writer.close();
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/CharConversionExceptionTest.java b/luni/src/test/java/tests/api/java/io/CharConversionExceptionTest.java
new file mode 100644
index 0000000..2d43ea9
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/CharConversionExceptionTest.java
@@ -0,0 +1,55 @@
+/*
+ *  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.io;
+
+import java.io.CharConversionException;
+
+public class CharConversionExceptionTest extends junit.framework.TestCase {
+
+    /**
+     * java.io.CharConversionException#CharConversionException()
+     */
+    public void test_Constructor() {
+        // Currently, there are no refs to CharConversionException so this is
+        // the best test we can do
+        try {
+            if (true) // BB: getting around LF
+                throw new CharConversionException();
+            fail("Exception not thrown");
+        } catch (CharConversionException e) {
+            assertNull(
+                    "Exception defined with no message answers non-null to getMessage()",
+                    e.getMessage());
+        }
+    }
+
+    /**
+     * java.io.CharConversionException#CharConversionException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        try {
+            if (true) // getting around LF
+                throw new CharConversionException("Blah");
+            fail("Exception not thrown");
+        } catch (CharConversionException e) {
+            assertEquals(
+                    "Exception defined with no message answers non-null to getMessage()",
+                    "Blah", e.getMessage());
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/ConsoleTest.java b/luni/src/test/java/tests/api/java/io/ConsoleTest.java
new file mode 100644
index 0000000..0f2b17f
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/ConsoleTest.java
@@ -0,0 +1,116 @@
+/*
+ *  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.io;
+
+import junit.framework.TestCase;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Console;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.lang.reflect.Constructor;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+/**
+ * This file is test for java.io.Console. Due to the redirect problem, it can
+ * only be run on Harmony.
+ *
+ * @since 1.6
+ */
+public class ConsoleTest extends TestCase {
+    private static final byte[] bytes = "hello world\n".getBytes();
+
+    private InputStream in = new ByteArrayInputStream(bytes);
+    private OutputStream out = new ByteArrayOutputStream();
+    private Console console = null;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        Constructor<Console> constructor =
+                Console.class.getDeclaredConstructor(InputStream.class, OutputStream.class);
+        constructor.setAccessible(true);
+        console = constructor.newInstance(in, out);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        console = null;
+        super.tearDown();
+    }
+
+    public void test_getConsole() throws Exception {
+        assertNotNull(System.console());
+    }
+
+    public void test_flush() {
+        console.flush();
+        assertFalse(console.writer().checkError());
+    }
+
+    public void test_format_LString_LObject() {
+        assertSame(console, console.format("%d %s", 1, "hello"));
+        String prompt = new String(((ByteArrayOutputStream) out).toByteArray());
+        assertEquals("1 hello", prompt);
+    }
+
+    public void test_printf_LString_LObject() {
+        Calendar c = new GregorianCalendar(1983, 2, 21);
+        assertSame(console, console.printf("%1$tm %1$te,%1$tY", c));
+        String prompt = new String(((ByteArrayOutputStream) out).toByteArray());
+        assertEquals("03 21,1983", prompt);
+    }
+
+    public void test_reader() throws IOException {
+        Reader reader1 = console.reader();
+        assertTrue(reader1.ready());
+        Reader reader2 = console.reader();
+        assertSame(reader1, reader2);
+    }
+
+    public void test_readLine() {
+        String line = console.readLine();
+        assertEquals("hello world", line);
+    }
+
+    public void test_readLine_LString_LObject() {
+        String line = console.readLine("%d %s", 2, "Please input a line of string to test:");
+        assertEquals("hello world", line);
+        String prompt = new String(((ByteArrayOutputStream) out).toByteArray());
+        assertEquals("2 Please input a line of string to test:", prompt);
+    }
+
+    public void test_readPassword_LString_LObject() {
+        console.readPassword("%d", 3);
+        String prompt = new String(((ByteArrayOutputStream) out).toByteArray());
+        assertEquals("3\n", prompt);
+    }
+
+    /**
+     * {@link java.io.Console#writer()}
+     */
+    public void test_writer() {
+        PrintWriter writer1 = console.writer();
+        PrintWriter writer2 = console.writer();
+        assertSame(writer1, writer2);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/DataInputStreamTest.java b/luni/src/test/java/tests/api/java/io/DataInputStreamTest.java
new file mode 100644
index 0000000..8403af7
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/DataInputStreamTest.java
@@ -0,0 +1,594 @@
+/*
+ *  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.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+
+public class DataInputStreamTest extends junit.framework.TestCase {
+
+    private DataOutputStream os;
+
+    private DataInputStream dis;
+
+    private ByteArrayOutputStream bos;
+
+    String unihw = "\u0048\u0065\u006C\u006C\u006F\u0020\u0057\u006F\u0072\u006C\u0064";
+
+    public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_DataInputStream\n";
+
+    /**
+     * java.io.DataInputStream#DataInputStream(java.io.InputStream)
+     */
+    public void test_ConstructorLjava_io_InputStream() throws IOException {
+        try {
+            os.writeChar('t');
+            os.close();
+            openDataInputStream();
+        } finally {
+            dis.close();
+        }
+    }
+
+    /**
+     * java.io.DataInputStream#read(byte[])
+     */
+    public void test_read$B() throws IOException {
+        os.write(fileString.getBytes());
+        os.close();
+        openDataInputStream();
+        byte rbytes[] = new byte[fileString.length()];
+        dis.read(rbytes);
+        assertTrue("Incorrect data read", new String(rbytes, 0, fileString
+                .length()).equals(fileString));
+    }
+
+    /**
+     * java.io.DataInputStream#read(byte[], int, int)
+     */
+    public void test_read$BII() throws IOException {
+        os.write(fileString.getBytes());
+        os.close();
+        openDataInputStream();
+        byte rbytes[] = new byte[fileString.length()];
+        dis.read(rbytes, 0, rbytes.length);
+        assertTrue("Incorrect data read", new String(rbytes, 0, fileString
+                .length()).equals(fileString));
+    }
+
+    /**
+     * java.io.DataInputStream#readBoolean()
+     */
+    public void test_readBoolean() throws IOException {
+        os.writeBoolean(true);
+        os.close();
+        openDataInputStream();
+        assertTrue("Incorrect boolean written", dis.readBoolean());
+    }
+
+    /**
+     * java.io.DataInputStream#readByte()
+     */
+    public void test_readByte() throws IOException {
+        os.writeByte((byte) 127);
+        os.close();
+        openDataInputStream();
+        assertTrue("Incorrect byte read", dis.readByte() == (byte) 127);
+    }
+
+    /**
+     * java.io.DataInputStream#readChar()
+     */
+    public void test_readChar() throws IOException {
+        os.writeChar('t');
+        os.close();
+        openDataInputStream();
+        assertEquals("Incorrect char read", 't', dis.readChar());
+    }
+
+    /**
+     * java.io.DataInputStream#readDouble()
+     */
+    public void test_readDouble() throws IOException {
+        os.writeDouble(2345.76834720202);
+        os.close();
+        openDataInputStream();
+        assertEquals("Incorrect double read", 2345.76834720202, dis
+                .readDouble());
+    }
+
+    /**
+     * java.io.DataInputStream#readFloat()
+     */
+    public void test_readFloat() throws IOException {
+        os.writeFloat(29.08764f);
+        os.close();
+        openDataInputStream();
+        assertTrue("Incorrect float read", dis.readFloat() == 29.08764f);
+    }
+
+    /**
+     * java.io.DataInputStream#readFully(byte[])
+     */
+    public void test_readFully$B() throws IOException {
+        os.write(fileString.getBytes());
+        os.close();
+        openDataInputStream();
+        byte rbytes[] = new byte[fileString.length()];
+        dis.readFully(rbytes);
+        assertTrue("Incorrect data read", new String(rbytes, 0, fileString
+                .length()).equals(fileString));
+    }
+
+    /**
+     * java.io.DataInputStream#readFully(byte[], int, int)
+     */
+    public void test_readFully$BII() throws IOException {
+        os.write(fileString.getBytes());
+        os.close();
+        openDataInputStream();
+        byte rbytes[] = new byte[fileString.length()];
+        dis.readFully(rbytes, 0, fileString.length());
+        assertTrue("Incorrect data read", new String(rbytes, 0, fileString
+                .length()).equals(fileString));
+    }
+
+    /**
+     * java.io.DataInputStream#readFully(byte[], int, int)
+     */
+    public void test_readFully$BII_Exception() throws IOException {
+        DataInputStream is = new DataInputStream(new ByteArrayInputStream(
+                new byte[fileString.length()]));
+
+        byte[] byteArray = new byte[fileString.length()];
+
+        try {
+            is.readFully(byteArray, -1, -1);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            is.readFully(byteArray, 0, -1);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            is.readFully(byteArray, 1, -1);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        is.readFully(byteArray, -1, 0);
+        is.readFully(byteArray, 0, 0);
+        is.readFully(byteArray, 1, 0);
+
+        try {
+            is.readFully(byteArray, -1, 1);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        is.readFully(byteArray, 0, 1);
+        is.readFully(byteArray, 1, 1);
+        try {
+            is.readFully(byteArray, 0, Integer.MAX_VALUE);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.DataInputStream#readFully(byte[], int, int)
+     */
+    public void test_readFully$BII_NullArray() throws IOException {
+        DataInputStream is = new DataInputStream(new ByteArrayInputStream(
+                new byte[fileString.length()]));
+
+        byte[] nullByteArray = null;
+
+        try {
+            is.readFully(nullByteArray, -1, -1);
+            fail();
+        } catch (NullPointerException expected) {
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        try {
+            is.readFully(nullByteArray, 0, -1);
+            fail();
+        } catch (NullPointerException expected) {
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        try {
+            is.readFully(nullByteArray, 1, -1);
+            fail();
+        } catch (NullPointerException expected) {
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        is.readFully(nullByteArray, -1, 0);
+        is.readFully(nullByteArray, 0, 0);
+        is.readFully(nullByteArray, 1, 0);
+
+        try {
+            is.readFully(nullByteArray, -1, 1);
+            fail();
+        } catch (NullPointerException expected) {
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        try {
+            is.readFully(nullByteArray, 0, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            is.readFully(nullByteArray, 1, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            is.readFully(nullByteArray, 0, Integer.MAX_VALUE);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.DataInputStream#readFully(byte[], int, int)
+     */
+    public void test_readFully$BII_NullStream() throws IOException {
+        DataInputStream is = new DataInputStream(null);
+        byte[] byteArray = new byte[fileString.length()];
+
+        try {
+            is.readFully(byteArray, -1, -1);
+            fail();
+        } catch (NullPointerException expected) {
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        try {
+            is.readFully(byteArray, 0, -1);
+            fail();
+        } catch (NullPointerException expected) {
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        try {
+            is.readFully(byteArray, 1, -1);
+            fail();
+        } catch (NullPointerException expected) {
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        is.readFully(byteArray, -1, 0);
+        is.readFully(byteArray, 0, 0);
+        is.readFully(byteArray, 1, 0);
+
+        try {
+            is.readFully(byteArray, -1, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            is.readFully(byteArray, 0, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            is.readFully(byteArray, 1, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            is.readFully(byteArray, 0, Integer.MAX_VALUE);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.DataInputStream#readFully(byte[], int, int)
+     */
+    public void test_readFully$BII_NullStream_NullArray() throws IOException {
+        DataInputStream is = new DataInputStream(null);
+        byte[] nullByteArray = null;
+
+        try {
+            is.readFully(nullByteArray, -1, -1);
+            fail();
+        } catch (NullPointerException expected) {
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        try {
+            is.readFully(nullByteArray, 0, -1);
+            fail();
+        } catch (NullPointerException expected) {
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        try {
+            is.readFully(nullByteArray, 1, -1);
+            fail();
+        } catch (NullPointerException expected) {
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        is.readFully(nullByteArray, -1, 0);
+        is.readFully(nullByteArray, 0, 0);
+        is.readFully(nullByteArray, 1, 0);
+
+        try {
+            is.readFully(nullByteArray, -1, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            is.readFully(nullByteArray, 0, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            is.readFully(nullByteArray, 1, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            is.readFully(nullByteArray, 0, Integer.MAX_VALUE);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.DataInputStream#readInt()
+     */
+    public void test_readInt() throws IOException {
+        os.writeInt(768347202);
+        os.close();
+        openDataInputStream();
+        assertEquals("Incorrect int read", 768347202, dis.readInt());
+    }
+
+    /**
+     * java.io.DataInputStream#readLine()
+     */
+    @SuppressWarnings("deprecation")
+    public void test_readLine() throws IOException {
+        os.writeBytes("Hello");
+        os.close();
+        openDataInputStream();
+        String line = dis.readLine();
+        assertTrue("Incorrect line read: " + line, line.equals("Hello"));
+    }
+
+    /**
+     * java.io.DataInputStream#readLong()
+     */
+    public void test_readLong() throws IOException {
+        os.writeLong(9875645283333L);
+        os.close();
+        openDataInputStream();
+        assertEquals("Incorrect long read", 9875645283333L, dis.readLong());
+    }
+
+    /**
+     * java.io.DataInputStream#readShort()
+     */
+    public void test_readShort() throws IOException {
+        os.writeShort(9875);
+        os.close();
+        openDataInputStream();
+        assertTrue("Incorrect short read", dis.readShort() == (short) 9875);
+    }
+
+    /**
+     * java.io.DataInputStream#readUnsignedByte()
+     */
+    public void test_readUnsignedByte() throws IOException {
+        os.writeByte((byte) -127);
+        os.close();
+        openDataInputStream();
+        assertEquals("Incorrect byte read", 129, dis.readUnsignedByte());
+    }
+
+    /**
+     * java.io.DataInputStream#readUnsignedShort()
+     */
+    public void test_readUnsignedShort() throws IOException {
+        os.writeShort(9875);
+        os.close();
+        openDataInputStream();
+        assertEquals("Incorrect short read", 9875, dis.readUnsignedShort());
+    }
+
+    /**
+     * java.io.DataInputStream#readUTF()
+     */
+    public void test_readUTF() throws IOException {
+        os.writeUTF(unihw);
+        os.close();
+        openDataInputStream();
+        assertTrue("Failed to write string in UTF format",
+                dis.available() == unihw.length() + 2);
+        assertTrue("Incorrect string read", dis.readUTF().equals(unihw));
+    }
+
+    static class TestDataInputStream implements DataInput {
+        public boolean readBoolean() throws IOException {
+            return false;
+        }
+
+        public byte readByte() throws IOException {
+            return (byte) 0;
+        }
+
+        public char readChar() throws IOException {
+            return (char) 0;
+        }
+
+        public double readDouble() throws IOException {
+            return 0.0;
+        }
+
+        public float readFloat() throws IOException {
+            return (float) 0.0;
+        }
+
+        public void readFully(byte[] buffer) throws IOException {
+        }
+
+        public void readFully(byte[] buffer, int offset, int count)
+                throws IOException {
+        }
+
+        public int readInt() throws IOException {
+            return 0;
+        }
+
+        public String readLine() throws IOException {
+            return null;
+        }
+
+        public long readLong() throws IOException {
+            return (long) 0;
+        }
+
+        public short readShort() throws IOException {
+            return (short) 0;
+        }
+
+        public int readUnsignedByte() throws IOException {
+            return 0;
+        }
+
+        public int readUnsignedShort() throws IOException {
+            return 0;
+        }
+
+        public String readUTF() throws IOException {
+            return DataInputStream.readUTF(this);
+        }
+
+        public int skipBytes(int count) throws IOException {
+            return 0;
+        }
+    }
+
+    /**
+     * java.io.DataInputStream#readUTF(java.io.DataInput)
+     */
+    public void test_readUTFLjava_io_DataInput() throws IOException {
+        os.writeUTF(unihw);
+        os.close();
+        openDataInputStream();
+        assertTrue("Failed to write string in UTF format",
+                dis.available() == unihw.length() + 2);
+        assertTrue("Incorrect string read", DataInputStream.readUTF(dis)
+                .equals(unihw));
+
+        // Regression test for HARMONY-5336
+        new TestDataInputStream().readUTF();
+    }
+
+    /**
+     * java.io.DataInputStream#skipBytes(int)
+     */
+    public void test_skipBytesI() throws IOException {
+        byte fileBytes[] = fileString.getBytes();
+        os.write(fileBytes);
+        os.close();
+        openDataInputStream();
+        dis.skipBytes(100);
+        byte rbytes[] = new byte[fileString.length()];
+        dis.read(rbytes, 0, 50);
+        dis.close();
+        assertTrue("Incorrect data read", new String(rbytes, 0, 50)
+                .equals(fileString.substring(100, 150)));
+
+        int skipped = 0;
+        openDataInputStream();
+        try {
+            skipped = dis.skipBytes(50000);
+        } catch (EOFException e) {
+        }
+        assertTrue("Skipped should report " + fileString.length() + " not "
+                + skipped, skipped == fileString.length());
+    }
+
+    private void openDataInputStream() throws IOException {
+        dis = new DataInputStream(new ByteArrayInputStream(bos.toByteArray()));
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() {
+        bos = new ByteArrayOutputStream();
+        os = new DataOutputStream(bos);
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    protected void tearDown() {
+        try {
+            os.close();
+        } catch (Exception e) {
+        }
+        try {
+            dis.close();
+        } catch (Exception e) {
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/DataOutputStreamTest.java b/luni/src/test/java/tests/api/java/io/DataOutputStreamTest.java
new file mode 100644
index 0000000..d6c27b9
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/DataOutputStreamTest.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 tests.api.java.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class DataOutputStreamTest extends junit.framework.TestCase {
+
+    private DataOutputStream os;
+
+    private DataInputStream dis;
+
+    private ByteArrayOutputStream bos;
+
+    String unihw = "\u0048\u0065\u006C\u006C\u006F\u0020\u0057\u006F\u0072\u006C\u0064";
+
+    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";
+
+    /**
+     * java.io.DataOutputStream#DataOutputStream(java.io.OutputStream)
+     */
+    public void test_ConstructorLjava_io_OutputStream() {
+        assertTrue("Used in all tests", true);
+    }
+
+    /**
+     * java.io.DataOutputStream#flush()
+     */
+    public void test_flush() throws IOException {
+        os.writeInt(9087589);
+        os.flush();
+        openDataInputStream();
+        int c = dis.readInt();
+        dis.close();
+        assertEquals("Failed to flush correctly", 9087589, c);
+    }
+
+    /**
+     * java.io.DataOutputStream#size()
+     */
+    public void test_size() throws IOException {
+        os.write(fileString.getBytes(), 0, 150);
+        os.close();
+        openDataInputStream();
+        byte[] rbuf = new byte[150];
+        dis.read(rbuf, 0, 150);
+        dis.close();
+        assertEquals("Incorrect size returned", 150, os.size());
+    }
+
+    /**
+     * java.io.DataOutputStream#write(byte[], int, int)
+     */
+    public void test_write$BII() throws IOException {
+        os.write(fileString.getBytes(), 0, 150);
+        os.close();
+        openDataInputStream();
+        byte[] rbuf = new byte[150];
+        dis.read(rbuf, 0, 150);
+        dis.close();
+        assertTrue("Incorrect bytes written", new String(rbuf, 0, 150)
+                .equals(fileString.substring(0, 150)));
+    }
+
+    /**
+     * java.io.DataOutputStream#write(int)
+     */
+    public void test_writeI() throws IOException {
+        os.write((int) 't');
+        os.close();
+        openDataInputStream();
+        int c = dis.read();
+        dis.close();
+        assertTrue("Incorrect int written", (int) 't' == c);
+    }
+
+    /**
+     * java.io.DataOutputStream#writeBoolean(boolean)
+     */
+    public void test_writeBooleanZ() throws IOException {
+        os.writeBoolean(true);
+        os.close();
+        openDataInputStream();
+        boolean c = dis.readBoolean();
+        dis.close();
+        assertTrue("Incorrect boolean written", c);
+    }
+
+    /**
+     * java.io.DataOutputStream#writeByte(int)
+     */
+    public void test_writeByteI() throws IOException {
+        os.writeByte((byte) 127);
+        os.close();
+        openDataInputStream();
+        byte c = dis.readByte();
+        dis.close();
+        assertTrue("Incorrect byte written", c == (byte) 127);
+    }
+
+    /**
+     * java.io.DataOutputStream#writeBytes(java.lang.String)
+     */
+    public void test_writeBytesLjava_lang_String() throws IOException {
+        os.write(fileString.getBytes());
+        os.close();
+        openDataInputStream();
+        byte[] rbuf = new byte[4000];
+        dis.read(rbuf, 0, fileString.length());
+        dis.close();
+        assertTrue("Incorrect bytes written", new String(rbuf, 0, fileString
+                .length()).equals(fileString));
+
+        // regression test for HARMONY-1101
+        new DataOutputStream(null).writeBytes("");
+    }
+
+    /**
+     * java.io.DataOutputStream#writeChar(int)
+     */
+    public void test_writeCharI() throws IOException {
+        os.writeChar('T');
+        os.close();
+        openDataInputStream();
+        char c = dis.readChar();
+        dis.close();
+        assertEquals("Incorrect char written", 'T', c);
+    }
+
+    /**
+     * java.io.DataOutputStream#writeChars(java.lang.String)
+     */
+    public void test_writeCharsLjava_lang_String() throws IOException {
+        os.writeChars("Test String");
+        os.close();
+        openDataInputStream();
+        char[] chars = new char[50];
+        int i, a = dis.available() / 2;
+        for (i = 0; i < a; i++)
+            chars[i] = dis.readChar();
+        assertEquals("Incorrect chars written", "Test String", new String(
+                chars, 0, i));
+    }
+
+    /**
+     * java.io.DataOutputStream#writeDouble(double)
+     */
+    public void test_writeDoubleD() throws IOException {
+        os.writeDouble(908755555456.98);
+        os.close();
+        openDataInputStream();
+        double c = dis.readDouble();
+        dis.close();
+        assertEquals("Incorrect double written", 908755555456.98, c);
+    }
+
+    /**
+     * java.io.DataOutputStream#writeFloat(float)
+     */
+    public void test_writeFloatF() throws IOException {
+        os.writeFloat(9087.456f);
+        os.close();
+        openDataInputStream();
+        float c = dis.readFloat();
+        dis.close();
+        assertTrue("Incorrect float written", c == 9087.456f);
+    }
+
+    /**
+     * java.io.DataOutputStream#writeInt(int)
+     */
+    public void test_writeIntI() throws IOException {
+        os.writeInt(9087589);
+        os.close();
+        openDataInputStream();
+        int c = dis.readInt();
+        dis.close();
+        assertEquals("Incorrect int written", 9087589, c);
+    }
+
+    /**
+     * java.io.DataOutputStream#writeLong(long)
+     */
+    public void test_writeLongJ() throws IOException {
+        os.writeLong(908755555456L);
+        os.close();
+        openDataInputStream();
+        long c = dis.readLong();
+        dis.close();
+        assertEquals("Incorrect long written", 908755555456L, c);
+    }
+
+    /**
+     * java.io.DataOutputStream#writeShort(int)
+     */
+    public void test_writeShortI() throws IOException {
+        os.writeShort((short) 9087);
+        os.close();
+        openDataInputStream();
+        short c = dis.readShort();
+        dis.close();
+        assertEquals("Incorrect short written", 9087, c);
+    }
+
+    /**
+     * java.io.DataOutputStream#writeUTF(java.lang.String)
+     */
+    public void test_writeUTFLjava_lang_String() throws IOException {
+        os.writeUTF(unihw);
+        os.close();
+        openDataInputStream();
+        assertTrue("Failed to write string in UTF format",
+                dis.available() == unihw.length() + 2);
+        assertTrue("Incorrect string returned", dis.readUTF().equals(unihw));
+    }
+
+    private void openDataInputStream() throws IOException {
+        dis = new DataInputStream(new ByteArrayInputStream(bos.toByteArray()));
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() {
+        bos = new ByteArrayOutputStream();
+        os = new DataOutputStream(bos);
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    protected void tearDown() {
+        try {
+            if (os != null)
+                os.close();
+            if (dis != null)
+                dis.close();
+        } catch (IOException e) {
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/EOFExceptionTest.java b/luni/src/test/java/tests/api/java/io/EOFExceptionTest.java
new file mode 100644
index 0000000..80e4636
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/EOFExceptionTest.java
@@ -0,0 +1,52 @@
+/*
+ *  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.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+
+public class EOFExceptionTest extends junit.framework.TestCase {
+
+    /**
+     * java.io.EOFException#EOFException()
+     */
+    public void test_Constructor() throws Exception {
+        try {
+            new DataInputStream(new ByteArrayInputStream(new byte[1]))
+                    .readShort();
+            fail("Failed to generate EOFException");
+        } catch (EOFException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.io.EOFException#EOFException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() throws IOException {
+        try {
+            new DataInputStream(new ByteArrayInputStream(new byte[1]))
+                    .readShort();
+            fail("Failed to generate EOFException");
+        } catch (EOFException e) {
+            // Expected
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/FileDescriptorTest.java b/luni/src/test/java/tests/api/java/io/FileDescriptorTest.java
new file mode 100644
index 0000000..f994677
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/FileDescriptorTest.java
@@ -0,0 +1,115 @@
+/*
+ *  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.io;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+import junit.framework.TestCase;
+
+public class FileDescriptorTest extends TestCase {
+
+    private static String platformId = "JDK"
+            + System.getProperty("java.vm.version").replace('.', '-');
+
+    FileOutputStream fos;
+
+    BufferedOutputStream os;
+
+    FileInputStream fis;
+
+    File f;
+
+    /**
+     * java.io.FileDescriptor#FileDescriptor()
+     */
+    public void test_Constructor() {
+        FileDescriptor fd = new FileDescriptor();
+        assertTrue("Failed to create FileDescriptor",
+                fd instanceof FileDescriptor);
+    }
+
+    /**
+     * java.io.FileDescriptor#sync()
+     */
+    public void test_sync() throws IOException {
+        f = new File(System.getProperty("user.dir"), "fd" + platformId + ".tst");
+        f.delete();
+        fos = new FileOutputStream(f.getPath());
+        fos.write("Test String".getBytes());
+        fis = new FileInputStream(f.getPath());
+        FileDescriptor fd = fos.getFD();
+        fd.sync();
+        int length = "Test String".length();
+        assertEquals("Bytes were not written after sync", length, fis
+                .available());
+
+        // Regression test for Harmony-1494
+        fd = fis.getFD();
+        fd.sync();
+        assertEquals("Bytes were not written after sync", length, fis
+                .available());
+
+        RandomAccessFile raf = new RandomAccessFile(f, "r");
+        fd = raf.getFD();
+        fd.sync();
+        raf.close();
+    }
+
+    /**
+     * java.io.FileDescriptor#valid()
+     */
+    public void test_valid() throws IOException {
+        f = new File(System.getProperty("user.dir"), "fd.tst");
+        f.delete();
+        os = new BufferedOutputStream(fos = new FileOutputStream(f.getPath()),
+                4096);
+        FileDescriptor fd = fos.getFD();
+        assertTrue("Valid fd returned false", fd.valid());
+        os.close();
+        assertTrue("Invalid fd returned true", !fd.valid());
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    protected void tearDown() {
+        try {
+            os.close();
+        } catch (Exception e) {
+        }
+        try {
+            fis.close();
+        } catch (Exception e) {
+        }
+        try {
+            fos.close();
+        } catch (Exception e) {
+        }
+        try {
+            f.delete();
+        } catch (Exception e) {
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/FileInputStreamTest.java b/luni/src/test/java/tests/api/java/io/FileInputStreamTest.java
new file mode 100644
index 0000000..0b9036e
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/FileInputStreamTest.java
@@ -0,0 +1,457 @@
+/*
+ *  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.io;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FilePermission;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.security.Permission;
+
+import junit.framework.TestCase;
+import tests.support.Support_PlatformFile;
+
+public class FileInputStreamTest extends TestCase {
+
+    public String fileName;
+
+    private java.io.InputStream is;
+
+    byte[] ibuf = new byte[4096];
+
+    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_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";
+
+    /**
+     * java.io.FileInputStream#FileInputStream(java.io.File)
+     */
+    public void test_ConstructorLjava_io_File() throws IOException {
+        java.io.File f = new File(fileName);
+        is = new FileInputStream(f);
+        is.close();
+    }
+
+    /**
+     * java.io.FileInputStream#FileInputStream(java.io.FileDescriptor)
+     */
+    public void test_ConstructorLjava_io_FileDescriptor() throws IOException {
+        FileOutputStream fos = new FileOutputStream(fileName);
+        FileInputStream fis = new FileInputStream(fos.getFD());
+        fos.close();
+        fis.close();
+    }
+
+    /**
+     * java.io.FileInputStream#FileInputStream(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() throws IOException {
+        is = new FileInputStream(fileName);
+        is.close();
+    }
+
+    /**
+     * java.io.FileInputStream#FileInputStream(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String_I() throws IOException {
+        try {
+            is = new FileInputStream("");
+            fail("should throw FileNotFoundException.");
+        } catch (FileNotFoundException e) {
+            // Expected
+        } finally {
+            if (is != null) {
+                is.close();
+            }
+        }
+        try {
+            is = new FileInputStream(new File(""));
+            fail("should throw FileNotFoundException.");
+        } catch (FileNotFoundException e) {
+            // Expected
+        } finally {
+            if (is != null) {
+                is.close();
+            }
+        }
+    }
+
+    /**
+     * java.io.FileInputStream#available()
+     */
+    public void test_available() throws IOException {
+        try {
+            is = new FileInputStream(fileName);
+            assertTrue("Returned incorrect number of available bytes", is
+                    .available() == fileString.length());
+        } finally {
+            try {
+                is.close();
+            } catch (IOException e) {
+            }
+        }
+    }
+
+    public void test_close() throws IOException {
+        is = new FileInputStream(fileName);
+        is.close();
+        try {
+            is.read();
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void test_close_shared_fd() throws IOException {
+        // Regression test for HARMONY-6642
+        FileInputStream fis1 = new FileInputStream(fileName);
+        FileInputStream fis2 = new FileInputStream(fis1.getFD());
+        try {
+            fis2.close();
+            fis1.read();
+            fail("fd sharing error");
+        } catch (IOException expected) {
+        } finally {
+            try {
+                fis1.close();
+            } catch (IOException e) {
+            }
+        }
+
+        // TODO: how does this differ from the test above?
+        FileInputStream stdin = new FileInputStream(FileDescriptor.in);
+        stdin.close();
+        stdin = new FileInputStream(FileDescriptor.in);
+        try {
+            stdin.read();
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    /**
+     * java.io.FileInputStream#getFD()
+     */
+    public void test_getFD() throws IOException {
+        FileInputStream fis = new FileInputStream(fileName);
+        assertTrue("Returned invalid fd", fis.getFD().valid());
+        fis.close();
+        assertTrue("Returned invalid fd", !fis.getFD().valid());
+    }
+
+    /**
+     * java.io.FileInputStream#read()
+     */
+    public void test_read() throws IOException {
+        InputStreamReader isr = new InputStreamReader(new FileInputStream(fileName));
+        int c = isr.read();
+        isr.close();
+        assertTrue("read returned incorrect char", c == fileString.charAt(0));
+    }
+
+    /**
+     * java.io.FileInputStream#read(byte[])
+     */
+    public void test_read$B() throws IOException {
+        byte[] buf1 = new byte[100];
+        is = new FileInputStream(fileName);
+        is.skip(3000);
+        is.read(buf1);
+        is.close();
+        assertTrue("Failed to read correct data", new String(buf1, 0,
+                buf1.length).equals(fileString.substring(3000, 3100)));
+    }
+
+    /**
+     * java.io.FileInputStream#read(byte[], int, int)
+     */
+    public void test_read$BII() throws IOException {
+        byte[] buf1 = new byte[100];
+        is = new FileInputStream(fileName);
+        is.skip(3000);
+        is.read(buf1, 0, buf1.length);
+        is.close();
+        assertTrue("Failed to read correct data", new String(buf1, 0,
+                buf1.length).equals(fileString.substring(3000, 3100)));
+
+        // Regression test for HARMONY-285
+        File tmpFile = File.createTempFile("FileOutputStream", "tmp");
+        FileInputStream in = new FileInputStream(tmpFile);
+        try {
+            in.read(null, 0, 0);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        } finally {
+            in.close();
+            tmpFile.delete();
+        }
+    }
+
+    /**
+     * java.io.FileInputStream#read(byte[], int, int)
+     */
+    public void test_read_$BII_IOException() throws IOException {
+        byte[] buf = new byte[1000];
+        try {
+            is = new FileInputStream(fileName);
+            is.read(buf, -1, 0);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        } finally {
+            is.close();
+        }
+
+        try {
+            is = new FileInputStream(fileName);
+            is.read(buf, 0, -1);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        } finally {
+            is.close();
+        }
+
+        try {
+            is = new FileInputStream(fileName);
+            is.read(buf, -1, -1);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        } finally {
+            is.close();
+        }
+
+        try {
+            is = new FileInputStream(fileName);
+            is.read(buf, 0, 1001);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        } finally {
+            is.close();
+        }
+
+        try {
+            is = new FileInputStream(fileName);
+            is.read(buf, 1001, 0);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        } finally {
+            is.close();
+        }
+
+        try {
+            is = new FileInputStream(fileName);
+            is.read(buf, 500, 501);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        } finally {
+            is.close();
+        }
+
+        try {
+            is = new FileInputStream(fileName);
+            is.close();
+            is.read(buf, 0, 100);
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // Expected
+        } finally {
+            is.close();
+        }
+
+        try {
+            is = new FileInputStream(fileName);
+            is.close();
+            is.read(buf, 0, 0);
+        } finally {
+            is.close();
+        }
+    }
+
+    /**
+     * java.io.FileInputStream#read(byte[], int, int)
+     */
+    public void test_read_$BII_NullPointerException() throws IOException {
+        byte[] buf = null;
+        try {
+            is = new FileInputStream(fileName);
+            is.read(buf, -1, 0);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        } finally {
+            is.close();
+        }
+    }
+
+    /**
+     * java.io.FileInputStream#read(byte[], int, int)
+     */
+    public void test_read_$BII_IndexOutOfBoundsException() throws IOException {
+        byte[] buf = new byte[1000];
+        try {
+            is = new FileInputStream(fileName);
+            is.close();
+            is.read(buf, -1, -1);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        } finally {
+            is.close();
+        }
+    }
+
+    /**
+     * java.io.FileInputStream#skip(long)
+     */
+    public void test_skipJ() throws IOException {
+        byte[] buf1 = new byte[10];
+        is = new FileInputStream(fileName);
+        is.skip(1000);
+        is.read(buf1, 0, buf1.length);
+        is.close();
+        assertTrue("Failed to skip to correct position", new String(buf1, 0,
+                buf1.length).equals(fileString.substring(1000, 1010)));
+    }
+
+    /**
+     * java.io.FileInputStream#read(byte[], int, int))
+     */
+    public void test_regressionNNN() throws IOException {
+        // Regression for HARMONY-434
+        FileInputStream fis = new FileInputStream(fileName);
+
+        try {
+            fis.read(new byte[1], -1, 1);
+            fail("IndexOutOfBoundsException must be thrown if off <0");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        try {
+            fis.read(new byte[1], 0, -1);
+            fail("IndexOutOfBoundsException must be thrown if len <0");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        try {
+            fis.read(new byte[1], 0, 5);
+            fail("IndexOutOfBoundsException must be thrown if off+len > b.length");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        try {
+            fis.read(new byte[10], Integer.MAX_VALUE, 5);
+            fail("IndexOutOfBoundsException expected");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        try {
+            fis.read(new byte[10], 5, Integer.MAX_VALUE);
+            fail("IndexOutOfBoundsException expected");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+        fis.close();
+    }
+
+    /**
+     * java.io.FileInputStream#skip(long)
+     */
+    public void test_skipNegativeArgumentJ() throws IOException {
+        FileInputStream fis = new FileInputStream(fileName);
+        try {
+            fis.skip(-5);
+            fail("IOException must be thrown if number of bytes to skip <0");
+        } catch (IOException e) {
+            // Expected IOException
+        } finally {
+            fis.close();
+        }
+    }
+
+    public void test_getChannel() throws Exception {
+        FileInputStream fis = new FileInputStream(fileName);
+        assertEquals(0, fis.getChannel().position());
+        int r;
+        int count = 1;
+        while ((r = fis.read()) != -1) {
+            assertEquals(count++, fis.getChannel().position());
+        }
+        fis.close();
+
+        try {
+            fis.getChannel().position();
+            fail("should throw ClosedChannelException");
+        } catch (java.nio.channels.ClosedChannelException e) {
+            // Expected
+        }
+
+        fis = new FileInputStream(fileName);
+        assertEquals(0, fis.getChannel().position());
+        byte[] bs = new byte[10];
+        r = fis.read(bs);
+        assertEquals(10, fis.getChannel().position());
+        fis.close();
+
+        fis = new FileInputStream(fileName);
+        assertEquals(0, fis.getChannel().position());
+        bs = new byte[10];
+        fis.skip(100);
+        assertEquals(100, fis.getChannel().position());
+        r = fis.read(bs);
+        assertEquals(110, fis.getChannel().position());
+        fis.close();
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() throws IOException {
+        fileName = System.getProperty("user.dir");
+        String separator = System.getProperty("file.separator");
+        if (fileName.charAt(fileName.length() - 1) == separator.charAt(0))
+            fileName = Support_PlatformFile.getNewPlatformFile(fileName,
+                    "input.tst");
+        else
+            fileName = Support_PlatformFile.getNewPlatformFile(fileName
+                    + separator, "input.tst");
+        java.io.OutputStream fos = new java.io.FileOutputStream(fileName);
+        fos.write(fileString.getBytes());
+        fos.close();
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    protected void tearDown() {
+        new File(fileName).delete();
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/FileNotFoundExceptionTest.java b/luni/src/test/java/tests/api/java/io/FileNotFoundExceptionTest.java
new file mode 100644
index 0000000..466aa3d
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/FileNotFoundExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.io;
+
+import java.io.FileNotFoundException;
+
+import junit.framework.TestCase;
+
+public class FileNotFoundExceptionTest extends TestCase {
+
+    /**
+     * java.io.FileNotFoundException#FileNotFoundException()
+     */
+    public void test_Constructor() {
+        FileNotFoundException e = new FileNotFoundException();
+        assertNull(e.getMessage());
+    }
+
+    /**
+     * java.io.FileNotFoundException#FileNotFoundException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        String message = "Cannot found file: 9://0//l";
+        FileNotFoundException e = new FileNotFoundException(message);
+        assertSame(message, e.getMessage());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/FileOutputStreamTest.java b/luni/src/test/java/tests/api/java/io/FileOutputStreamTest.java
new file mode 100644
index 0000000..8f3c498
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/FileOutputStreamTest.java
@@ -0,0 +1,401 @@
+/*
+ * 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.io;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+public class FileOutputStreamTest extends TestCase {
+
+    public String fileName;
+
+    FileOutputStream fos;
+
+    FileInputStream fis;
+
+    File f;
+
+    byte[] ibuf = new byte[4096];
+
+    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_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";
+
+    byte[] bytes;
+
+    /**
+     * java.io.FileOutputStream#FileOutputStream(java.io.File)
+     */
+    public void test_ConstructorLjava_io_File() throws IOException {
+        f = new File(fileName = System.getProperty("user.home"), "fos.tst");
+        fos = new FileOutputStream(f);
+    }
+
+    /**
+     * java.io.FileOutputStream#FileOutputStream(java.io.FileDescriptor)
+     */
+    public void test_ConstructorLjava_io_FileDescriptor() throws IOException {
+        f = new File(fileName = System.getProperty("user.home"), "fos.tst");
+        fileName = f.getAbsolutePath();
+        fos = new FileOutputStream(fileName);
+        fos.write('l');
+        fos.close();
+        fis = new FileInputStream(fileName);
+        fos = new FileOutputStream(fis.getFD());
+        fos.close();
+        fis.close();
+    }
+
+    /**
+     * java.io.FileOutputStream#FileOutputStream(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() throws IOException {
+        f = new File(fileName = System.getProperty("user.home"), "fos.tst");
+        fileName = f.getAbsolutePath();
+        fos = new FileOutputStream(fileName);
+
+        // Regression test for HARMONY-4012
+        new FileOutputStream("nul");
+    }
+
+    /**
+     * java.io.FileOutputStream#FileOutputStream(java.lang.String,
+     *boolean)
+     */
+    public void test_ConstructorLjava_lang_StringZ() throws IOException {
+        f = new File(System.getProperty("user.home"), "fos.tst");
+        fos = new FileOutputStream(f.getPath(), false);
+        fos.write("HI".getBytes(), 0, 2);
+        fos.close();
+        fos = new FileOutputStream(f.getPath(), true);
+        fos.write(fileString.getBytes());
+        fos.close();
+        byte[] buf = new byte[fileString.length() + 2];
+        fis = new FileInputStream(f.getPath());
+        fis.read(buf, 0, buf.length);
+        assertTrue("Failed to create appending stream", new String(buf, 0,
+                buf.length).equals("HI" + fileString));
+    }
+
+    /**
+     * java.io.FileOutputStream#FileOutputStream(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String_I() throws IOException {
+        try {
+            fos = new FileOutputStream("");
+            fail("should throw FileNotFoundException.");
+        } catch (FileNotFoundException e) {
+            // Expected
+        } finally {
+            if (fos != null) {
+                fos.close();
+            }
+        }
+        try {
+            fos = new FileOutputStream(new File(""));
+            fail("should throw FileNotFoundException.");
+        } catch (FileNotFoundException e) {
+            // Expected
+        } finally {
+            if (fos != null) {
+                fos.close();
+            }
+        }
+    }
+
+    /**
+     * java.io.FileOutputStream#close()
+     */
+    public void test_close() throws IOException {
+        f = new File(System.getProperty("user.home"), "output.tst");
+        fos = new FileOutputStream(f.getPath());
+        fos.close();
+
+        try {
+            fos.write(fileString.getBytes());
+            fail("Close test failed - wrote to closed stream");
+        } catch (IOException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.io.FileOutputStream#getFD()
+     */
+    public void test_getFD() throws IOException {
+        f = new File(fileName = System.getProperty("user.home"), "testfd");
+        fileName = f.getAbsolutePath();
+        fos = new FileOutputStream(f);
+        assertTrue("Returned invalid fd", fos.getFD().valid());
+        fos.close();
+        assertTrue("Returned invalid fd", !fos.getFD().valid());
+    }
+
+    /**
+     * java.io.FileOutputStream#write(byte[])
+     */
+    public void test_write$B() throws IOException {
+        f = new File(System.getProperty("user.home"), "output.tst");
+        fos = new FileOutputStream(f.getPath());
+        fos.write(fileString.getBytes());
+        fis = new FileInputStream(f.getPath());
+        byte rbytes[] = new byte[4000];
+        fis.read(rbytes, 0, fileString.length());
+        assertTrue("Incorrect string returned", new String(rbytes, 0,
+                fileString.length()).equals(fileString));
+    }
+
+    /**
+     * java.io.FileOutputStream#write(byte[], int, int)
+     */
+    public void test_write$BII() throws IOException {
+        f = new File(System.getProperty("user.home"), "output.tst");
+        fos = new FileOutputStream(f.getPath());
+        fos.write(fileString.getBytes(), 0, fileString.length());
+        fis = new FileInputStream(f.getPath());
+        byte rbytes[] = new byte[4000];
+        fis.read(rbytes, 0, fileString.length());
+        assertTrue("Incorrect bytes written", new String(rbytes, 0, fileString
+                .length()).equals(fileString));
+
+        // Regression test for HARMONY-285
+        File file = new File("FileOutputStream.tmp");
+        file.deleteOnExit();
+        FileOutputStream out = new FileOutputStream(file);
+        try {
+            out.write(null, 0, 0);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        } finally {
+            out.close();
+            file.delete();
+        }
+    }
+
+    /**
+     * java.io.FileOutputStream#write(int)
+     */
+    public void test_writeI() throws IOException {
+        f = new File(System.getProperty("user.home"), "output.tst");
+        fos = new FileOutputStream(f.getPath());
+        fos.write('t');
+        fis = new FileInputStream(f.getPath());
+        assertEquals("Incorrect char written", 't', fis.read());
+    }
+
+    /**
+     * java.io.FileOutputStream#write(byte[], int, int)
+     */
+    public void test_write$BII2() throws IOException {
+        // Regression for HARMONY-437
+        f = new File(System.getProperty("user.home"), "output.tst");
+        fos = new FileOutputStream(f.getPath());
+
+        try {
+            fos.write(null, 1, 1);
+            fail("NullPointerException must be thrown");
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            fos.write(new byte[1], -1, 1);
+            fail("IndexOutOfBoundsException must be thrown if off <0");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            fos.write(new byte[1], 0, -1);
+            fail("IndexOutOfBoundsException must be thrown if len <0");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            fos.write(new byte[1], 0, 5);
+            fail("IndexOutOfBoundsException must be thrown if off+len > b.length");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            fos.write(new byte[10], Integer.MAX_VALUE, 5);
+            fail("IndexOutOfBoundsException expected");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            fos.write(new byte[10], 5, Integer.MAX_VALUE);
+            fail("IndexOutOfBoundsException expected");
+        } catch (IndexOutOfBoundsException e) {
+        }
+        fos.close();
+    }
+
+    /**
+     * java.io.FileOutputStream#write(byte[], int, int)
+     */
+    public void test_write$BII3() throws IOException {
+        // Regression for HARMONY-834
+        // no exception expected
+        new FileOutputStream(new FileDescriptor()).write(new byte[1], 0, 0);
+    }
+
+    /**
+     * java.io.FileOutputStream#getChannel()
+     */
+    public void test_getChannel() throws IOException {
+        // Regression for HARMONY-508
+        File tmpfile = File.createTempFile("FileOutputStream", "tmp");
+        tmpfile.deleteOnExit();
+        FileOutputStream fos = new FileOutputStream(tmpfile);
+        fos.write(bytes);
+        fos.flush();
+        fos.close();
+        FileOutputStream f = new FileOutputStream(tmpfile, true);
+        // Harmony expected 10, but the RI and Android report 0.
+        assertEquals(0, f.getChannel().position());
+    }
+
+    public void test_getChannel_Append() throws IOException {
+        File tmpfile = File.createTempFile("FileOutputStream", "tmp");
+        tmpfile.deleteOnExit();
+        FileOutputStream fos = new FileOutputStream(tmpfile, true);
+        assertEquals(0, fos.getChannel().position());
+        fos.write(bytes);
+        assertEquals(10, fos.getChannel().position());
+        fos.write(bytes);
+        assertEquals(20, fos.getChannel().position());
+        fos.write(bytes);
+        assertEquals(30, fos.getChannel().position());
+        fos.close();
+
+        try {
+            fos.getChannel().position();
+            fail("should throw ClosedChannelException");
+        } catch (java.nio.channels.ClosedChannelException e) {
+            // Expected
+        }
+    }
+
+    public void test_getChannel_UnAppend() throws IOException {
+        File tmpfile = File.createTempFile("FileOutputStream", "tmp");
+        tmpfile.deleteOnExit();
+        FileOutputStream fos = new FileOutputStream(tmpfile, false);
+        assertEquals(0, fos.getChannel().position());
+        fos.write(bytes);
+        assertEquals(10, fos.getChannel().position());
+        fos.write(bytes);
+        assertEquals(20, fos.getChannel().position());
+        fos.write(bytes);
+        assertEquals(30, fos.getChannel().position());
+        fos.close();
+
+        try {
+            fos.getChannel().position();
+            fail("should throw ClosedChannelException");
+        } catch (java.nio.channels.ClosedChannelException e) {
+            // Expected
+        }
+    }
+
+    public void test_getChannel_Unappend_Unappend() throws IOException {
+        File tmpfile = File.createTempFile("FileOutputStream", "tmp");
+        tmpfile.deleteOnExit();
+        FileOutputStream fos = new FileOutputStream(tmpfile, false);
+        assertEquals(0, fos.getChannel().position());
+        fos.write(bytes);
+        assertEquals(10, fos.getChannel().position());
+        fos.close();
+
+        fos = new FileOutputStream(tmpfile, false);
+        assertEquals(0, fos.getChannel().position());
+        fos.close();
+    }
+
+    public void test_getChannel_Unappend_Append() throws IOException {
+        File tmpfile = File.createTempFile("FileOutputStream", "tmp");
+        tmpfile.deleteOnExit();
+        FileOutputStream fos = new FileOutputStream(tmpfile, false);
+        assertEquals(0, fos.getChannel().position());
+        fos.write(bytes);
+        assertEquals(10, fos.getChannel().position());
+        fos.close();
+
+        fos = new FileOutputStream(tmpfile, true);
+        // Harmony expected 10, but the RI and Android report 0.
+        assertEquals(0, fos.getChannel().position());
+        fos.close();
+    }
+
+    public void test_getChannel_Append_Unappend() throws IOException {
+        File tmpfile = File.createTempFile("FileOutputStream", "tmp");
+        tmpfile.deleteOnExit();
+        FileOutputStream fos = new FileOutputStream(tmpfile, true);
+        assertEquals(0, fos.getChannel().position());
+        fos.write(bytes);
+        assertEquals(10, fos.getChannel().position());
+        fos.close();
+
+        fos = new FileOutputStream(tmpfile, false);
+        assertEquals(0, fos.getChannel().position());
+        fos.close();
+    }
+
+    public void test_getChanne_Append_Append() throws IOException {
+        File tmpfile = File.createTempFile("FileOutputStream", "tmp");
+        tmpfile.deleteOnExit();
+        FileOutputStream fos = new FileOutputStream(tmpfile, true);
+        assertEquals(0, fos.getChannel().position());
+        fos.write(bytes);
+        assertEquals(10, fos.getChannel().position());
+        fos.close();
+
+        fos = new FileOutputStream(tmpfile, true);
+        // Harmony expected 10, but the RI and Android report 0.
+        assertEquals(0, fos.getChannel().position());
+        fos.close();
+    }
+
+    protected void setUp() {
+        bytes = new byte[10];
+        for (int i = 0; i < bytes.length; i++) {
+            bytes[i] = (byte) i;
+        }
+    }
+
+    /**
+     * 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 {
+        super.tearDown();
+        if (f != null) {
+            f.delete();
+        }
+        if (fis != null) {
+            fis.close();
+        }
+        if (fos != null) {
+            fos.close();
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/FileReaderTest.java b/luni/src/test/java/tests/api/java/io/FileReaderTest.java
new file mode 100644
index 0000000..d2ed6de
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/FileReaderTest.java
@@ -0,0 +1,123 @@
+/*
+ *  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.io;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+public class FileReaderTest extends TestCase {
+
+    FileReader br;
+
+    BufferedWriter bw;
+
+    FileInputStream fis;
+
+    File f;
+
+    /**
+     * java.io.FileReader#FileReader(java.io.File)
+     */
+    public void test_ConstructorLjava_io_File() throws IOException {
+        bw = new BufferedWriter(new FileWriter(f.getPath()));
+        bw.write(" After test string", 0, 18);
+        bw.close();
+        br = new FileReader(f);
+        char[] buf = new char[100];
+        int r = br.read(buf);
+        br.close();
+        assertEquals("Failed to read correct chars", " After test string",
+                new String(buf, 0, r));
+    }
+
+    /**
+     * java.io.FileReader#FileReader(java.io.FileDescriptor)
+     */
+    public void test_ConstructorLjava_io_FileDescriptor() throws IOException {
+        bw = new BufferedWriter(new FileWriter(f.getPath()));
+        bw.write(" After test string", 0, 18);
+        bw.close();
+        FileInputStream fis = new FileInputStream(f.getPath());
+        br = new FileReader(fis.getFD());
+        char[] buf = new char[100];
+        int r = br.read(buf);
+        br.close();
+        fis.close();
+        assertEquals("Failed to read correct chars", " After test string",
+                new String(buf, 0, r));
+    }
+
+    /**
+     * java.io.FileReader#FileReader(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() throws IOException {
+        bw = new BufferedWriter(new FileWriter(f.getPath()));
+        bw.write(" After test string", 0, 18);
+        bw.close();
+        br = new FileReader(f.getPath());
+        char[] buf = new char[100];
+        int r = br.read(buf);
+        br.close();
+        assertEquals("Failed to read correct chars", " After test string",
+                new String(buf, 0, r));
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() {
+        f = new File(System.getProperty("user.home"), "reader.tst");
+        if (f.exists()) {
+            if (!f.delete()) {
+                fail("Unable to delete test file");
+            }
+        }
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    protected void tearDown() {
+        try {
+            bw.close();
+        } catch (Exception e) {
+            // Ignore
+        }
+        try {
+            br.close();
+        } catch (Exception e) {
+            // Ignore
+        }
+        try {
+            if (fis != null) {
+                fis.close();
+            }
+        } catch (Exception e) {
+            // Ignore
+        }
+        f.delete();
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/FileTest.java b/luni/src/test/java/tests/api/java/io/FileTest.java
new file mode 100644
index 0000000..829c2da
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/FileTest.java
@@ -0,0 +1,2226 @@
+/*
+ *  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.io;
+
+import junit.framework.TestCase;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import tests.support.Support_PlatformFile;
+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;
+
+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;
+
+    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();
+    }
+
+    protected void tearDown() {
+        if (tempDirectory != null) {
+            deleteTempFolder(tempDirectory);
+            tempDirectory = null;
+        }
+    }
+
+    /**
+     * java.io.File#File(java.io.File, java.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());
+        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 = tempDirectory.getPath();
+        String fileName = "input.tst";
+
+        // Check filename is preserved correctly
+        File d = new File(dirName);
+        File f = new File(d, fileName);
+        dirName = addTrailingSlash(dirName);
+        dirName += fileName;
+        assertEquals("Assert 1: Created incorrect file ",
+                dirName, f.getPath());
+
+        // Check null argument is handled
+        try {
+            f = new File(d, null);
+            fail("Assert 2: NullPointerException not thrown.");
+        } catch (NullPointerException e) {
+            // Expected.
+        }
+    }
+
+    public void test_ConstructorLjava_io_FileLjava_lang_String6() {
+        // Regression for HARMONY-46
+        File f1 = new File("a");
+        File f2 = new File("a/");
+        assertEquals("Trailing slash file name is incorrect", f1, f2);
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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"));
+    }
+
+    /**
+     * 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();
+        }
+    }
+
+    /**
+     * 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();
+        }
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * java.io.File#createNewFile()
+     */
+    public void test_createNewFile_EmptyString() {
+        File f = new File("");
+        try {
+            f.createNewFile();
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+    }
+
+    /**
+     * 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;
+        // }
+    }
+
+    /**
+     * 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();
+            }
+        }
+    }
+
+    /**
+     * 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();
+            }
+        }
+    }
+
+    /**
+     * 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.
+    // /**
+    // * 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);
+    // }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+            }
+        }
+    }
+
+    /**
+     * 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();
+            }
+        }
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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());
+        }
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * java.io.File#getPath()
+     */
+    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;
+
+        file = new File((File) null, "x/y/z");
+        assertEquals("x" + separator + "y" + separator + "z", file.getPath());
+
+        file = new File((String) null, "x/y/z");
+        assertEquals("x" + separator + "y" + separator + "z", file.getPath());
+
+        // Regression for HARMONY-829
+        String f1ParentName = "01";
+        f1 = new File(f1ParentName, "");
+        assertEquals(f1ParentName, f1.getPath());
+
+        String f2ParentName = "0";
+        f2 = new File(f2ParentName, "");
+
+        assertEquals(-1, f2.compareTo(f1));
+        assertEquals(1, f1.compareTo(f2));
+
+        File parent = tempDirectory;
+        f3 = new File(parent, "");
+
+        assertEquals(parent.getPath(), f3.getPath());
+
+        File file0 = new File("");
+        assertEquals("", file0.getPath());
+
+        // Regression for HARMONY-3869
+        // Behavior here is system-dependent according to the RI javadoc.
+        String path1 = new File("", "").getPath();
+        assertTrue(path1.equals(File.separator) || path1.isEmpty());
+        String path2 = new File(new File(""), "").getPath();
+        assertTrue(path2.equals(File.separator) || path2.isEmpty());
+    }
+
+    /**
+     * java.io.File#hashCode()
+     */
+    public void test_hashCode() {
+        // Regression for HARMONY-53
+        File mfile = new File("SoMe FiLeNaMe"); // Mixed case
+        File lfile = new File("some filename"); // Lower case
+
+        if (mfile.equals(lfile)) {
+            assertTrue("Assert 0: wrong hashcode", mfile.hashCode() == lfile
+                    .hashCode());
+        } else {
+            assertFalse("Assert 1: wrong hashcode", mfile.hashCode() == lfile
+                    .hashCode());
+        }
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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();
+        }
+    }
+
+    /**
+     * 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();
+    }
+
+    public void test_isHidden() throws IOException, InterruptedException {
+        boolean onUnix = File.separatorChar == '/';
+        assertTrue(onUnix);
+
+        // On Unix hidden files are marked with a "." at the beginning
+        // of the file name.
+        File f1 = File.createTempFile("harmony-test-FileTest_notHidden_", ".tmp");
+        File f2 = File.createTempFile(".harmony-test-FileTest_isHidden_", ".tmp");
+        assertFalse(f1.isHidden());
+        assertTrue(f2.isHidden());
+        // We can still delete hidden files.
+        assertTrue(f2.delete());
+        f1.delete();
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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();
+        }
+    }
+
+    /**
+     * 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();
+        }
+    }
+
+    /**
+     * 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();
+        }
+    }
+
+    /**
+     * 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();
+        }
+    }
+
+    /**
+     * 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();
+        }
+    }
+
+    /**
+     * 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);
+        }
+    }
+
+    /**
+     * 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();
+        }
+    }
+
+    /**
+     * java.io.File#mkdir()
+     * <p/>
+     * 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());
+    }
+
+    /**
+     * 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();
+        }
+    }
+
+    /**
+     * 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();
+        }
+    }
+
+    /**
+     * 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();
+            }
+        }
+    }
+
+    /**
+     * 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();
+            }
+        }
+    }
+
+    /**
+     * 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);
+        }
+    }
+
+    /**
+     * 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("/"));
+    }
+
+    /**
+     * 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("/"));
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * serialization
+     */
+    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);
+    }
+
+    /**
+     * serialization/deserialization.
+     */
+    public void test_serialization_self() throws Exception {
+        File testFile = new File("test.ser");
+        SerializationTest.verifySelf(testFile);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    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/tests/api/java/io/FileWriterTest.java b/luni/src/test/java/tests/api/java/io/FileWriterTest.java
new file mode 100644
index 0000000..1fb38dc
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/FileWriterTest.java
@@ -0,0 +1,197 @@
+/*
+ *  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.io;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+public class FileWriterTest extends TestCase {
+
+    FileWriter fw;
+
+    FileInputStream fis;
+
+    BufferedWriter bw;
+
+    File f;
+
+    FileOutputStream fos;
+
+    BufferedReader br;
+
+    /**
+     * java.io.FileWriter#FileWriter(java.io.File)
+     */
+    public void test_ConstructorLjava_io_File() throws IOException {
+        fos = new FileOutputStream(f.getPath());
+        fos.write("Test String".getBytes());
+        fos.close();
+        bw = new BufferedWriter(new FileWriter(f));
+        bw.write(" After test string", 0, 18);
+        bw.close();
+        br = new BufferedReader(new FileReader(f.getPath()));
+        char[] buf = new char[100];
+        int r = br.read(buf);
+        br.close();
+        assertEquals("Failed to write correct chars", " After test string",
+                new String(buf, 0, r));
+    }
+
+    /**
+     * java.io.FileWriter#FileWriter(java.io.File, boolean)
+     */
+    public void test_ConstructorLjava_io_FileZ() throws IOException {
+        FileWriter fileWriter = new FileWriter(f);
+
+        String first = "The first string for testing. ";
+        fileWriter.write(first);
+        fileWriter.close();
+
+        fileWriter = new FileWriter(f, true);
+        String second = "The second String for testing.";
+        fileWriter.write(second);
+        fileWriter.close();
+
+        FileReader fileReader = new FileReader(f);
+        char[] out = new char[first.length() + second.length() + 10];
+        int length = fileReader.read(out);
+        fileReader.close();
+        assertEquals(first + second, new String(out, 0, length));
+
+        fileWriter = new FileWriter(f);
+        first = "The first string for testing. ";
+        fileWriter.write(first);
+        fileWriter.close();
+
+        fileWriter = new FileWriter(f, false);
+        second = "The second String for testing.";
+        fileWriter.write(second);
+        fileWriter.close();
+
+        fileReader = new FileReader(f);
+        out = new char[first.length() + second.length() + 10];
+        length = fileReader.read(out);
+        fileReader.close();
+        assertEquals(second, new String(out, 0, length));
+    }
+
+    /**
+     * java.io.FileWriter#FileWriter(java.io.FileDescriptor)
+     */
+    public void test_ConstructorLjava_io_FileDescriptor() throws IOException {
+        fos = new FileOutputStream(f.getPath());
+        fos.write("Test String".getBytes());
+        fos.close();
+        fis = new FileInputStream(f.getPath());
+        br = new BufferedReader(new FileReader(fis.getFD()));
+        char[] buf = new char[100];
+        int r = br.read(buf);
+        br.close();
+        fis.close();
+        assertTrue("Failed to write correct chars: " + new String(buf, 0, r),
+                new String(buf, 0, r).equals("Test String"));
+    }
+
+    /**
+     * java.io.FileWriter#FileWriter(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() throws IOException {
+        fos = new FileOutputStream(f.getPath());
+        fos.write("Test String".getBytes());
+        fos.close();
+        bw = new BufferedWriter(new FileWriter(f.getPath()));
+        bw.write(" After test string", 0, 18);
+        bw.close();
+        br = new BufferedReader(new FileReader(f.getPath()));
+        char[] buf = new char[100];
+        int r = br.read(buf);
+        br.close();
+        assertEquals("Failed to write correct chars", " After test string",
+                new String(buf, 0, r));
+    }
+
+    /**
+     * java.io.FileWriter#FileWriter(java.lang.String, boolean)
+     */
+    public void test_ConstructorLjava_lang_StringZ() throws IOException {
+        fos = new FileOutputStream(f.getPath());
+        fos.write("Test String".getBytes());
+        fos.close();
+        bw = new BufferedWriter(new FileWriter(f.getPath(), true));
+        bw.write(" After test string", 0, 18);
+        bw.close();
+        br = new BufferedReader(new FileReader(f.getPath()));
+        char[] buf = new char[100];
+        int r = br.read(buf);
+        br.close();
+        assertEquals("Failed to append to file",
+                "Test String After test string", new String(buf, 0, r));
+
+        fos = new FileOutputStream(f.getPath());
+        fos.write("Test String".getBytes());
+        fos.close();
+        bw = new BufferedWriter(new FileWriter(f.getPath(), false));
+        bw.write(" After test string", 0, 18);
+        bw.close();
+        br = new BufferedReader(new FileReader(f.getPath()));
+        buf = new char[100];
+        r = br.read(buf);
+        br.close();
+        assertEquals("Failed to overwrite file", " After test string",
+                new String(buf, 0, r));
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    @Override
+    protected void setUp() {
+        f = new File(System.getProperty("user.home"), "writer.tst");
+        if (f.exists()) {
+            if (!f.delete()) {
+                fail("Unable to delete test file");
+            }
+        }
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    @Override
+    protected void tearDown() {
+        try {
+            bw.close();
+        } catch (Exception e) {
+        }
+        try {
+            fis.close();
+        } catch (Exception e) {
+        }
+        f.delete();
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/FilterInputStreamTest.java b/luni/src/test/java/tests/api/java/io/FilterInputStreamTest.java
new file mode 100644
index 0000000..14b63dc
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/FilterInputStreamTest.java
@@ -0,0 +1,167 @@
+/*
+ *  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.io;
+
+import java.io.File;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import junit.framework.TestCase;
+import tests.support.Support_PlatformFile;
+
+public class FilterInputStreamTest extends TestCase {
+
+    static class MyFilterInputStream extends FilterInputStream {
+        public MyFilterInputStream(InputStream is) {
+            super(is);
+        }
+    }
+
+    private String fileName;
+
+    private InputStream is;
+
+    byte[] ibuf = new byte[4096];
+
+    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_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";
+
+    /**
+     * java.io.FilterInputStream#available()
+     */
+    public void test_available() throws IOException {
+        assertTrue("Returned incorrect number of available bytes", is
+                .available() == fileString.length());
+    }
+
+    /**
+     * java.io.FilterInputStream#close()
+     */
+    public void test_close() throws IOException {
+        is.close();
+
+        try {
+            is.read();
+            fail("Able to read from closed stream");
+        } catch (java.io.IOException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.io.FilterInputStream#mark(int)
+     */
+    public void test_markI() {
+        assertTrue("Mark not supported by parent InputStream", true);
+    }
+
+    /**
+     * java.io.FilterInputStream#markSupported()
+     */
+    public void test_markSupported() {
+        assertTrue("markSupported returned true", !is.markSupported());
+    }
+
+    /**
+     * java.io.FilterInputStream#read()
+     */
+    public void test_read() throws Exception {
+        int c = is.read();
+        assertTrue("read returned incorrect char", c == fileString.charAt(0));
+    }
+
+    /**
+     * java.io.FilterInputStream#read(byte[])
+     */
+    public void test_read$B() throws Exception {
+        byte[] buf1 = new byte[100];
+        is.read(buf1);
+        assertTrue("Failed to read correct data", new String(buf1, 0,
+                buf1.length, "UTF-8").equals(fileString.substring(0, 100)));
+    }
+
+    /**
+     * java.io.FilterInputStream#read(byte[], int, int)
+     */
+    public void test_read$BII() throws Exception {
+        byte[] buf1 = new byte[100];
+        is.skip(3000);
+        is.mark(1000);
+        is.read(buf1, 0, buf1.length);
+        assertTrue("Failed to read correct data", new String(buf1, 0,
+                buf1.length, "UTF-8").equals(fileString.substring(3000, 3100)));
+    }
+
+    /**
+     * java.io.FilterInputStream#reset()
+     */
+    public void test_reset() {
+        try {
+            is.reset();
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.FilterInputStream#skip(long)
+     */
+    public void test_skipJ() throws Exception {
+        byte[] buf1 = new byte[10];
+        is.skip(1000);
+        is.read(buf1, 0, buf1.length);
+        assertTrue("Failed to skip to correct position", new String(buf1, 0,
+                buf1.length, "UTF-8").equals(fileString.substring(1000, 1010)));
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    @Override
+    protected void setUp() throws IOException {
+        fileName = System.getProperty("user.dir");
+        String separator = System.getProperty("file.separator");
+        if (fileName.charAt(fileName.length() - 1) == separator.charAt(0)) {
+            fileName = Support_PlatformFile.getNewPlatformFile(fileName,
+                    "input.tst");
+        } else {
+            fileName = Support_PlatformFile.getNewPlatformFile(fileName
+                    + separator, "input.tst");
+        }
+        java.io.OutputStream fos = new java.io.FileOutputStream(fileName);
+        fos.write(fileString.getBytes("UTF-8"));
+        fos.close();
+        is = new MyFilterInputStream(new java.io.FileInputStream(fileName));
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    @Override
+    protected void tearDown() {
+        try {
+            is.close();
+        } catch (Exception e) {
+            // Ignored
+        }
+        new File(fileName).delete();
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/FilterOutputStreamTest.java b/luni/src/test/java/tests/api/java/io/FilterOutputStreamTest.java
new file mode 100644
index 0000000..5a5b6b0
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/FilterOutputStreamTest.java
@@ -0,0 +1,138 @@
+/*
+ *  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.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import junit.framework.TestCase;
+
+public class FilterOutputStreamTest extends TestCase {
+
+    private OutputStream os;
+
+    ByteArrayOutputStream bos;
+
+    ByteArrayInputStream bis;
+
+    byte[] ibuf = new byte[4096];
+
+    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_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";
+
+    /**
+     * java.io.FilterOutputStream#FilterOutputStream(java.io.OutputStream)
+     */
+    public void test_ConstructorLjava_io_OutputStream() throws IOException {
+        bos = new ByteArrayOutputStream();
+        os = new FilterOutputStream(bos);
+        os.write('t');
+    }
+
+    /**
+     * java.io.FilterOutputStream#close()
+     */
+    public void test_close() throws IOException {
+        bos = new ByteArrayOutputStream();
+        os = new FilterOutputStream(bos);
+        os.write(fileString.getBytes(), 0, 500);
+        os.flush();
+        assertEquals("Bytes not written after flush", 500, bos.size());
+        os.close();
+    }
+
+    /**
+     * java.io.FilterOutputStream#flush()
+     */
+    public void test_flush() throws IOException {
+        bos = new ByteArrayOutputStream();
+        os = new FilterOutputStream(bos);
+        os.write(fileString.getBytes(), 0, 500);
+        os.flush();
+        assertEquals("Bytes not written after flush", 500, bos.size());
+        os.close();
+    }
+
+    /**
+     * java.io.FilterOutputStream#write(byte[])
+     */
+    public void test_write$B() throws IOException {
+        bos = new ByteArrayOutputStream();
+        os = new FilterOutputStream(bos);
+        os.write(fileString.getBytes());
+        bis = new ByteArrayInputStream(bos.toByteArray());
+        os.flush();
+        assertTrue("Bytes not written after flush",
+                bis.available() == fileString.length());
+        byte[] wbytes = new byte[fileString.length()];
+        bis.read(wbytes, 0, fileString.length());
+        assertTrue("Incorrect bytes written", fileString.equals(new String(
+                wbytes, 0, wbytes.length)));
+    }
+
+    /**
+     * java.io.FilterOutputStream#write(byte[], int, int)
+     */
+    public void test_write$BII() throws IOException {
+        bos = new ByteArrayOutputStream();
+        os = new FilterOutputStream(bos);
+        os.write(fileString.getBytes(), 0, fileString.length());
+        bis = new ByteArrayInputStream(bos.toByteArray());
+        os.flush();
+        assertTrue("Bytes not written after flush",
+                bis.available() == fileString.length());
+        byte[] wbytes = new byte[fileString.length()];
+        bis.read(wbytes, 0, fileString.length());
+        assertTrue("Incorrect bytes written", fileString.equals(new String(
+                wbytes, 0, wbytes.length)));
+    }
+
+    /**
+     * java.io.FilterOutputStream#write(int)
+     */
+    public void test_writeI() throws IOException {
+        bos = new ByteArrayOutputStream();
+        os = new FilterOutputStream(bos);
+        os.write('t');
+        bis = new ByteArrayInputStream(bos.toByteArray());
+        os.flush();
+        assertEquals("Byte not written after flush", 1, bis.available());
+        byte[] wbytes = new byte[1];
+        bis.read(wbytes, 0, 1);
+        assertEquals("Incorrect byte written", 't', wbytes[0]);
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    protected void tearDown() {
+        try {
+            if (bos != null)
+                bos.close();
+            if (bis != null)
+                bis.close();
+            if (os != null)
+                os.close();
+        } catch (Exception e) {
+            // Ignored
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/IOErrorTest.java b/luni/src/test/java/tests/api/java/io/IOErrorTest.java
new file mode 100644
index 0000000..69f9efd
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/IOErrorTest.java
@@ -0,0 +1,73 @@
+/*
+ *  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.io;
+
+import java.io.IOError;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+import junit.framework.TestCase;
+
+public class IOErrorTest extends TestCase {
+
+    /**
+     * java.io.IOError#IOError(java.lang.Throwable)
+     * @since 1.6
+     */
+    public void test_IOError_LThrowable() {
+        IOError e = new IOError(null);
+        assertNull(e.getCause());
+
+        String errorMsg = "java.io.IOError"; //$NON-NLS-1$
+        assertTrue(e.toString().contains(errorMsg));
+
+        errorMsg = "A dummy error"; //$NON-NLS-1$
+        e = new IOError(new Throwable(errorMsg));
+        assertTrue(e.toString().contains(errorMsg));
+
+        try {
+            throw new IOError(null);
+        } catch (IOError error) {
+            return;
+        } catch (Error error) {
+            fail("Error during IOException test" + error.toString()); //$NON-NLS-1$
+        }
+        fail("Failed to generate error"); //$NON-NLS-1$
+    }
+
+    /**
+     * serialization/deserialization.
+     * @since 1.6
+     */
+    public void testSerializationSelf() throws Exception {
+        String errorMsg = "java.io.IOError";
+        IOError e = new IOError(new Throwable(errorMsg));
+        SerializationTest.verifySelf(e);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     * @since 1.6
+     */
+    public void testSerializationCompatibility() throws Exception {
+        String errorMsg = "java.io.IOError";
+        IOError e = new IOError(new Throwable(errorMsg));
+        SerializationTest.verifyGolden(this, e);
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/io/IOExceptionTest.java b/luni/src/test/java/tests/api/java/io/IOExceptionTest.java
new file mode 100644
index 0000000..943fc8b
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/IOExceptionTest.java
@@ -0,0 +1,113 @@
+/*
+ *  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.io;
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+public class IOExceptionTest extends TestCase {
+
+    /**
+     * java.io.IOException#IOException()
+     */
+    public void test_Constructor() {
+        try {
+            if (true) {
+                throw new IOException();
+            }
+            fail("Exception during IOException test");
+        } catch (IOException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.io.IOException#IOException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        try {
+            if (true) {
+                throw new IOException("Some error message");
+            }
+            fail("Failed to generate exception");
+        } catch (IOException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.io.IOException#IOException(java.lang.String,
+     *java.lang.Throwable)
+     * @since 1.6
+     */
+    public void test_ConstructorLString_LThrowable() {
+        // Test for constructor java.io.IOException(java.lang.String, java.lang.Throwable)
+
+        IOException ioException = new IOException(
+                "A dummy IOException", new Throwable("A dummy Throwable")); //$NON-NLS-1$//$NON-NLS-2$
+        assertEquals("A dummy IOException", ioException.getMessage()); //$NON-NLS-1$
+
+        try {
+            throw new IOException(
+                    "A dummy error", new Throwable("Some error message")); //$NON-NLS-1$ //$NON-NLS-2$
+        } catch (IOException e) {
+            return;
+        } catch (Exception e) {
+            fail("Exception during IOException test" + e.toString()); //$NON-NLS-1$
+        }
+        fail("Failed to generate exception"); //$NON-NLS-1$
+    }
+
+    /**
+     * java.io.IOException#IOException(java.lang.Throwable)
+     * @since 1.6
+     */
+    public void test_Constructor_LThrowable() {
+        // Test for constructor java.io.IOException(java.lang.Throwable)
+        Throwable cause = new Throwable("A dummy Throwable"); //$NON-NLS-1$
+        IOException ioException = new IOException(cause);
+        assertEquals(cause.toString(), ioException.getMessage());
+
+        ioException = new IOException((Throwable) null);
+        assertNull(ioException.getMessage());
+
+        try {
+            throw new IOException(new Throwable("Some error message")); //$NON-NLS-1$
+        } catch (IOException e) {
+            return;
+        } catch (Exception e) {
+            fail("Exception during IOException test" + e.toString()); //$NON-NLS-1$
+        }
+        fail("Failed to generate exception"); //$NON-NLS-1$
+    }
+
+    /**
+     * 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() {
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/InputStreamReaderTest.java b/luni/src/test/java/tests/api/java/io/InputStreamReaderTest.java
new file mode 100644
index 0000000..fa9f5b9
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/InputStreamReaderTest.java
@@ -0,0 +1,536 @@
+/*
+ *  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.io;
+
+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.PrintStream;
+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;
+
+public class InputStreamReaderTest extends TestCase {
+
+    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;
+        }
+
+        @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();
+    }
+
+    /**
+     * 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()));
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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) {
+            assertNotNull(e.getMessage());
+        }
+
+        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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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 {
+            reader.read(null, -1, 1);
+            fail();
+        } catch (NullPointerException expected) {
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        try {
+            reader.read(null, 0, -1);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+        } catch (IndexOutOfBoundsException 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()));
+    }
+
+    /**
+     * 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/tests/api/java/io/InputStreamTest.java b/luni/src/test/java/tests/api/java/io/InputStreamTest.java
new file mode 100644
index 0000000..9d478c7
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/InputStreamTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import junit.framework.TestCase;
+
+public class InputStreamTest extends TestCase {
+    // Regression for HARMONY-4337
+    public void test1() throws IOException {
+        try {
+            InputStream in = new MockInputStream();
+            in.read(null, -1, 1);
+            fail("should throw NullPointerException.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    class MockInputStream extends InputStream {
+        public int read() throws IOException {
+            return 0;
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/InterruptedIOExceptionTest.java b/luni/src/test/java/tests/api/java/io/InterruptedIOExceptionTest.java
new file mode 100644
index 0000000..ae38d0e
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/InterruptedIOExceptionTest.java
@@ -0,0 +1,47 @@
+/*
+ *  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.io;
+
+import java.io.InterruptedIOException;
+
+import junit.framework.TestCase;
+
+public class InterruptedIOExceptionTest extends TestCase {
+
+    /**
+     * java.io.InterruptedIOException#InterruptedIOException()
+     */
+    public void test_Constructor() {
+        try {
+            throw new InterruptedIOException();
+        } catch (InterruptedIOException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.io.InterruptedIOException#InterruptedIOException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        try {
+            throw new InterruptedIOException("Some error message");
+        } catch (InterruptedIOException e) {
+            // Expected
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/InvalidClassExceptionTest.java b/luni/src/test/java/tests/api/java/io/InvalidClassExceptionTest.java
new file mode 100644
index 0000000..de7017a
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/InvalidClassExceptionTest.java
@@ -0,0 +1,71 @@
+/*
+ *  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.io;
+
+import java.io.InvalidClassException;
+
+import junit.framework.TestCase;
+
+public class InvalidClassExceptionTest extends TestCase {
+
+    /**
+     * java.io.InvalidClassException#InvalidClassException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        final String message = "A message";
+        try {
+            if (true) {
+                throw new InvalidClassException(message);
+            }
+            fail("Failed to throw exception");
+        } catch (InvalidClassException e) {
+            // correct
+            assertTrue("Incorrect message read", e.getMessage().equals(message));
+        }
+    }
+
+    /**
+     * java.io.InvalidClassException#InvalidClassException(java.lang.String,
+     *java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_StringLjava_lang_String() {
+        final String message = "A message";
+        final String className = "Object";
+        try {
+            if (true) {
+                throw new InvalidClassException(className, message);
+            }
+            fail("Failed to throw exception");
+        } catch (InvalidClassException e) {
+            // correct
+            String returnedMessage = e.getMessage();
+            assertTrue("Incorrect message read: " + e.getMessage(),
+                    returnedMessage.indexOf(className) >= 0
+                            && returnedMessage.indexOf(message) >= 0);
+        }
+    }
+
+    /**
+     * java.io.InvalidClassException#getMessage()
+     */
+    public void test_getMessage() {
+        // Test for method java.lang.String
+        // java.io.InvalidClassException.getMessage()
+        // used to test
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/LineNumberInputStreamTest.java b/luni/src/test/java/tests/api/java/io/LineNumberInputStreamTest.java
new file mode 100644
index 0000000..189daef
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/LineNumberInputStreamTest.java
@@ -0,0 +1,167 @@
+/*
+ *  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.io;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.LineNumberInputStream;
+import java.io.UnsupportedEncodingException;
+
+import junit.framework.TestCase;
+
+@SuppressWarnings("deprecation")
+public class LineNumberInputStreamTest extends TestCase {
+
+    String text = "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n34\n35\n36\n37\n38\n39\n40\n41\n42\n43\n44\n45\n46\n47\n48\n49\n50\n51\n52\n53\n54\n55\n56\n57\n58\n59\n60\n61\n62\n63\n64\n65\n66\n67\n68\n69\n70\n71\n72\n73\n74\n75\n76\n77\n78\n79\n80\n81\n82\n83\n84\n85\n86\n87\n88\n89\n90\n91\n92\n93\n94\n95\n96\n97\n98\n99\n100\n101\n102\n103\n104\n105\n106\n107\n108\n109\n110\n111\n112\n113\n114\n115\n116\n117\n118\n119\n120\n121\n122\n123\n124\n125\n126\n127\n128\n129\n130\n131\n132\n133\n134\n135\n136\n137\n138\n139\n140\n141\n142\n143\n144\n145\n146\n147\n148\n149\n150\n151\n152\n153\n154\n155\n156\n157\n158\n159\n160\n161\n162\n163\n164\n165\n166\n167\n168\n169\n170\n171\n172\n173\n174\n175\n176\n177\n178\n179\n180\n181\n182\n183\n184\n185\n186\n187\n188\n189\n190\n191\n192\n193\n194\n195\n196\n197\n198\n199\n200\n201\n202\n203\n204\n205\n206\n207\n208\n209\n210\n211\n212\n213\n214\n215\n216\n217\n218\n219\n220\n221\n222\n223\n224\n225\n226\n227\n228\n229\n230\n231\n232\n233\n234\n235\n236\n237\n238\n239\n240\n241\n242\n243\n244\n245\n246\n247\n248\n249\n250\n251\n252\n253\n254\n255\n256\n257\n258\n259\n260\n261\n262\n263\n264\n265\n266\n267\n268\n269\n270\n271\n272\n273\n274\n275\n276\n277\n278\n279\n280\n281\n282\n283\n284\n285\n286\n287\n288\n289\n290\n291\n292\n293\n294\n295\n296\n297\n298\n299\n300\n301\n302\n303\n304\n305\n306\n307\n308\n309\n310\n311\n312\n313\n314\n315\n316\n317\n318\n319\n320\n321\n322\n323\n324\n325\n326\n327\n328\n329\n330\n331\n332\n333\n334\n335\n336\n337\n338\n339\n340\n341\n342\n343\n344\n345\n346\n347\n348\n349\n350\n351\n352\n353\n354\n355\n356\n357\n358\n359\n360\n361\n362\n363\n364\n365\n366\n367\n368\n369\n370\n371\n372\n373\n374\n375\n376\n377\n378\n379\n380\n381\n382\n383\n384\n385\n386\n387\n388\n389\n390\n391\n392\n393\n394\n395\n396\n397\n398\n399\n400\n401\n402\n403\n404\n405\n406\n407\n408\n409\n410\n411\n412\n413\n414\n415\n416\n417\n418\n419\n420\n421\n422\n423\n424\n425\n426\n427\n428\n429\n430\n431\n432\n433\n434\n435\n436\n437\n438\n439\n440\n441\n442\n443\n444\n445\n446\n447\n448\n449\n450\n451\n452\n453\n454\n455\n456\n457\n458\n459\n460\n461\n462\n463\n464\n465\n466\n467\n468\n469\n470\n471\n472\n473\n474\n475\n476\n477\n478\n479\n480\n481\n482\n483\n484\n485\n486\n487\n488\n489\n490\n491\n492\n493\n494\n495\n496\n497\n498\n499\n500\n501";
+
+    String dosText = "0\r\n1\r\n2";
+
+    LineNumberInputStream lnis;
+
+    LineNumberInputStream lnis2;
+
+    /**
+     * java.io.LineNumberInputStream#LineNumberInputStream(java.io.InputStream)
+     */
+    public void test_ConstructorLjava_io_InputStream() {
+        // Used in other tests
+    }
+
+    /**
+     * java.io.LineNumberInputStream#available()
+     */
+    public void test_available() throws IOException {
+        assertTrue("Returned incorrect number of available bytes", lnis
+                .available() == text.length() / 2);
+    }
+
+    /**
+     * java.io.LineNumberInputStream#getLineNumber()
+     */
+    public void test_getLineNumber() throws IOException {
+        assertEquals("New stream returned line number other than zero", 0, lnis
+                .getLineNumber());
+
+        lnis.read();
+        lnis.read();
+
+        assertEquals("stream returned incorrect line number after read", 1,
+                lnis.getLineNumber());
+
+        lnis.setLineNumber(89);
+        assertEquals("stream returned incorrect line number after set", 89,
+                lnis.getLineNumber());
+    }
+
+    /**
+     * java.io.LineNumberInputStream#mark(int)
+     */
+    public void test_markI() throws IOException {
+        lnis.mark(40);
+        lnis.skip(4);
+        lnis.reset();
+        assertEquals("Failed to mark", 0, lnis.getLineNumber());
+        assertEquals("Failed to mark", '0', lnis.read());
+    }
+
+    /**
+     * java.io.LineNumberInputStream#read()
+     */
+    public void test_read() throws IOException {
+        assertEquals("Failed to read correct byte", '0', lnis.read());
+        assertEquals("Failed to read correct byte on dos text", '0', lnis2
+                .read());
+        assertTrue("Failed to read correct byte on dos text",
+                lnis2.read() == '\n');
+        assertEquals("Failed to read correct byte on dos text", '1', lnis2
+                .read());
+        assertTrue("Failed to read correct byte on dos text",
+                lnis2.read() == '\n');
+        assertEquals("Failed to read correct byte on dos text", '2', lnis2
+                .read());
+    }
+
+    /**
+     * java.io.LineNumberInputStream#read(byte[], int, int)
+     */
+    public void test_read$BII() throws IOException, UnsupportedEncodingException {
+        byte[] buf = new byte[100];
+        lnis.read(buf, 0, 100);
+        assertTrue("Failed to read correct bytes on normal text", new String(
+                buf, 0, 100, "UTF-8").equals(text.substring(0, 100)));
+    }
+
+    /**
+     * java.io.LineNumberInputStream#reset()
+     */
+    public void test_reset() throws IOException {
+        lnis.mark(40);
+        lnis.skip(4);
+        lnis.reset();
+        assertEquals("Failed to reset", 0, lnis.getLineNumber());
+        assertEquals("Failed to reset", '0', lnis.read());
+        lnis.reset();
+
+        // see comment for setup
+        try {
+            lnis.mark(5);
+            lnis.skip(100);
+            lnis.reset();
+            fail("Failed to invalidate mark");
+        } catch (IOException e) {
+            // Correct mark has been invalidated
+            // Expected
+        }
+    }
+
+    /**
+     * java.io.LineNumberInputStream#setLineNumber(int)
+     */
+    public void test_setLineNumberI() {
+        lnis.setLineNumber(89);
+        assertEquals("Failed to set line number", 89, lnis.getLineNumber());
+    }
+
+    /**
+     * java.io.LineNumberInputStream#skip(long)
+     */
+    public void test_skipJ() throws IOException {
+        lnis.skip(4);
+        assertEquals("Skip failed to increment lineNumber", 2, lnis
+                .getLineNumber());
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() throws UnsupportedEncodingException {
+        /*
+         * In order for IOException to be thrown in reset(),the inputStream to
+         * the constructor cannot be a byteArrayInputstream because the reset()
+         * in byteArrayInputStream does not throw IOException. When
+         * BufferedInputStream is used, the size of the buffer must be smaller
+         * than the readlimit in mark inorder for IOException to be thrown
+         */
+        BufferedInputStream buftemp = new BufferedInputStream(
+                new ByteArrayInputStream(text.getBytes("UTF-8")), 4);
+        lnis = new LineNumberInputStream(buftemp);
+        lnis2 = new LineNumberInputStream(new ByteArrayInputStream(dosText
+                .getBytes("UTF-8")));
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/LineNumberReaderTest.java b/luni/src/test/java/tests/api/java/io/LineNumberReaderTest.java
new file mode 100644
index 0000000..e90c561
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/LineNumberReaderTest.java
@@ -0,0 +1,221 @@
+/*
+ *  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.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.io.Reader;
+import java.io.StringReader;
+
+import junit.framework.TestCase;
+
+public class LineNumberReaderTest extends TestCase {
+
+    String text = "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n34\n35\n36\n37\n38\n39\n40\n41\n42\n43\n44\n45\n46\n47\n48\n49\n50\n51\n52\n53\n54\n55\n56\n57\n58\n59\n60\n61\n62\n63\n64\n65\n66\n67\n68\n69\n70\n71\n72\n73\n74\n75\n76\n77\n78\n79\n80\n81\n82\n83\n84\n85\n86\n87\n88\n89\n90\n91\n92\n93\n94\n95\n96\n97\n98\n99\n100\n101\n102\n103\n104\n105\n106\n107\n108\n109\n110\n111\n112\n113\n114\n115\n116\n117\n118\n119\n120\n121\n122\n123\n124\n125\n126\n127\n128\n129\n130\n131\n132\n133\n134\n135\n136\n137\n138\n139\n140\n141\n142\n143\n144\n145\n146\n147\n148\n149\n150\n151\n152\n153\n154\n155\n156\n157\n158\n159\n160\n161\n162\n163\n164\n165\n166\n167\n168\n169\n170\n171\n172\n173\n174\n175\n176\n177\n178\n179\n180\n181\n182\n183\n184\n185\n186\n187\n188\n189\n190\n191\n192\n193\n194\n195\n196\n197\n198\n199\n200\n201\n202\n203\n204\n205\n206\n207\n208\n209\n210\n211\n212\n213\n214\n215\n216\n217\n218\n219\n220\n221\n222\n223\n224\n225\n226\n227\n228\n229\n230\n231\n232\n233\n234\n235\n236\n237\n238\n239\n240\n241\n242\n243\n244\n245\n246\n247\n248\n249\n250\n251\n252\n253\n254\n255\n256\n257\n258\n259\n260\n261\n262\n263\n264\n265\n266\n267\n268\n269\n270\n271\n272\n273\n274\n275\n276\n277\n278\n279\n280\n281\n282\n283\n284\n285\n286\n287\n288\n289\n290\n291\n292\n293\n294\n295\n296\n297\n298\n299\n300\n301\n302\n303\n304\n305\n306\n307\n308\n309\n310\n311\n312\n313\n314\n315\n316\n317\n318\n319\n320\n321\n322\n323\n324\n325\n326\n327\n328\n329\n330\n331\n332\n333\n334\n335\n336\n337\n338\n339\n340\n341\n342\n343\n344\n345\n346\n347\n348\n349\n350\n351\n352\n353\n354\n355\n356\n357\n358\n359\n360\n361\n362\n363\n364\n365\n366\n367\n368\n369\n370\n371\n372\n373\n374\n375\n376\n377\n378\n379\n380\n381\n382\n383\n384\n385\n386\n387\n388\n389\n390\n391\n392\n393\n394\n395\n396\n397\n398\n399\n400\n401\n402\n403\n404\n405\n406\n407\n408\n409\n410\n411\n412\n413\n414\n415\n416\n417\n418\n419\n420\n421\n422\n423\n424\n425\n426\n427\n428\n429\n430\n431\n432\n433\n434\n435\n436\n437\n438\n439\n440\n441\n442\n443\n444\n445\n446\n447\n448\n449\n450\n451\n452\n453\n454\n455\n456\n457\n458\n459\n460\n461\n462\n463\n464\n465\n466\n467\n468\n469\n470\n471\n472\n473\n474\n475\n476\n477\n478\n479\n480\n481\n482\n483\n484\n485\n486\n487\n488\n489\n490\n491\n492\n493\n494\n495\n496\n497\n498\n499\n500\n";
+
+    LineNumberReader lnr;
+
+    /**
+     * java.io.LineNumberReader#LineNumberReader(java.io.Reader)
+     */
+    public void test_ConstructorLjava_io_Reader() {
+        lnr = new LineNumberReader(new StringReader(text), 4092);
+        assertEquals("Failed to create reader", 0, lnr.getLineNumber());
+    }
+
+    /**
+     * java.io.LineNumberReader#LineNumberReader(java.io.Reader, int)
+     */
+    public void test_ConstructorLjava_io_ReaderI() {
+        lnr = new LineNumberReader(new StringReader(text));
+        assertEquals("Failed to create reader", 0, lnr.getLineNumber());
+    }
+
+    /**
+     * java.io.LineNumberReader#getLineNumber()
+     */
+    public void test_getLineNumber() throws IOException {
+        lnr = new LineNumberReader(new StringReader(text));
+        assertEquals("Returned incorrect line number--expected 0, got ", 0, lnr
+                .getLineNumber());
+
+        lnr.readLine();
+        lnr.readLine();
+
+        assertTrue("Returned incorrect line number--expected 2, got: "
+                + lnr.getLineNumber(), lnr.getLineNumber() == 2);
+    }
+
+    /**
+     * java.io.LineNumberReader#mark(int)
+     */
+    public void test_markI() throws IOException {
+        lnr = new LineNumberReader(new StringReader(text));
+        String line;
+        lnr.skip(80);
+        lnr.mark(100);
+        line = lnr.readLine();
+        lnr.reset();
+        assertTrue("Failed to return to marked position", line.equals(lnr
+                .readLine()));
+        // The spec does not say the mark has to be invalidated
+    }
+
+    /**
+     * java.io.LineNumberReader#read()
+     */
+    public void test_read() throws IOException {
+        lnr = new LineNumberReader(new StringReader(text));
+
+        int c = lnr.read();
+        assertEquals("Read returned incorrect character", '0', c);
+
+        lnr.read();
+        assertEquals("Read failed to inc lineNumber", 1, lnr.getLineNumber());
+    }
+
+    /**
+     * java.io.LineNumberReader#read(char[], int, int)
+     */
+    public void test_read$CII() throws IOException {
+        lnr = new LineNumberReader(new StringReader(text));
+        char[] c = new char[100];
+        lnr.read(c, 0, 4);
+        assertTrue("Read returned incorrect characters", "0\n1\n"
+                .equals(new String(c, 0, 4)));
+        assertEquals("Read failed to inc lineNumber", 2, lnr.getLineNumber());
+    }
+
+    /**
+     * java.io.LineNumberReader#readLine()
+     */
+    public void test_readLine() throws IOException {
+        lnr = new LineNumberReader(new StringReader(text));
+        assertEquals("Returned incorrect line number", 0, lnr.getLineNumber());
+        String line = null;
+        lnr.readLine();
+        line = lnr.readLine();
+
+        assertEquals("Returned incorrect string", "1", line);
+        assertTrue("Returned incorrect line number :" + lnr.getLineNumber(),
+                lnr.getLineNumber() == 2);
+
+        // Regression for HARMONY-4294
+        byte[] buffer = new byte[] { '\r', '\n' };
+        LineNumberReader reader = new LineNumberReader(new InputStreamReader(
+                new ByteArrayInputStream(buffer), "UTF-8"));
+        assertEquals('\n', reader.read());
+        assertEquals(-1, reader.read());
+        reader = new LineNumberReader(new InputStreamReader(
+                new ByteArrayInputStream(buffer), "UTF-8"));
+        assertNotNull(reader.readLine());
+        assertNull(reader.readLine());
+    }
+
+    /**
+     * java.io.LineNumberReader#reset()
+     */
+    public void test_reset() throws IOException {
+        lnr = new LineNumberReader(new StringReader(text));
+        assertEquals("Returned incorrect line number", 0, lnr.getLineNumber());
+        String line = null;
+        lnr.mark(100);
+        lnr.readLine();
+        lnr.reset();
+        line = lnr.readLine();
+
+        assertEquals("Failed to reset reader", "0", line);
+    }
+
+    public void testReadLineSourceThrows() throws IOException {
+        lnr = new LineNumberReader(new Reader() {
+            private StringReader delegate = new StringReader("hello\nworld");
+            private int calls = 0;
+
+            @Override
+            public void close() throws IOException {
+            }
+
+            @Override
+            public int read(char[] buf, int offset, int len) throws IOException {
+                if (calls++ < 2) {
+                    throw new IOException();
+                } else {
+                    return delegate.read(buf, offset, len);
+                }
+            }
+        });
+
+        assertEquals(0, lnr.getLineNumber());
+        try {
+            lnr.readLine();
+            fail();
+        } catch (IOException expected) {
+        }
+
+        assertEquals(0, lnr.getLineNumber());
+        try {
+            lnr.readLine();
+            fail();
+        } catch (IOException expected) {
+        }
+
+        assertEquals(0, lnr.getLineNumber());
+        assertEquals("hello", lnr.readLine());
+        assertEquals(1, lnr.getLineNumber());
+        assertEquals("world", lnr.readLine());
+        assertEquals(2, lnr.getLineNumber());
+    }
+
+    public void testGetLineNumberAfterEnd() throws IOException {
+        lnr = new LineNumberReader(new StringReader("hello\nworld"));
+        assertEquals(0, lnr.getLineNumber());
+        assertEquals("hello", lnr.readLine());
+        assertEquals(1, lnr.getLineNumber());
+        assertEquals("world", lnr.readLine());
+        assertEquals(2, lnr.getLineNumber());
+        assertEquals(null, lnr.readLine());
+        assertEquals(2, lnr.getLineNumber());
+        assertEquals(null, lnr.readLine());
+        assertEquals(2, lnr.getLineNumber());
+    }
+
+    /**
+     * java.io.LineNumberReader#setLineNumber(int)
+     */
+    public void test_setLineNumberI() {
+        lnr = new LineNumberReader(new StringReader(text));
+        lnr.setLineNumber(1001);
+        assertEquals("set incorrect line number", 1001, lnr.getLineNumber());
+    }
+
+    /**
+     * java.io.LineNumberReader#skip(long)
+     */
+    public void test_skipJ() throws IOException {
+        lnr = new LineNumberReader(new StringReader(text));
+        char[] c = new char[100];
+        lnr.skip(80);
+        lnr.read(c, 0, 100);
+
+        assertTrue("Failed to skip to correct position", text
+                .substring(80, 180).equals(new String(c, 0, c.length)));
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/NotActiveExceptionTest.java b/luni/src/test/java/tests/api/java/io/NotActiveExceptionTest.java
new file mode 100644
index 0000000..a34a349
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/NotActiveExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.io;
+
+import java.io.NotActiveException;
+
+import junit.framework.TestCase;
+
+public class NotActiveExceptionTest extends TestCase {
+
+    /**
+     * java.io.NotActiveException#NotActiveException()
+     */
+    public void test_Constructor() {
+        NotActiveException e = new NotActiveException();
+        assertNull(e.getMessage());
+    }
+
+    /**
+     * java.io.NotActiveException#NotActiveException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        String message = "Exception message";
+        NotActiveException e = new NotActiveException(message);
+        assertSame(message, e.getMessage());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/NotSerializableExceptionTest.java b/luni/src/test/java/tests/api/java/io/NotSerializableExceptionTest.java
new file mode 100644
index 0000000..a4c90c8
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/NotSerializableExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.io;
+
+import java.io.NotSerializableException;
+
+import junit.framework.TestCase;
+
+public class NotSerializableExceptionTest extends TestCase {
+
+    /**
+     * java.io.NotSerializableException#NotSerializableException()
+     */
+    public void test_Constructor() {
+        NotSerializableException nse = new NotSerializableException();
+        assertNull(nse.getMessage());
+    }
+
+    /**
+     * java.io.NotSerializableException#NotSerializableException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        String message = "Test message";
+        NotSerializableException nse = new NotSerializableException(message);
+        assertSame(message, nse.getMessage());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/ObjectInputStream2Test.java b/luni/src/test/java/tests/api/java/io/ObjectInputStream2Test.java
new file mode 100644
index 0000000..6988f27
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/ObjectInputStream2Test.java
@@ -0,0 +1,213 @@
+/*
+ * 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.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InvalidClassException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.util.ArrayList;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class ObjectInputStream2Test extends TestCase {
+
+    public void test_readUnshared() throws IOException, ClassNotFoundException {
+        // Regression test for HARMONY-819
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream oos = new ObjectOutputStream(baos);
+            oos.writeObject("abc");
+            oos.writeObject("abc");
+            oos.close();
+
+            ObjectInputStream ois = new ObjectInputStream(
+                    new ByteArrayInputStream(baos.toByteArray()));
+            ois.readUnshared();
+            ois.readObject();
+            ois.close();
+            fail("Expected ObjectStreamException");
+        } catch (ObjectStreamException e) {
+            // expected
+        }
+    }
+
+    /**
+     * Micro-scenario of de/serialization of an object with non-serializable
+     * superclass. The super-constructor only should be invoked on the
+     * deserialized instance.
+     */
+    public void test_readObject_Hierarchy() throws IOException,
+            ClassNotFoundException {
+        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();
+        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);
+    }
+
+    /**
+     * {@link java.io.ObjectInputStream#readNewLongString()}
+     */
+    public void test_readNewLongString() throws Exception {
+        LongString longString = new LongString();
+        SerializationTest.verifySelf(longString);
+    }
+
+    @SuppressWarnings("serial")
+    private static class LongString implements Serializable {
+        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();
+        }
+
+    }
+
+    public void test_readClassDescriptor() throws ClassNotFoundException,
+            IOException {
+        try {
+            new OIS().test();
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    static class TestObjectInputStream extends ObjectInputStream {
+        public TestObjectInputStream(InputStream in) throws IOException {
+            super(in);
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        protected Class resolveClass(ObjectStreamClass desc)
+                throws IOException, ClassNotFoundException {
+            if (desc.getName().endsWith("ObjectInputStream2Test$TestClass1")) {
+                return TestClass2.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;
+    }
+
+    public void test_resolveClass_invalidClassName() throws Exception {
+        // Regression test for HARMONY-1920
+        TestClass1 to1 = new TestClass1();
+        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();
+        bais = new ByteArrayInputStream(bytes);
+        ois = new TestObjectInputStream(bais);
+
+        try {
+            ois.readObject();
+            fail("Should throw InvalidClassException");
+        } catch (InvalidClassException ice) {
+            // Excpected
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/ObjectOutputStream2Test.java b/luni/src/test/java/tests/api/java/io/ObjectOutputStream2Test.java
new file mode 100644
index 0000000..82d82b9
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/ObjectOutputStream2Test.java
@@ -0,0 +1,59 @@
+/*
+ *  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.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import junit.framework.TestCase;
+
+public class ObjectOutputStream2Test extends TestCase {
+
+    private static enum MyEnum {
+        ONE {
+            public void anything() {
+            }
+        },
+        TWO {
+            public void anything() {
+            }
+        },
+        THREE {
+            public void anything() {
+            }
+        };
+
+        public abstract void anything();
+    }
+
+    public void test_writeReadEnum() throws IOException, ClassNotFoundException {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        ObjectOutputStream os = new ObjectOutputStream(bos);
+        os.writeObject(MyEnum.TWO);
+        os.close();
+
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        ObjectInputStream is = new ObjectInputStream(bis);
+        Object readObj = is.readObject();
+        is.close();
+        assertSame(MyEnum.TWO, readObj);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/ObjectOutputStreamTest.java b/luni/src/test/java/tests/api/java/io/ObjectOutputStreamTest.java
new file mode 100644
index 0000000..96d1771
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/ObjectOutputStreamTest.java
@@ -0,0 +1,1323 @@
+/*
+ *  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.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Externalizable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.NotActiveException;
+import java.io.NotSerializableException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.ObjectStreamConstants;
+import java.io.ObjectStreamException;
+import java.io.ObjectStreamField;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.io.SerializablePermission;
+import java.io.WriteAbortedException;
+import java.security.Permission;
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+@SuppressWarnings({ "unused", "serial" })
+public class ObjectOutputStreamTest extends TestCase implements Serializable {
+
+    File f;
+
+    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 IOException {
+            // note aField2 is not read
+            try {
+                ObjectInputStream.GetField fields = ois.readFields();
+                aField1 = (String) fields.get("aField1", "Zap");
+            } catch (Exception e) {
+            }
+        }
+
+        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;
+        }
+    }
+
+    private static class SerializationTest implements java.io.Serializable {
+        int anInt = INIT_INT_VALUE;
+
+        public SerializationTest() {
+            super();
+        }
+    }
+
+    private static class SerializationTestSubclass1 extends SerializationTest
+            implements Serializable {
+        String aString = INIT_STR_VALUE;
+
+        public SerializationTestSubclass1() {
+            super();
+            // Just to change default superclass init value
+            anInt = INIT_INT_VALUE / 2;
+        }
+    }
+
+    private static class SpecTestSuperClass implements Runnable, Serializable {
+        protected java.lang.String instVar;
+
+        public void run() {
+        }
+    }
+
+    private static class SpecTest extends SpecTestSuperClass implements
+            Cloneable, Serializable {
+        public java.lang.String instVar1;
+
+        public static java.lang.String staticVar1;
+
+        public static java.lang.String staticVar2;
+
+        {
+            instVar1 = "NonStaticInitialValue";
+        }
+
+        static {
+            staticVar1 = "StaticInitialValue";
+            staticVar1 = new String(staticVar1);
+        }
+
+        public Object method(Object objParam, Object objParam2) {
+            return new Object();
+        }
+
+        public boolean method(boolean bParam, Object objParam) {
+            return true;
+        }
+
+        public boolean method(boolean bParam, Object objParam, Object objParam2) {
+            return true;
+        }
+
+    }
+
+    private static class SpecTestSubclass extends SpecTest implements
+            Serializable {
+        public transient java.lang.String transientInstVar = "transientValue";
+    }
+
+    private static class ReadWriteObject implements java.io.Serializable {
+        public boolean calledWriteObject = false;
+
+        public boolean calledReadObject = false;
+
+        public ReadWriteObject() {
+            super();
+        }
+
+        private void readObject(java.io.ObjectInputStream in)
+                throws java.io.IOException, ClassNotFoundException {
+            calledReadObject = true;
+            in.readObject();
+        }
+
+        private void writeObject(java.io.ObjectOutputStream out)
+                throws java.io.IOException {
+            calledWriteObject = true;
+            out.writeObject(FOO);
+        }
+    }
+
+    private static class PublicReadWriteObject implements java.io.Serializable {
+        public boolean calledWriteObject = false;
+
+        public boolean calledReadObject = false;
+
+        public PublicReadWriteObject() {
+            super();
+        }
+
+        public void readObject(java.io.ObjectInputStream in)
+                throws java.io.IOException, ClassNotFoundException {
+            calledReadObject = true;
+            in.readObject();
+        }
+
+        public void writeObject(java.io.ObjectOutputStream out)
+                throws java.io.IOException {
+            calledWriteObject = true;
+            out.writeObject(FOO);
+        }
+    }
+
+    private static class FieldOrder implements Serializable {
+        String aaa1NonPrimitive = "aaa1";
+
+        int bbb1PrimitiveInt = 5;
+
+        boolean aaa2PrimitiveBoolean = true;
+
+        String bbb2NonPrimitive = "bbb2";
+    }
+
+    private static class JustReadObject implements java.io.Serializable {
+        public boolean calledReadObject = false;
+
+        public JustReadObject() {
+            super();
+        }
+
+        private void readObject(java.io.ObjectInputStream in)
+                throws java.io.IOException, ClassNotFoundException {
+            calledReadObject = true;
+            in.defaultReadObject();
+        }
+    }
+
+    private static class JustWriteObject implements java.io.Serializable {
+        public boolean calledWriteObject = false;
+
+        public JustWriteObject() {
+            super();
+        }
+
+        private void writeObject(java.io.ObjectOutputStream out)
+                throws java.io.IOException, ClassNotFoundException {
+            calledWriteObject = true;
+            out.defaultWriteObject();
+        }
+    }
+
+    private static class ClassBasedReplacementWhenDumping implements
+            java.io.Serializable {
+        public boolean calledReplacement = false;
+
+        public ClassBasedReplacementWhenDumping() {
+            super();
+        }
+
+        private Object writeReplace() {
+            calledReplacement = true;
+            return FOO; // Replacement is a String
+        }
+    }
+
+    private static class MultipleClassBasedReplacementWhenDumping implements
+            java.io.Serializable {
+        private static class C1 implements java.io.Serializable {
+            private Object writeReplace() {
+                return new C2();
+            }
+        }
+
+        private static class C2 implements java.io.Serializable {
+            private Object writeReplace() {
+                return new C3();
+            }
+        }
+
+        private static class C3 implements java.io.Serializable {
+            private Object writeReplace() {
+                return FOO;
+            }
+        }
+
+        public MultipleClassBasedReplacementWhenDumping() {
+            super();
+        }
+
+        private Object writeReplace() {
+            return new C1();
+        }
+    }
+
+    private static class ClassBasedReplacementWhenLoading implements
+            java.io.Serializable {
+        public ClassBasedReplacementWhenLoading() {
+            super();
+        }
+
+        private Object readResolve() {
+            return FOO; // Replacement is a String
+        }
+    }
+
+    private static class ClassBasedReplacementWhenLoadingViolatesFieldType
+            implements java.io.Serializable {
+        public ClassBasedReplacementWhenLoading classBasedReplacementWhenLoading = new ClassBasedReplacementWhenLoading();
+
+        public ClassBasedReplacementWhenLoadingViolatesFieldType() {
+            super();
+        }
+    }
+
+    private static class MyExceptionWhenDumping implements java.io.Serializable {
+        private static class MyException extends java.io.IOException {
+        }
+
+        ;
+
+        public boolean anInstanceVar = false;
+
+        public MyExceptionWhenDumping() {
+            super();
+        }
+
+        private void readObject(java.io.ObjectInputStream in)
+                throws java.io.IOException, ClassNotFoundException {
+            in.defaultReadObject();
+        }
+
+        private void writeObject(java.io.ObjectOutputStream out)
+                throws java.io.IOException, ClassNotFoundException {
+            throw new MyException();
+        }
+    }
+
+    private static class NonSerializableExceptionWhenDumping implements
+            java.io.Serializable {
+        public Object anInstanceVar = new Object();
+
+        public NonSerializableExceptionWhenDumping() {
+            super();
+        }
+    }
+
+    private static class MyUnserializableExceptionWhenDumping implements
+            java.io.Serializable {
+        private static class MyException extends java.io.IOException {
+            private Object notSerializable = new Object();
+        }
+
+        ;
+
+        public boolean anInstanceVar = false;
+
+        public MyUnserializableExceptionWhenDumping() {
+            super();
+        }
+
+        private void readObject(java.io.ObjectInputStream in)
+                throws java.io.IOException, ClassNotFoundException {
+            in.defaultReadObject();
+        }
+
+        private void writeObject(java.io.ObjectOutputStream out)
+                throws java.io.IOException, ClassNotFoundException {
+            throw new MyException();
+        }
+    }
+
+    private static class WithUnmatchingSerialPersistentFields implements
+            java.io.Serializable {
+        private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
+                "value", String.class) };
+
+        public int anInstanceVar = 5;
+
+        public WithUnmatchingSerialPersistentFields() {
+            super();
+        }
+    }
+
+    private static class WithMatchingSerialPersistentFields implements
+            java.io.Serializable {
+        private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
+                "anInstanceVar", String.class) };
+
+        public String anInstanceVar = FOO + FOO;
+
+        public WithMatchingSerialPersistentFields() {
+            super();
+        }
+    }
+
+    private static class SerialPersistentFields implements java.io.Serializable {
+        private static final String SIMULATED_FIELD_NAME = "text";
+
+        private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
+                SIMULATED_FIELD_NAME, String.class) };
+
+        public int anInstanceVar = 5;
+
+        public SerialPersistentFields() {
+            super();
+        }
+
+        private void readObject(java.io.ObjectInputStream in)
+                throws java.io.IOException, ClassNotFoundException {
+            ObjectInputStream.GetField fields = in.readFields();
+            anInstanceVar = Integer.parseInt((String) fields.get(
+                    SIMULATED_FIELD_NAME, "-5"));
+        }
+
+        private void writeObject(java.io.ObjectOutputStream out)
+                throws java.io.IOException, ClassNotFoundException {
+            ObjectOutputStream.PutField fields = out.putFields();
+            fields.put(SIMULATED_FIELD_NAME, Integer.toString(anInstanceVar));
+            out.writeFields();
+        }
+    }
+
+    private static class WriteFieldsWithoutFetchingPutFields implements
+            java.io.Serializable {
+        private static final String SIMULATED_FIELD_NAME = "text";
+
+        private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
+                SIMULATED_FIELD_NAME, String.class) };
+
+        public int anInstanceVar = 5;
+
+        public WriteFieldsWithoutFetchingPutFields() {
+            super();
+        }
+
+        private void readObject(java.io.ObjectInputStream in)
+                throws java.io.IOException, ClassNotFoundException {
+            in.readFields();
+        }
+
+        private void writeObject(java.io.ObjectOutputStream out)
+                throws java.io.IOException, ClassNotFoundException {
+            out.writeFields();
+        }
+    }
+
+    private static class SerialPersistentFieldsWithoutField implements
+            java.io.Serializable {
+        public int anInstanceVar = 5;
+
+        public SerialPersistentFieldsWithoutField() {
+            super();
+        }
+
+        private void readObject(java.io.ObjectInputStream in)
+                throws java.io.IOException, ClassNotFoundException {
+            in.readFields();
+        }
+
+        private void writeObject(java.io.ObjectOutputStream out)
+                throws java.io.IOException, ClassNotFoundException {
+            out.putFields();
+            out.writeFields();
+        }
+    }
+
+    private static class NotSerializable {
+        private int foo;
+
+        public NotSerializable() {
+        }
+
+        protected Object writeReplace() throws ObjectStreamException {
+            return new Integer(42);
+        }
+    }
+
+    private static class WriteReplaceObject implements Serializable {
+        private Object replaceObject;
+
+        private static enum Color {
+            red, blue, green
+        }
+
+        ;
+
+        public WriteReplaceObject(Object o) {
+            replaceObject = o;
+        }
+
+        protected Object writeReplace() throws ObjectStreamException {
+            return replaceObject;
+        }
+    }
+
+    private static class ExternalizableWithReplace implements Externalizable {
+        private int foo;
+
+        public ExternalizableWithReplace() {
+        }
+
+        protected Object writeReplace() throws ObjectStreamException {
+            return new Integer(42);
+        }
+
+        public void writeExternal(ObjectOutput out) {
+        }
+
+        public void readExternal(ObjectInput in) {
+        }
+    }
+
+    private static class ObjectOutputStreamWithReplace extends
+            ObjectOutputStream {
+        public ObjectOutputStreamWithReplace(OutputStream out)
+                throws IOException {
+            super(out);
+            enableReplaceObject(true);
+        }
+
+        protected Object replaceObject(Object obj) throws IOException {
+            if (obj instanceof NotSerializable) {
+                return new Long(10);
+            }
+            if (obj instanceof Integer) {
+                return new Long(((Integer) obj).longValue());
+            }
+            return super.replaceObject(obj);
+        }
+    }
+
+    private static class ObjectOutputStreamWithReplace2 extends
+            ObjectOutputStream {
+        public ObjectOutputStreamWithReplace2(OutputStream out)
+                throws IOException {
+            super(out);
+            enableReplaceObject(true);
+        }
+
+        protected Object replaceObject(Object obj) throws IOException {
+            return new Long(10);
+        }
+    }
+
+    private static class ObjectOutputStreamWriteOverride extends
+            ObjectOutputStream {
+        String test = "test";
+
+        protected ObjectOutputStreamWriteOverride() throws IOException,
+                SecurityException {
+            super();
+        }
+
+        @Override
+        protected void writeObjectOverride(Object object) throws IOException {
+            test = null;
+            super.writeObjectOverride(object);
+        }
+    }
+
+    protected static final String MODE_XLOAD = "xload";
+
+    protected static final String MODE_XDUMP = "xdump";
+
+    static final String FOO = "foo";
+
+    static final String MSG_WITE_FAILED = "Failed to write: ";
+
+    private static final boolean DEBUG = false;
+
+    protected static boolean xload = false;
+
+    protected static boolean xdump = false;
+
+    protected static String xFileName = null;
+
+    protected ObjectInputStream ois;
+
+    protected ObjectOutputStream oos;
+
+    protected ByteArrayOutputStream bao;
+
+    static final int INIT_INT_VALUE = 7;
+
+    static final String INIT_STR_VALUE = "a string that is blortz";
+
+    /**
+     * java.io.ObjectOutputStream#ObjectOutputStream(java.io.OutputStream)
+     */
+    public void test_ConstructorLjava_io_OutputStream() throws IOException {
+        // Test for method java.io.ObjectOutputStream(java.io.OutputStream)
+        oos.close();
+        oos = new ObjectOutputStream(new ByteArrayOutputStream());
+        oos.close();
+    }
+
+    /**
+     * java.io.ObjectOutputStream#close()
+     */
+    public void test_close() {
+        // Test for method void java.io.ObjectOutputStream.close()
+    }
+
+    /**
+     * java.io.ObjectOutputStream#defaultWriteObject()
+     */
+    public void test_defaultWriteObject() throws IOException {
+        // Test for method void java.io.ObjectOutputStream.defaultWriteObject()
+        try {
+            oos.defaultWriteObject();
+            fail("Failed to throw NotActiveException");
+        } catch (NotActiveException e) {
+            // Correct
+        }
+    }
+
+    /**
+     * java.io.ObjectOutputStream#flush()
+     */
+    public void test_flush() throws Exception {
+        // Test for method void java.io.ObjectOutputStream.flush()
+        int size = bao.size();
+        oos.writeByte(127);
+        assertTrue("Data flushed already", bao.size() == size);
+        oos.flush();
+        assertTrue("Failed to flush data", bao.size() > size);
+        // we don't know how many bytes are actually written for 1
+        // byte, so we test > <before>
+        oos.close();
+        oos = null;
+    }
+
+    /**
+     * java.io.ObjectOutputStream#putFields()
+     */
+    public void test_putFields() throws Exception {
+        // Test for method java.io.ObjectOutputStream$PutField
+        // java.io.ObjectOutputStream.putFields()
+
+        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());
+    }
+
+    /**
+     * java.io.ObjectOutputStream#reset()
+     */
+    public void test_reset() throws Exception {
+        // Test for method void java.io.ObjectOutputStream.reset()
+        String o = "HelloWorld";
+        oos.writeObject(o);
+        oos.writeObject(o);
+        oos.reset();
+        oos.writeObject(o);
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        ois.close();
+    }
+
+    private static class ExternalTest implements Externalizable {
+        public String value;
+
+        public ExternalTest() {
+        }
+
+        public void setValue(String val) {
+            value = val;
+        }
+
+        public String getValue() {
+            return value;
+        }
+
+        public void writeExternal(ObjectOutput output) {
+            try {
+                output.writeUTF(value);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+
+        public void readExternal(ObjectInput input) {
+            try {
+                value = input.readUTF();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * java.io.ObjectOutputStream#useProtocolVersion(int)
+     */
+    public void test_useProtocolVersionI() throws Exception {
+        // Test for method void
+        // java.io.ObjectOutputStream.useProtocolVersion(int)
+        oos.useProtocolVersion(ObjectOutputStream.PROTOCOL_VERSION_1);
+        ExternalTest t1 = new ExternalTest();
+        t1.setValue("hello1");
+        oos.writeObject(t1);
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        ExternalTest t2 = (ExternalTest) ois.readObject();
+        ois.close();
+        assertTrue(
+                "Cannot read/write PROTOCAL_VERSION_1 Externalizable objects: "
+                        + t2.getValue(), t1.getValue().equals(t2.getValue()));
+
+        // Cannot set protocol version when stream in-flight
+        ObjectOutputStream out = new ObjectOutputStream(
+                new ByteArrayOutputStream());
+        out.writeObject("hello world");
+        try {
+            out.useProtocolVersion(ObjectStreamConstants.PROTOCOL_VERSION_1);
+            fail("Expected IllegalStateException");
+        } catch (IllegalStateException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.io.ObjectOutputStream#write(byte[])
+     */
+    public void test_write$B() throws Exception {
+        // Test for method void java.io.ObjectOutputStream.write(byte [])
+        byte[] buf = new byte[10];
+        oos.write("HelloWorld".getBytes());
+        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));
+    }
+
+    /**
+     * java.io.ObjectOutputStream#write(byte[], int, int)
+     */
+    public void test_write$BII() throws Exception {
+        // Test for method void java.io.ObjectOutputStream.write(byte [], int,
+        // int)
+        byte[] buf = new byte[10];
+        oos.write("HelloWorld".getBytes(), 0, 10);
+        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));
+    }
+
+    /**
+     * java.io.ObjectOutputStream#write(int)
+     */
+    public void test_writeI() throws Exception {
+        // Test for method void java.io.ObjectOutputStream.write(int)
+        oos.write('T');
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertEquals("Read incorrect byte", 'T', ois.read());
+        ois.close();
+    }
+
+    /**
+     * java.io.ObjectOutputStream#writeBoolean(boolean)
+     */
+    public void test_writeBooleanZ() throws Exception {
+        // Test for method void java.io.ObjectOutputStream.writeBoolean(boolean)
+        oos.writeBoolean(true);
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertTrue("Wrote incorrect byte value", ois.readBoolean());
+    }
+
+    /**
+     * java.io.ObjectOutputStream#writeByte(int)
+     */
+    public void test_writeByteI() throws Exception {
+        // Test for method void java.io.ObjectOutputStream.writeByte(int)
+        oos.writeByte(127);
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertEquals("Wrote incorrect byte value", 127, ois.readByte());
+    }
+
+    /**
+     * java.io.ObjectOutputStream#writeBytes(java.lang.String)
+     */
+    public void test_writeBytesLjava_lang_String() throws Exception {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeBytes(java.lang.String)
+        byte[] buf = new byte[10];
+        oos.writeBytes("HelloWorld");
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        ois.readFully(buf);
+        ois.close();
+        assertEquals("Wrote incorrect bytes value", "HelloWorld", new String(
+                buf, 0, 10, "UTF-8"));
+    }
+
+    /**
+     * java.io.ObjectOutputStream#writeChar(int)
+     */
+    public void test_writeCharI() throws Exception {
+        // Test for method void java.io.ObjectOutputStream.writeChar(int)
+        oos.writeChar('T');
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertEquals("Wrote incorrect char value", 'T', ois.readChar());
+    }
+
+    /**
+     * java.io.ObjectOutputStream#writeChars(java.lang.String)
+     */
+    public void test_writeCharsLjava_lang_String() throws Exception {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeChars(java.lang.String)
+        int avail = 0;
+        char[] buf = new char[10];
+        oos.writeChars("HelloWorld");
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        // Number of prim data bytes in stream / 2 to give char index
+        avail = ois.available() / 2;
+        for (int i = 0; i < avail; ++i)
+            buf[i] = ois.readChar();
+        ois.close();
+        assertEquals("Wrote incorrect chars", "HelloWorld", new String(buf, 0,
+                10));
+    }
+
+    /**
+     * java.io.ObjectOutputStream#writeDouble(double)
+     */
+    public void test_writeDoubleD() throws Exception {
+        // Test for method void java.io.ObjectOutputStream.writeDouble(double)
+        oos.writeDouble(Double.MAX_VALUE);
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertTrue("Wrote incorrect double value",
+                ois.readDouble() == Double.MAX_VALUE);
+    }
+
+    /**
+     * java.io.ObjectOutputStream#writeFields()
+     */
+    public void test_writeFields() {
+        // Test for method void java.io.ObjectOutputStream.writeFields()
+        assertTrue("Used to test", true);
+    }
+
+    /**
+     * java.io.ObjectOutputStream#writeFloat(float)
+     */
+    public void test_writeFloatF() throws Exception {
+        // Test for method void java.io.ObjectOutputStream.writeFloat(float)
+        oos.writeFloat(Float.MAX_VALUE);
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertTrue("Wrote incorrect double value",
+                ois.readFloat() == Float.MAX_VALUE);
+        ois.close();
+        ois = null;
+    }
+
+    /**
+     * java.io.ObjectOutputStream#writeInt(int)
+     */
+    public void test_writeIntI() throws Exception {
+        // Test for method void java.io.ObjectOutputStream.writeInt(int)
+        oos.writeInt(Integer.MAX_VALUE);
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertTrue("Wrote incorrect double value",
+                ois.readInt() == Integer.MAX_VALUE);
+        ois.close();
+    }
+
+    /**
+     * java.io.ObjectOutputStream#writeLong(long)
+     */
+    public void test_writeLongJ() throws Exception {
+        // Test for method void java.io.ObjectOutputStream.writeLong(long)
+        oos.writeLong(Long.MAX_VALUE);
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertTrue("Wrote incorrect double value",
+                ois.readLong() == Long.MAX_VALUE);
+    }
+
+    /**
+     * java.io.ObjectOutputStream#writeObject(java.lang.Object)
+     */
+    public void test_writeObjectLjava_lang_Object() throws Exception {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        SerialPersistentFieldsWithoutField spf = new SerialPersistentFieldsWithoutField();
+        final int CONST = -500;
+        spf.anInstanceVar = CONST;
+        objToSave = spf;
+        if (DEBUG)
+            System.out.println("Obj = " + objToSave);
+        objLoaded = dumpAndReload(objToSave);
+        assertTrue(
+                "serialPersistentFields do not work properly in this implementation",
+                ((SerialPersistentFieldsWithoutField) objLoaded).anInstanceVar != CONST);
+
+    }
+
+    /**
+     * java.io.ObjectOutputStream#writeObject(java.lang.Object)
+     */
+    public void test_writeObject_NotSerializable() throws Exception {
+        ObjectOutput out = null;
+        try {
+            out = new ObjectOutputStream(new ByteArrayOutputStream());
+            out.writeObject(new NotSerializable());
+            fail("Expected NotSerializableException");
+        } catch (NotSerializableException e) {
+        }
+        out.writeObject(new ExternalizableWithReplace());
+    }
+
+    /**
+     * {@link java.io.ObjectOutputStream#writeObjectOverride(Object)}
+     */
+    public void test_writeObject_WriteOverride() throws Exception {
+        ObjectOutputStreamWriteOverride mockOut = new ObjectOutputStreamWriteOverride();
+        mockOut.writeObject(new Object());
+        assertNull(mockOut.test);
+    }
+
+    /**
+     * java.io.ObjectOutputStream#writeShort(int)
+     */
+    public void test_writeShortI() throws Exception {
+        // Test for method void java.io.ObjectOutputStream.writeShort(int)
+        oos.writeShort(127);
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertEquals("Wrote incorrect short value", 127, ois.readShort());
+    }
+
+    /**
+     * java.io.ObjectOutputStream#writeUTF(java.lang.String)
+     */
+    public void test_writeUTFLjava_lang_String() throws Exception {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeUTF(java.lang.String)
+        oos.writeUTF("HelloWorld");
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertEquals("Wrote incorrect UTF value", "HelloWorld", ois.readUTF());
+    }
+
+    /**
+     * java.io.ObjectOutputStream#writeObject(java.lang.Object)
+     */
+    public void test_writeObject_Exception() throws ClassNotFoundException,
+            IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+
+        try {
+            oos.writeObject(new Object());
+            fail("should throw ObjectStreamException");
+        } catch (ObjectStreamException e) {
+            // expected
+        } finally {
+            oos.close();
+            baos.close();
+        }
+
+        byte[] bytes = baos.toByteArray();
+        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
+                bytes));
+        try {
+            ois.readObject();
+            fail("should throw WriteAbortedException");
+        } catch (WriteAbortedException e) {
+            // expected
+        } finally {
+            ois.close();
+        }
+    }
+
+    /**
+     * {@link java.io.ObjectOutputStream#annotateProxyClass(java.lang.Class<T>)}
+     */
+    public void test_annotateProxyClass() throws SecurityException, IOException {
+        MockObjectOutputStream mockObjectOutputStream = new MockObjectOutputStream();
+        mockObjectOutputStream.annotateProxyClass(this.getClass());
+        assertEquals("The default implementation is doing nothing.",
+                mockObjectOutputStream, mockObjectOutputStream);
+
+    }
+
+    class MockObjectOutputStream extends ObjectOutputStream {
+
+        protected MockObjectOutputStream() throws IOException,
+                SecurityException {
+            super();
+        }
+
+        @Override
+        public void annotateProxyClass(Class<?> aClass) throws IOException {
+            super.annotateProxyClass(aClass);
+        }
+
+    }
+
+    /**
+     * 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();
+        oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        if (oos != null) {
+            try {
+                oos.close();
+            } catch (Exception e) {
+            }
+        }
+        if (f != null && f.exists()) {
+            if (!f.delete()) {
+                fail("Error cleaning up files during teardown");
+            }
+        }
+    }
+
+    protected Object reload() throws IOException, ClassNotFoundException {
+
+        // Choose the load stream
+        if (xload || xdump) {
+            // Load from pre-existing file
+            ois = new ObjectInputStream(new FileInputStream(xFileName + "-"
+                    + getName() + ".ser"));
+        } else {
+            // Just load from memory, we dumped to memory
+            ois = new ObjectInputStream(new ByteArrayInputStream(bao
+                    .toByteArray()));
+        }
+
+        try {
+            return ois.readObject();
+        } finally {
+            ois.close();
+        }
+    }
+
+    protected void dump(Object o) throws IOException, ClassNotFoundException {
+
+        // Choose the dump stream
+        if (xdump) {
+            oos = new ObjectOutputStream(new FileOutputStream(
+                    f = new java.io.File(xFileName + "-" + getName() + ".ser")));
+        } else {
+            oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
+        }
+
+        // Dump the object
+        try {
+            oos.writeObject(o);
+        } finally {
+            oos.close();
+        }
+    }
+
+    /**
+     * java.io.ObjectOutputStream#writeInt(int)
+     * java.io.ObjectOutputStream#writeObject(java.lang.Object)
+     * java.io.ObjectOutputStream#writeUTF(java.lang.String)
+     */
+
+    public void testMixPrimitivesAndObjects() throws Exception {
+        int i = 7;
+        String s1 = "string 1";
+        String s2 = "string 2";
+        byte[] bytes = { 1, 2, 3 };
+        try {
+            oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
+            oos.writeInt(i);
+            oos.writeObject(s1);
+            oos.writeUTF(s2);
+            oos.writeObject(bytes);
+            oos.close();
+
+            ois = new ObjectInputStream(new ByteArrayInputStream(bao
+                    .toByteArray()));
+
+            int j = ois.readInt();
+            assertTrue("Wrong int :" + j, i == j);
+
+            String l1 = (String) ois.readObject();
+            assertTrue("Wrong obj String :" + l1, s1.equals(l1));
+
+            String l2 = ois.readUTF();
+            assertTrue("Wrong UTF String :" + l2, s2.equals(l2));
+
+            byte[] bytes2 = (byte[]) ois.readObject();
+            assertTrue("Wrong byte[]", Arrays.equals(bytes, bytes2));
+        } finally {
+            try {
+                if (oos != null)
+                    oos.close();
+                if (ois != null)
+                    ois.close();
+            } catch (IOException e) {
+            }
+        }
+    }
+
+    /**
+     * java.io.ObjectOutputStream#writeUnshared(java.lang.Object)
+     */
+    public void test_writeUnshared() throws Exception {
+        // Regression for HARMONY-187
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+
+        Object o = "foobar";
+        oos.writeObject(o);
+        oos.writeUnshared(o);
+        oos.writeObject(o);
+        oos.flush();
+
+        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
+                baos.toByteArray()));
+
+        Object[] oa = new Object[3];
+        for (int i = 0; i < oa.length; i++) {
+            oa[i] = ois.readObject();
+        }
+
+        oos.close();
+        ois.close();
+
+        // All three conditions must be met
+        assertNotSame("oa[0] != oa[1]", oa[0], oa[1]);
+        assertNotSame("oa[1] != oa[2]", oa[1], oa[2]);
+        assertSame("oa[0] == oa[2]", oa[0], oa[2]);
+    }
+
+    /**
+     * java.io.ObjectOutputStream#writeUnshared(java.lang.Object)
+     */
+    public void test_writeUnshared2() throws Exception {
+        // Regression for HARMONY-187
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+
+        Object o = new Object[1];
+        oos.writeObject(o);
+        oos.writeUnshared(o);
+        oos.writeObject(o);
+        oos.flush();
+
+        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
+                baos.toByteArray()));
+
+        Object[] oa = new Object[3];
+        for (int i = 0; i < oa.length; i++) {
+            oa[i] = ois.readObject();
+        }
+
+        oos.close();
+        ois.close();
+
+        // All three conditions must be met
+        assertNotSame("oa[0] != oa[1]", oa[0], oa[1]);
+        assertNotSame("oa[1] != oa[2]", oa[1], oa[2]);
+        assertSame("oa[0] == oa[2]", oa[0], oa[2]);
+    }
+
+    protected Object dumpAndReload(Object o) throws IOException,
+            ClassNotFoundException {
+        dump(o);
+        return reload();
+    }
+
+    /**
+     * java.io.ObjectOutputStream#useProtocolVersion(int)
+     */
+    public void test_useProtocolVersionI_2() throws Exception {
+        ObjectOutputStream oos = new ObjectOutputStream(
+                new ByteArrayOutputStream());
+
+        oos.useProtocolVersion(ObjectOutputStream.PROTOCOL_VERSION_1);
+        oos.useProtocolVersion(ObjectOutputStream.PROTOCOL_VERSION_2);
+        try {
+            oos.useProtocolVersion(3);
+            fail("Protocol 3 should not be accepted");
+        } catch (IllegalArgumentException e) {
+            // expected
+        } finally {
+            oos.close();
+        }
+    }
+
+    /**
+     * java.io.ObjectOutputStream#replaceObject(java.lang.Object)
+     */
+    public void test_replaceObject() throws Exception {
+        // Regression for HARMONY-1429
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStreamWithReplace oos = new ObjectOutputStreamWithReplace(
+                baos);
+
+        oos.writeObject(new NotSerializable());
+        oos.flush();
+        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
+                baos.toByteArray()));
+        Object obj = ois.readObject();
+        oos.close();
+        ois.close();
+        assertTrue("replaceObject has not been called", (obj instanceof Long));
+
+        // Regression for HARMONY-2239
+        Object replaceObject = int.class;
+        baos = new ByteArrayOutputStream();
+        ObjectOutputStreamWithReplace2 oos2 = new ObjectOutputStreamWithReplace2(
+                baos);
+        oos2.writeObject(new WriteReplaceObject(replaceObject));
+        oos2.flush();
+        ois = new ObjectInputStream(
+                new ByteArrayInputStream(baos.toByteArray()));
+        obj = ois.readObject();
+        oos.close();
+        ois.close();
+        assertTrue("replaceObject has not been called", (obj instanceof Long));
+
+        replaceObject = ObjectStreamClass.lookup(Integer.class);
+        baos = new ByteArrayOutputStream();
+        oos2 = new ObjectOutputStreamWithReplace2(baos);
+        oos2.writeObject(new WriteReplaceObject(replaceObject));
+        oos2.flush();
+        ois = new ObjectInputStream(
+                new ByteArrayInputStream(baos.toByteArray()));
+        obj = ois.readObject();
+        oos.close();
+        ois.close();
+        assertTrue("replaceObject has not been called", (obj instanceof Long));
+
+        replaceObject = WriteReplaceObject.Color.red;
+        baos = new ByteArrayOutputStream();
+        oos2 = new ObjectOutputStreamWithReplace2(baos);
+        oos2.writeObject(new WriteReplaceObject(replaceObject));
+        oos2.flush();
+        ois = new ObjectInputStream(
+                new ByteArrayInputStream(baos.toByteArray()));
+        obj = ois.readObject();
+        oos.close();
+        ois.close();
+        assertTrue("replaceObject has not been called", (obj instanceof Long));
+
+        // Regression for HARMONY-3158
+        Object obj1;
+        Object obj2;
+        Object obj3;
+
+        baos = new ByteArrayOutputStream();
+        oos = new ObjectOutputStreamWithReplace(baos);
+
+        oos.writeObject(new Integer(99));
+        oos.writeObject(Integer.class);
+        oos.writeObject(ObjectStreamClass.lookup(Integer.class));
+        oos.flush();
+
+        ois = new ObjectInputStream(
+                new ByteArrayInputStream(baos.toByteArray()));
+        obj1 = ois.readObject();
+        obj2 = ois.readObject();
+        obj3 = ois.readObject();
+        oos.close();
+        ois.close();
+
+        assertTrue("1st replaceObject worked incorrectly", obj1 instanceof Long);
+        assertEquals("1st replaceObject worked incorrectly", 99, ((Long) obj1)
+                .longValue());
+        assertEquals("2nd replaceObject worked incorrectly", Integer.class,
+                obj2);
+        assertEquals("3rd replaceObject worked incorrectly",
+                ObjectStreamClass.class, obj3.getClass());
+    }
+
+    public void test_putFieldWrite() throws Exception {
+        // Regression test for HARMONY-6483
+        ObjectOutputStream oos = new ObjectOutputStream(new ByteArrayOutputStream());
+        try {
+            oos.writeObject(new OutputObject());
+            fail("Should throw an IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // Expected
+        }
+    }
+
+    private static class OutputObject implements Serializable {
+        private void writeObject(ObjectOutputStream oos) throws IOException {
+            ObjectOutputStream oos2 = new ObjectOutputStream(new ByteArrayOutputStream());
+            ObjectOutputStream.PutField putField = oos.putFields();
+            putField.write(oos2);
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/ObjectStreamClassTest.java b/luni/src/test/java/tests/api/java/io/ObjectStreamClassTest.java
new file mode 100644
index 0000000..838b413
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/ObjectStreamClassTest.java
@@ -0,0 +1,256 @@
+/*
+ *  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.io;
+
+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;
+
+import junit.framework.TestCase;
+
+public class ObjectStreamClassTest extends TestCase {
+
+    static class DummyClass implements Serializable {
+        private static final long serialVersionUID = 999999999999999L;
+
+        long bam = 999L;
+
+        int ham = 9999;
+
+        public static long getUID() {
+            return serialVersionUID;
+        }
+    }
+
+    /**
+     * java.io.ObjectStreamClass#forClass()
+     */
+    public void test_forClass() {
+        // Need to test during serialization to be sure an instance is
+        // returned
+        ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
+        assertEquals("forClass returned an object: " + osc.forClass(),
+                DummyClass.class, osc.forClass());
+    }
+
+    /**
+     * java.io.ObjectStreamClass#getField(java.lang.String)
+     */
+    public void test_getFieldLjava_lang_String() {
+        ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
+        assertEquals("getField did not return correct field", 'J', osc
+                .getField("bam").getTypeCode());
+        assertNull("getField did not null for non-existent field", osc
+                .getField("wham"));
+    }
+
+    /**
+     * java.io.ObjectStreamClass#getFields()
+     */
+    public void test_getFields() {
+        ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
+        ObjectStreamField[] osfArray = osc.getFields();
+        assertTrue(
+                "Array of fields should be of length 2 but is instead of length: "
+                        + osfArray.length, osfArray.length == 2);
+    }
+
+    /**
+     * java.io.ObjectStreamClass#getName()
+     */
+    public void test_getName() {
+        ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
+        assertEquals(
+                "getName returned incorrect name: " + osc.getName(),
+                "org.apache.harmony.luni.tests.java.io.ObjectStreamClassTest$DummyClass",
+                osc.getName());
+    }
+
+    /**
+     * java.io.ObjectStreamClass#getSerialVersionUID()
+     */
+    public void test_getSerialVersionUID() {
+        ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
+        assertTrue("getSerialversionUID returned incorrect uid: "
+                + osc.getSerialVersionUID() + " instead of "
+                + DummyClass.getUID(), osc.getSerialVersionUID() == DummyClass
+                .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();
+        }
+    }
+
+    public void test_getSerialVersionUID_inner_private_class() {
+        ObjectStreamClass osc1 = ObjectStreamClass.lookup(SyntheticTest.class);
+        assertEquals(-4332969662791850406L, osc1.getSerialVersionUID());
+
+        ObjectStreamClass osc2 = ObjectStreamClass.lookup(SyntheticTest.X.class);
+        assertEquals(-3926212872029449440L, osc2.getSerialVersionUID());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * java.io.ObjectStreamClass#lookup(java.lang.Class)
+     */
+    public void test_lookupLjava_lang_Class() {
+        ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
+        assertEquals(
+                "lookup returned wrong class: " + osc.getName(),
+                "org.apache.harmony.luni.tests.java.io.ObjectStreamClassTest$DummyClass",
+                osc.getName());
+    }
+
+    /**
+     * java.io.ObjectStreamClass#toString()
+     */
+    public void test_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);
+    }
+
+    public void testSerialization() {
+        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;
+        }
+    }
+
+    /**
+     * @since 1.6
+     */
+    static class ExternalizableClass implements Externalizable {
+
+        private static final long serialVersionUID = -4285635779249689129L;
+
+        public void readExternal(ObjectInput input) throws IOException, ClassNotFoundException {
+            throw new ClassNotFoundException();
+        }
+
+        public void writeExternal(ObjectOutput output) throws IOException {
+            throw new IOException();
+        }
+
+    }
+
+    /**
+     * 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(),
+                "org.apache.harmony.luni.tests.java.io.ObjectStreamClassTest$DummyClass", osc
+                .getName());
+
+        osc = ObjectStreamClass.lookupAny(NonSerialzableClass.class);
+        assertEquals("lookup returned wrong class: " + osc.getName(),
+                "org.apache.harmony.luni.tests.java.io.ObjectStreamClassTest$NonSerialzableClass",
+                osc.getName());
+
+        osc = ObjectStreamClass.lookupAny(ExternalizableClass.class);
+        assertEquals("lookup returned wrong class: " + osc.getName(),
+                "org.apache.harmony.luni.tests.java.io.ObjectStreamClassTest$ExternalizableClass",
+                osc.getName());
+
+        osc = ObjectStreamClass.lookup(NonSerialzableClass.class);
+        assertNull(osc);
+
+    }
+
+
+}
diff --git a/luni/src/test/java/tests/api/java/io/ObjectStreamConstantsTest.java b/luni/src/test/java/tests/api/java/io/ObjectStreamConstantsTest.java
new file mode 100644
index 0000000..5fd09f6
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/ObjectStreamConstantsTest.java
@@ -0,0 +1,45 @@
+/* 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.io;
+
+import java.io.ObjectStreamConstants;
+
+import junit.framework.TestCase;
+
+public class ObjectStreamConstantsTest extends TestCase {
+
+    /**
+     * java.io.ObjectStreamConstants#TC_ENUM
+     */
+    public void test_TC_ENUM() {
+        assertEquals(126, ObjectStreamConstants.TC_ENUM);
+    }
+
+    /**
+     * java.io.ObjectStreamConstants#SC_ENUM
+     */
+    public void test_SC_ENUM() {
+        assertEquals(16, ObjectStreamConstants.SC_ENUM);
+    }
+
+    /**
+     * java.io.ObjectStreamConstants#TC_MAX
+     */
+    public void test_TC_MAX() {
+        assertEquals(126, ObjectStreamConstants.TC_MAX);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/ObjectStreamFieldTest.java b/luni/src/test/java/tests/api/java/io/ObjectStreamFieldTest.java
new file mode 100644
index 0000000..2b225b4
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/ObjectStreamFieldTest.java
@@ -0,0 +1,395 @@
+/*
+ *  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.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.NotActiveException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.ObjectStreamField;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.io.StreamCorruptedException;
+import java.util.Date;
+
+public class ObjectStreamFieldTest extends junit.framework.TestCase {
+
+    static class DummyClass implements Serializable {
+        private static final long serialVersionUID = 999999999999998L;
+
+        long bam = 999L;
+
+        int ham = 9999;
+
+        int sam = 8888;
+
+        Object hola = new Object();
+
+        public static long getUID() {
+            return serialVersionUID;
+        }
+    }
+
+    ObjectStreamClass osc;
+
+    ObjectStreamField hamField;
+
+    ObjectStreamField samField;
+
+    ObjectStreamField bamField;
+
+    ObjectStreamField holaField;
+
+    /**
+     * java.io.ObjectStreamField#ObjectStreamField(java.lang.String,
+     *java.lang.Class)
+     */
+    public void test_ConstructorLjava_lang_StringLjava_lang_Class() {
+        assertTrue("Used to test", true);
+    }
+
+    public void test_equalsLjava_lang_Object() {
+        // Regression test for HARMONY-4273
+        assertTrue(samField.equals(samField));
+        assertFalse(samField.equals(hamField));
+        assertFalse(samField.equals("fish"));
+        assertFalse(samField.equals(null));
+    }
+
+    /**
+     * java.io.ObjectStreamField#compareTo(java.lang.Object)
+     */
+    public void test_compareToLjava_lang_Object() {
+        assertTrue("Object compared to int did not return > 0", holaField
+                .compareTo(hamField) > 0);
+        assertEquals("Int compared to itself did not return 0", 0, hamField
+                .compareTo(hamField));
+        assertTrue("(Int)ham compared to (Int)sam did not return < 0", hamField
+                .compareTo(samField) < 0);
+    }
+
+    /**
+     * java.io.ObjectStreamField#getName()
+     */
+    public void test_getName() {
+        assertEquals("Field did not return correct name", "hola", holaField
+                .getName());
+    }
+
+    /**
+     * java.io.ObjectStreamField#getOffset()
+     */
+    public void test_getOffset() {
+        ObjectStreamField[] osfArray;
+        osfArray = osc.getFields();
+        assertTrue("getOffset did not return reasonable values", osfArray[0]
+                .getOffset() != osfArray[1].getOffset());
+        assertEquals("getOffset for osfArray[0].getOffset() did not return 0",
+                0, osfArray[0].getOffset());
+        assertEquals("osfArray[1].getOffset() did not return	8", 8, osfArray[1]
+                .getOffset());
+        assertEquals("osfArray[2].getOffset() did not return 12", 12,
+                osfArray[2].getOffset());
+    }
+
+    /**
+     * java.io.ObjectStreamField#getType()
+     */
+    public void test_getType() {
+        assertTrue("getType on an Object field did not answer Object",
+                holaField.getType().equals(Object.class));
+    }
+
+    /**
+     * java.io.ObjectStreamField#getTypeCode()
+     */
+    public void test_getTypeCode() {
+        assertEquals("getTypeCode on an Object field did not answer 'L'", 'L',
+                holaField.getTypeCode());
+        assertEquals("getTypeCode on a long field did not answer 'J'", 'J',
+                bamField.getTypeCode());
+    }
+
+    /**
+     * java.io.ObjectStreamField#getTypeString()
+     */
+    public void test_getTypeString() {
+        assertTrue("getTypeString returned: " + holaField.getTypeString(),
+                holaField.getTypeString().indexOf("Object") >= 0);
+        assertNull("Primitive types' strings should be null", hamField
+                .getTypeString());
+
+        ObjectStreamField osf = new ObjectStreamField("s", String.class, true);
+        assertTrue(osf.getTypeString() == "Ljava/lang/String;");
+    }
+
+    /**
+     * java.io.ObjectStreamField#toString()
+     */
+    public void test_toString() {
+        assertTrue("toString on a long returned: " + bamField.toString(),
+                bamField.toString().indexOf("bam") >= 0);
+    }
+
+    /**
+     * java.io.ObjectStreamField#getType()
+     */
+    public void test_getType_Deserialized() throws IOException,
+            ClassNotFoundException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+        oos.writeObject(new SerializableObject());
+        oos.close();
+        baos.close();
+
+        byte[] bytes = baos.toByteArray();
+        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        ObjectInputStream ois = new ObjectInputStream(bais);
+        SerializableObject obj = (SerializableObject) ois.readObject();
+
+        ObjectStreamClass oc = obj.getObjectStreamClass();
+        ObjectStreamField field = oc.getField("i");
+        assertEquals(Object.class, field.getType());
+    }
+
+    /**
+     * java.io.ObjectStreamField#getType()
+     */
+    public void test_getType_MockObjectInputStream() throws IOException,
+            ClassNotFoundException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+        oos.writeObject(new SerializableObject());
+        oos.close();
+        baos.close();
+
+        byte[] bytes = baos.toByteArray();
+        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        MockObjectInputStream ois = new MockObjectInputStream(bais);
+        ois.readObject();
+
+        ObjectStreamClass oc = ois.getObjectStreamClass();
+        ObjectStreamField field = oc.getField("i");
+        assertEquals(Object.class, field.getType());
+    }
+
+    public void test_isUnshared() throws Exception {
+        SerializableObject2 obj = new SerializableObject2();
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+        oos.writeObject(obj);
+        oos.close();
+        baos.close();
+        byte[] bytes = baos.toByteArray();
+        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        ObjectInputStream ois = new ObjectInputStream(bais);
+        SerializableObject2 newObj = (SerializableObject2) ois.readObject();
+
+        ObjectInputStream.GetField getField = newObj.getGetField();
+        ObjectStreamClass objectStreamClass = getField.getObjectStreamClass();
+
+        assertTrue(objectStreamClass.getField("i").isUnshared());
+        assertFalse(objectStreamClass.getField("d").isUnshared());
+        assertTrue(objectStreamClass.getField("s").isUnshared());
+
+        assertEquals(1000, getField.get("i", null));
+        assertEquals(SerializableObject2.today, getField.get("d", null));
+        assertEquals("Richard", getField.get("s", null));
+
+        assertTrue(objectStreamClass.getField("s").getTypeString() == "Ljava/lang/String;");
+
+        assertEquals(0, objectStreamClass.getField("d").getOffset());
+        assertEquals(1, objectStreamClass.getField("i").getOffset());
+        assertEquals(2, objectStreamClass.getField("s").getOffset());
+    }
+
+
+    /**
+     * Write/serialize and read/de-serialize an object with primitive field
+     */
+    public void test_ObjectWithPrimitiveField()
+            throws IOException, ClassNotFoundException {
+
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        final MyObjectOutputStream oos = new MyObjectOutputStream(baos);
+        oos.writeObject(new MockClass());
+        final byte[] bytes = baos.toByteArray();
+        final ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        final MyObjectInputStream ois = new MyObjectInputStream(bais);
+        // NullPointerException is thrown by the readObject call below. 
+        ois.readObject();
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() {
+        osc = ObjectStreamClass.lookup(DummyClass.class);
+        bamField = osc.getField("bam");
+        samField = osc.getField("sam");
+        hamField = osc.getField("ham");
+        holaField = osc.getField("hola");
+    }
+}
+
+class SerializableObject implements Serializable {
+    public ObjectInputStream.GetField getField = null;
+
+    private static final long serialVersionUID = -2953957835918368056L;
+
+    public Date d;
+
+    public Integer i;
+
+    public Exception e;
+
+    public SerializableObject() {
+        d = new Date();
+        i = new Integer(1);
+        e = new Exception("e");
+    }
+
+    private void writeObject(ObjectOutputStream o) throws IOException {
+        o.putFields().put("d", new Date());
+        o.putFields().put("i", new Integer(11));
+        o.writeFields();
+    }
+
+    private void readObject(ObjectInputStream in) throws NotActiveException,
+            IOException, ClassNotFoundException {
+        getField = in.readFields();
+        d = (Date) getField.get("d", null);
+        i = (Integer) getField.get("i", null);
+    }
+
+    public ObjectStreamClass getObjectStreamClass() {
+        return getField.getObjectStreamClass();
+    }
+}
+
+class MockObjectInputStream extends ObjectInputStream {
+    private ObjectStreamClass temp = null;
+
+    public MockObjectInputStream() throws SecurityException, IOException {
+        super();
+    }
+
+    public MockObjectInputStream(InputStream in)
+            throws StreamCorruptedException, IOException {
+        super(in);
+    }
+
+    public ObjectStreamClass readClassDescriptor() throws IOException,
+            ClassNotFoundException {
+        ObjectStreamClass osc = super.readClassDescriptor();
+        // To get the ObjectStreamClass of SerializableObject
+        if (osc.getSerialVersionUID() == -2953957835918368056L) {
+            temp = osc;
+        }
+        return osc;
+    }
+
+    public ObjectStreamClass getObjectStreamClass() {
+        return temp;
+    }
+}
+
+class SerializableObject2 implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final ObjectStreamField[] serialPersistentFields = {
+            new ObjectStreamField("i", Integer.class, true),
+            new ObjectStreamField("d", Date.class, false),
+            new ObjectStreamField("s", String.class, true), };
+
+    private ObjectInputStream.GetField getField;
+
+    public static Date today = new Date(1172632429156l);
+
+    public ObjectInputStream.GetField getGetField() {
+        return getField;
+    }
+
+    private void writeObject(ObjectOutputStream o) throws IOException {
+        ObjectOutputStream.PutField putField = o.putFields();
+        putField.put("i", new Integer(1000));
+        putField.put("d", today);
+        putField.put("s", "Richard");
+        o.writeFields();
+    }
+
+    private void readObject(ObjectInputStream in) throws NotActiveException,
+            IOException, ClassNotFoundException {
+        getField = in.readFields();
+    }
+}
+
+
+// Primitive fields are necessary to cause the NullPointerException. 
+class MockClass implements Serializable {
+    String str1 = "string 1";
+    String str2 = "string 2";
+    int int1 = 1;
+    int int2 = 2;
+    String str3 = "string 3";
+}
+
+
+// Overrides writeClassDescriptor to store ObjectStreamClass in map. 
+class MyObjectOutputStream extends ObjectOutputStream {
+
+    // record the only ObjectStreamClass
+    static ObjectStreamClass descs;
+
+    MyObjectOutputStream(OutputStream out)
+            throws IOException {
+        super(out);
+    }
+
+    @Override
+    protected void writeClassDescriptor(ObjectStreamClass desc)
+            throws IOException {
+        descs = desc;
+        // Write a int
+        writeInt(1);
+    }
+}
+
+// Overrides readClassDescriptor to get ObjectStreamClass from map.
+class MyObjectInputStream extends ObjectInputStream {
+
+    MyObjectInputStream(InputStream in)
+            throws IOException {
+        super(in);
+    }
+
+    @Override
+    protected ObjectStreamClass readClassDescriptor()
+            throws IOException, ClassNotFoundException {
+        // Read a integer and get the only ObjectStreamClass for the test
+        final int id = readInt();
+        return MyObjectOutputStream.descs;
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/OpenRandomFileTest.java b/luni/src/test/java/tests/api/java/io/OpenRandomFileTest.java
new file mode 100644
index 0000000..cb7b312
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/OpenRandomFileTest.java
@@ -0,0 +1,58 @@
+/* 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.io;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+import junit.framework.TestCase;
+
+public class OpenRandomFileTest extends TestCase {
+
+    public static void main(String[] args) throws IOException {
+        new OpenRandomFileTest().testOpenEmptyFile();
+    }
+
+    public OpenRandomFileTest() {
+        super();
+    }
+
+    public void testOpenNonEmptyFile() throws IOException {
+        File file = File.createTempFile("test", "tmp");
+        assertTrue(file.exists());
+        file.deleteOnExit();
+        FileOutputStream fos = new FileOutputStream(file);
+        fos.write(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
+        fos.close();
+
+        String fileName = file.getCanonicalPath();
+        RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
+        raf.close();
+    }
+
+    public void testOpenEmptyFile() throws IOException {
+        File file = File.createTempFile("test", "tmp");
+        assertTrue(file.exists());
+        file.deleteOnExit();
+
+        String fileName = file.getCanonicalPath();
+        RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
+        raf.close();
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/OutputStreamTesterTest.java b/luni/src/test/java/tests/api/java/io/OutputStreamTesterTest.java
new file mode 100644
index 0000000..f9e1561
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/OutputStreamTesterTest.java
@@ -0,0 +1,205 @@
+/*
+ *  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.io;
+
+import junit.framework.TestSuite;
+import org.apache.harmony.testframework.SinkTester;
+import org.apache.harmony.testframework.WrapperTester;
+import tests.support.Streams;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.PrintStream;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+/**
+ * Tests basic {@link OutputStream} behaviors for the luni implementations of
+ * the type.
+ */
+public class OutputStreamTesterTest {
+
+    public static junit.framework.Test suite() {
+        TestSuite suite = new TestSuite();
+
+        // sink tests
+        suite.addTest(new FileOutputStreamSinkTester(true).createTests());
+        suite.addTest(new FileOutputStreamSinkTester(false).createTests());
+        suite.addTest(new ByteArrayOutputStreamSinkTester(0).setThrowsExceptions(false).createTests());
+        suite.addTest(new ByteArrayOutputStreamSinkTester(4).setThrowsExceptions(false).createTests());
+        suite.addTest(new PipedOutputStreamSinkTester().createTests());
+
+        // wrapper tests
+        suite.addTest(new BufferedOutputStreamTester(1).createTests());
+        suite.addTest(new BufferedOutputStreamTester(5).createTests());
+        suite.addTest(new BufferedOutputStreamTester(1024).createTests());
+        suite.addTest(new FilterOutputStreamTester().createTests());
+        suite.addTest(new DataOutputStreamTester().createTests());
+        // fails wrapperTestFlushThrowsViaClose() and sinkTestWriteAfterClose():
+        // suite.addTest(new ObjectOutputStreamTester().createTests());
+        suite.addTest(new PrintStreamTester().setThrowsExceptions(false).createTests());
+
+        return suite;
+    }
+
+    private static class FileOutputStreamSinkTester extends SinkTester {
+
+        private final boolean append;
+        private File file;
+
+        private FileOutputStreamSinkTester(boolean append) {
+            this.append = append;
+        }
+
+        public OutputStream create() throws IOException {
+            file = File.createTempFile("FileOutputStreamSinkTester", "tmp");
+            file.deleteOnExit();
+            return new FileOutputStream(file, append);
+        }
+
+        public byte[] getBytes() throws IOException {
+            return Streams.streamToBytes(new FileInputStream(file));
+        }
+    }
+
+    private static class ByteArrayOutputStreamSinkTester extends SinkTester {
+
+        private final int size;
+        private ByteArrayOutputStream stream;
+
+        private ByteArrayOutputStreamSinkTester(int size) {
+            this.size = size;
+        }
+
+        public OutputStream create() throws IOException {
+            stream = new ByteArrayOutputStream(size);
+            return stream;
+        }
+
+        public byte[] getBytes() throws IOException {
+            return stream.toByteArray();
+        }
+    }
+
+    private static class PipedOutputStreamSinkTester extends SinkTester {
+
+        private ExecutorService executor;
+        private Future<byte[]> future;
+
+        public OutputStream create() throws IOException {
+            final PipedInputStream in = new PipedInputStream();
+            PipedOutputStream out = new PipedOutputStream(in);
+
+            executor = Executors.newSingleThreadExecutor();
+            future = executor.submit(new Callable<byte[]>() {
+                final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+
+                public byte[] call() throws Exception {
+                    byte[] buffer = new byte[256];
+                    int count;
+                    while ((count = in.read(buffer)) != -1) {
+                        bytes.write(buffer, 0, count);
+                    }
+                    return bytes.toByteArray();
+                }
+            });
+
+            return out;
+        }
+
+        public byte[] getBytes() throws Exception {
+            executor.shutdown();
+            return future.get();
+        }
+    }
+
+    private static class FilterOutputStreamTester extends WrapperTester {
+
+        public OutputStream create(OutputStream delegate) throws Exception {
+            return new FilterOutputStream(delegate);
+        }
+
+        public byte[] decode(byte[] delegateBytes) throws Exception {
+            return delegateBytes;
+        }
+    }
+
+    private static class BufferedOutputStreamTester extends WrapperTester {
+        private final int bufferSize;
+
+        private BufferedOutputStreamTester(int bufferSize) {
+            this.bufferSize = bufferSize;
+        }
+
+        public OutputStream create(OutputStream delegate) throws Exception {
+            return new BufferedOutputStream(delegate, bufferSize);
+        }
+
+        public byte[] decode(byte[] delegateBytes) throws Exception {
+            return delegateBytes;
+        }
+    }
+
+    private static class DataOutputStreamTester extends WrapperTester {
+
+        public OutputStream create(OutputStream delegate) throws Exception {
+            return new DataOutputStream(delegate);
+        }
+
+        public byte[] decode(byte[] delegateBytes) throws Exception {
+            return delegateBytes;
+        }
+    }
+
+    private static class ObjectOutputStreamTester extends WrapperTester {
+
+        public OutputStream create(OutputStream delegate) throws Exception {
+            return new ObjectOutputStream(delegate);
+        }
+
+        public byte[] decode(byte[] delegateBytes) throws Exception {
+            return Streams.streamToBytes(new ObjectInputStream(
+                    new ByteArrayInputStream(delegateBytes)));
+        }
+    }
+
+    private static class PrintStreamTester extends WrapperTester {
+
+        public OutputStream create(OutputStream delegate) throws Exception {
+            return new PrintStream(delegate);
+        }
+
+        public byte[] decode(byte[] delegateBytes) throws Exception {
+            return delegateBytes;
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/OutputStreamWriterTest.java b/luni/src/test/java/tests/api/java/io/OutputStreamWriterTest.java
new file mode 100644
index 0000000..16244ec
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/OutputStreamWriterTest.java
@@ -0,0 +1,701 @@
+/*
+ *  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.io;
+
+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;
+
+public class OutputStreamWriterTest extends TestCase {
+
+    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);
+    }
+
+    /*
+     * @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();
+        } catch (NullPointerException exception) {
+        } catch (IndexOutOfBoundsException exception) {
+        }
+
+        // throws NullPointerException though count is negative
+        try {
+            writer.write((char[]) null, 1, -1);
+            fail();
+        } catch (NullPointerException exception) {
+        } catch (IndexOutOfBoundsException exception) {
+        }
+
+        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
+        }
+
+        try {
+            writer.write((String) null, -1, -1);
+            fail();
+        } catch (NullPointerException expected) {
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        // Throws NullPointerException before StringIndexOutOfBoundsException
+        try {
+            writer.write((String) null, -1, 0);
+            fail();
+        } catch (NullPointerException expected) {
+        } catch (IndexOutOfBoundsException 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();
+        } catch (NullPointerException expected) {
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        try {
+            writer.write((String) null, -1, 0);
+            fail();
+        } catch (NullPointerException expected) {
+        } catch (IndexOutOfBoundsException 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) {
+                }
+            }
+        }
+    }
+
+    /**
+     * java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
+     */
+    public void test_ConstructorLjava_io_OutputStream() {
+        assertTrue("Used in tests", true);
+    }
+
+    /**
+     * 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
+        }
+    }
+
+    /**
+     * 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);
+        }
+    }
+
+    /**
+     * 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));
+    }
+
+    /**
+     * 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
+        }
+        result = out.getEncoding();
+        assertEquals("UnicodeBigUnmarked", result);
+    }
+
+    /**
+     * 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));
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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/tests/api/java/io/PipedInputStreamTest.java b/luni/src/test/java/tests/api/java/io/PipedInputStreamTest.java
new file mode 100644
index 0000000..e787c67
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/PipedInputStreamTest.java
@@ -0,0 +1,470 @@
+/*
+ *  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.io;
+
+import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+
+public class PipedInputStreamTest extends junit.framework.TestCase {
+
+    static class PWriter implements Runnable {
+        PipedOutputStream pos;
+
+        public byte bytes[];
+
+        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);
+            }
+        }
+    }
+
+    Thread t;
+
+    PWriter pw;
+
+    PipedInputStream pis;
+
+    PipedOutputStream pos;
+
+    /**
+     * java.io.PipedInputStream#PipedInputStream()
+     */
+    public void test_Constructor() {
+        // Test for method java.io.PipedInputStream()
+        // Used in 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());
+        pis.available();
+    }
+
+
+    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();
+            while (true) {
+                pis.read();
+                t.interrupt();
+            }
+        } catch (IOException expected) {
+        } finally {
+            try {
+                pis.close();
+                pos.close();
+            } catch (IOException ee) {
+            }
+        }
+    }
+
+    /**
+     * java.io.PipedInputStream#available()
+     */
+    public void test_available() throws Exception {
+        pis = new PipedInputStream();
+        pos = new PipedOutputStream();
+
+        pis.connect(pos);
+        t = new Thread(pw = new PWriter(pos, 1000));
+        t.start();
+
+        synchronized (pw) {
+            pw.wait(10000);
+        }
+        assertTrue("Available returned incorrect number of bytes: "
+                + pis.available(), pis.available() == 1000);
+
+        PipedInputStream pin = new PipedInputStream();
+        PipedOutputStream pout = new PipedOutputStream(pin);
+        // We know the PipedInputStream buffer size is 1024.
+        // Writing another byte would cause the write to wait
+        // for a read before returning
+        for (int i = 0; i < 1024; i++) {
+            pout.write(i);
+        }
+        assertEquals("Incorrect available count", 1024, pin.available());
+    }
+
+    /**
+     * 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("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;
+        }
+    }
+
+    /**
+     * java.io.PipedInputStream#connect(java.io.PipedOutputStream)
+     */
+    public void test_connectLjava_io_PipedOutputStream() throws Exception {
+        pis = new PipedInputStream();
+        pos = new PipedOutputStream();
+        assertEquals("Non-conected pipe returned non-zero available bytes", 0,
+                pis.available());
+
+        pis.connect(pos);
+        t = new Thread(pw = new PWriter(pos, 1000));
+        t.start();
+
+        synchronized (pw) {
+            pw.wait(10000);
+        }
+        assertEquals("Available returned incorrect number of bytes", 1000, pis
+                .available());
+    }
+
+    /**
+     * java.io.PipedInputStream#read()
+     */
+    public void test_read() throws Exception {
+        pis = new PipedInputStream();
+        pos = new PipedOutputStream();
+
+        pis.connect(pos);
+        t = new Thread(pw = new PWriter(pos, 1000));
+        t.start();
+
+        synchronized (pw) {
+            pw.wait(10000);
+        }
+        assertEquals("Available returned incorrect number of bytes", 1000, pis
+                .available());
+        assertEquals("read returned incorrect byte", pw.bytes[0], (byte) pis
+                .read());
+    }
+
+    /**
+     * java.io.PipedInputStream#read(byte[], int, int)
+     */
+    public void test_read$BII() throws Exception {
+        pis = new PipedInputStream();
+        pos = new PipedOutputStream();
+
+        pis.connect(pos);
+        t = new Thread(pw = new PWriter(pos, 1000));
+        t.start();
+
+        byte[] buf = new byte[400];
+        synchronized (pw) {
+            pw.wait(10000);
+        }
+        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("read returned incorrect byte[]", pw.bytes[i], buf[i]);
+        }
+    }
+
+    /**
+     * java.io.PipedInputStream#read(byte[], int, int)
+     * Regression for HARMONY-387
+     */
+    public void test_read$BII_2() throws IOException {
+        PipedInputStream obj = new PipedInputStream();
+        try {
+            obj.read(new byte[0], 0, -1);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+    }
+
+    /**
+     * java.io.PipedInputStream#read(byte[], int, int)
+     */
+    public void test_read$BII_3() throws IOException {
+        PipedInputStream obj = new PipedInputStream();
+        try {
+            obj.read(new byte[0], -1, 0);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+    }
+
+    /**
+     * java.io.PipedInputStream#read(byte[], int, int)
+     */
+    public void test_read$BII_4() throws IOException {
+        PipedInputStream obj = new PipedInputStream();
+        try {
+            obj.read(new byte[0], -1, -1);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+    }
+
+    /**
+     * java.io.PipedInputStream#receive(int)
+     */
+    public void test_receive() throws IOException {
+        pis = new PipedInputStream();
+        pos = new PipedOutputStream();
+
+        // test if writer recognizes dead reader
+        pis.connect(pos);
+        class WriteRunnable implements Runnable {
+
+            boolean pass = false;
+
+            volatile boolean readerAlive = true;
+
+            public void run() {
+                try {
+                    pos.write(1);
+                    while (readerAlive) {
+                        ;
+                    }
+                    try {
+                        // should throw exception since reader thread
+                        // is now dead
+                        pos.write(1);
+                    } catch (IOException e) {
+                        pass = true;
+                    }
+                } catch (IOException e) {
+                }
+            }
+        }
+        WriteRunnable writeRunnable = new WriteRunnable();
+        Thread writeThread = new Thread(writeRunnable);
+        class ReadRunnable implements Runnable {
+
+            boolean pass;
+
+            public void run() {
+                try {
+                    pis.read();
+                    pass = true;
+                } catch (IOException e) {
+                }
+            }
+        }
+        ;
+        ReadRunnable readRunnable = new ReadRunnable();
+        Thread readThread = new Thread(readRunnable);
+        writeThread.start();
+        readThread.start();
+        while (readThread.isAlive()) {
+            ;
+        }
+        writeRunnable.readerAlive = false;
+        assertTrue("reader thread failed to read", readRunnable.pass);
+        while (writeThread.isAlive()) {
+            ;
+        }
+        assertTrue("writer thread failed to recognize dead reader",
+                writeRunnable.pass);
+
+        // attempt to write to stream after writer closed
+        pis = new PipedInputStream();
+        pos = new PipedOutputStream();
+
+        pis.connect(pos);
+        class MyRunnable implements Runnable {
+
+            boolean pass;
+
+            public void run() {
+                try {
+                    pos.write(1);
+                } catch (IOException e) {
+                    pass = true;
+                }
+            }
+        }
+        MyRunnable myRun = new MyRunnable();
+        synchronized (pis) {
+            t = new Thread(myRun);
+            // thread t will be blocked inside pos.write(1)
+            // when it tries to call the synchronized method pis.receive
+            // because we hold the monitor for object pis
+            t.start();
+            try {
+                // wait for thread t to get to the call to pis.receive
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+            }
+            // now we close
+            pos.close();
+        }
+        // we have exited the synchronized block, so now thread t will make
+        // a call to pis.receive AFTER the output stream was closed,
+        // in which case an IOException should be thrown
+        while (t.isAlive()) {
+            ;
+        }
+        assertTrue(
+                "write failed to throw IOException on closed PipedOutputStream",
+                myRun.pass);
+    }
+
+    static class Worker extends Thread {
+        PipedOutputStream out;
+
+        Worker(PipedOutputStream pos) {
+            this.out = pos;
+        }
+
+        public void run() {
+            try {
+                out.write(20);
+                out.close();
+                Thread.sleep(5000);
+            } catch (Exception e) {
+            }
+        }
+    }
+
+    public void test_read_after_write_close() throws Exception {
+        PipedInputStream in = new PipedInputStream();
+        PipedOutputStream out = new PipedOutputStream();
+        in.connect(out);
+        Thread worker = new Worker(out);
+        worker.start();
+        Thread.sleep(2000);
+        assertEquals("Should read 20.", 20, in.read());
+        worker.join();
+        assertEquals("Write end is closed, should return -1", -1, in.read());
+        byte[] buf = new byte[1];
+        assertEquals("Write end is closed, should return -1", -1, in.read(buf, 0, 1));
+        assertEquals("Buf len 0 should return first", 0, in.read(buf, 0, 0));
+        in.close();
+        out.close();
+    }
+
+    /**
+     * 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) {
+        }
+        super.tearDown();
+    }
+
+
+    /**
+     * 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
+        }
+    }
+
+    /**
+     * 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/PipedOutputStreamTest.java b/luni/src/test/java/tests/api/java/io/PipedOutputStreamTest.java
new file mode 100644
index 0000000..bf2f703
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/PipedOutputStreamTest.java
@@ -0,0 +1,231 @@
+/*
+ *  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.io;
+
+import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.UnsupportedEncodingException;
+
+import junit.framework.TestCase;
+
+public class PipedOutputStreamTest extends TestCase {
+
+    static class PReader implements Runnable {
+        PipedInputStream reader;
+
+        public PipedInputStream getReader() {
+            return reader;
+        }
+
+        public PReader(PipedOutputStream out) {
+            try {
+                reader = new PipedInputStream(out);
+            } catch (Exception e) {
+                System.out.println("Couldn't start reader");
+            }
+        }
+
+        public int available() {
+            try {
+                return reader.available();
+            } catch (Exception e) {
+                return -1;
+            }
+        }
+
+        public void run() {
+            try {
+                while (true) {
+                    Thread.sleep(1000);
+                    Thread.yield();
+                }
+            } catch (InterruptedException e) {
+            }
+        }
+
+        public String read(int nbytes) {
+            byte[] buf = new byte[nbytes];
+            try {
+                reader.read(buf, 0, nbytes);
+                return new String(buf, "UTF-8");
+            } catch (IOException e) {
+                System.out.println("Exception reading info");
+                return "ERROR";
+            }
+        }
+    }
+
+    Thread rt;
+
+    PReader reader;
+
+    PipedOutputStream out;
+
+    /**
+     * java.io.PipedOutputStream#PipedOutputStream()
+     */
+    public void test_Constructor() {
+        // Used in tests
+    }
+
+    /**
+     * java.io.PipedOutputStream#PipedOutputStream(java.io.PipedInputStream)
+     */
+    public void test_ConstructorLjava_io_PipedInputStream() throws Exception {
+        out = new PipedOutputStream(new PipedInputStream());
+        out.write('b');
+    }
+
+    /**
+     * java.io.PipedOutputStream#close()
+     */
+    public void test_close() throws Exception {
+        out = new PipedOutputStream();
+        rt = new Thread(reader = new PReader(out));
+        rt.start();
+        out.close();
+    }
+
+    /**
+     * java.io.PipedOutputStream#connect(java.io.PipedInputStream)
+     */
+    public void test_connectLjava_io_PipedInputStream_Exception()
+            throws IOException {
+        out = new PipedOutputStream();
+        out.connect(new PipedInputStream());
+        try {
+            out.connect(null);
+            fail("should throw NullPointerException"); //$NON-NLS-1$
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.PipedOutputStream#connect(java.io.PipedInputStream)
+     */
+    public void test_connectLjava_io_PipedInputStream() {
+        try {
+            out = new PipedOutputStream();
+            rt = new Thread(reader = new PReader(out));
+            rt.start();
+            out.connect(new PipedInputStream());
+            fail("Failed to throw exception attempting connect on already connected stream");
+        } catch (IOException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.io.PipedOutputStream#flush()
+     */
+    public void test_flush() throws IOException, UnsupportedEncodingException {
+        out = new PipedOutputStream();
+        rt = new Thread(reader = new PReader(out));
+        rt.start();
+        out.write("HelloWorld".getBytes("UTF-8"), 0, 10);
+        assertTrue("Bytes written before flush", reader.available() != 0);
+        out.flush();
+        assertEquals("Wrote incorrect bytes", "HelloWorld", reader.read(10));
+    }
+
+    /**
+     * java.io.PipedOutputStream#write(byte[], int, int)
+     */
+    public void test_write$BII() throws IOException, UnsupportedEncodingException {
+        out = new PipedOutputStream();
+        rt = new Thread(reader = new PReader(out));
+        rt.start();
+        out.write("HelloWorld".getBytes("UTF-8"), 0, 10);
+        out.flush();
+        assertEquals("Wrote incorrect bytes", "HelloWorld", reader.read(10));
+    }
+
+    /**
+     * java.io.PipedOutputStream#write(byte[], int, int) Regression for
+     * HARMONY-387
+     */
+    public void test_write$BII_2() throws IOException {
+        PipedInputStream pis = new PipedInputStream();
+        PipedOutputStream pos = null;
+        try {
+            pos = new PipedOutputStream(pis);
+            pos.write(new byte[0], -1, -1);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        // Regression for HARMONY-4311
+        try {
+            pis = new PipedInputStream();
+            PipedOutputStream out = new PipedOutputStream(pis);
+            out.write(null, -10, 10);
+            fail("should throw NullPointerException.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        pis = new PipedInputStream();
+        pos = new PipedOutputStream(pis);
+        pos.close();
+        pos.write(new byte[0], 0, 0);
+
+        try {
+            pis = new PipedInputStream();
+            pos = new PipedOutputStream(pis);
+            pos.write(new byte[0], -1, 0);
+            fail("IndexOutOfBoundsException expected");
+        } catch (IndexOutOfBoundsException t) {
+            //expected
+        }
+
+        try {
+            pis = new PipedInputStream();
+            pos = new PipedOutputStream(pis);
+            pos.write(null, -10, 0);
+            fail("should throw NullPointerException.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+    }
+
+    /**
+     * java.io.PipedOutputStream#write(int)
+     */
+    public void test_writeI() throws IOException {
+        out = new PipedOutputStream();
+        rt = new Thread(reader = new PReader(out));
+        rt.start();
+        out.write('c');
+        out.flush();
+        assertEquals("Wrote incorrect byte", "c", reader.read(1));
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    @Override
+    protected void tearDown() {
+        if (rt != null) {
+            rt.interrupt();
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/PipedReaderTest.java b/luni/src/test/java/tests/api/java/io/PipedReaderTest.java
new file mode 100644
index 0000000..fb42069
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/PipedReaderTest.java
@@ -0,0 +1,399 @@
+/*
+ *  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.io;
+
+import java.io.IOException;
+import java.io.PipedReader;
+import java.io.PipedWriter;
+
+import junit.framework.TestCase;
+
+public class PipedReaderTest extends TestCase {
+
+    static class PWriter implements Runnable {
+        public PipedWriter pw;
+
+        public PWriter(PipedReader reader) {
+            try {
+                pw = new PipedWriter(reader);
+            } catch (Exception e) {
+                System.out.println("Couldn't create writer");
+            }
+        }
+
+        public PWriter() {
+            pw = new PipedWriter();
+        }
+
+        public void run() {
+            try {
+                char[] c = new char[11];
+                "Hello World".getChars(0, 11, c, 0);
+                pw.write(c);
+                Thread.sleep(10000);
+            } catch (InterruptedException e) {
+            } catch (Exception e) {
+                System.out.println("Exception occurred: " + e.toString());
+            }
+        }
+    }
+
+    PipedReader preader;
+
+    PWriter pwriter;
+
+    Thread t;
+
+    /**
+     * java.io.PipedReader#PipedReader()
+     */
+    public void test_Constructor() {
+        // Used in test
+    }
+
+    /**
+     * java.io.PipedReader#PipedReader(java.io.PipedWriter)
+     */
+    public void test_ConstructorLjava_io_PipedWriter() throws IOException {
+        preader = new PipedReader(new PipedWriter());
+    }
+
+    /**
+     * 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(null, -1);
+            fail("Should throw IllegalArgumentException"); //$NON-NLS-1$
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            preader = new PipedReader(null, 0);
+            fail("Should throw IllegalArgumentException"); //$NON-NLS-1$
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    /**
+     * 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
+        }
+    }
+
+    /**
+     * java.io.PipedReader#close()
+     */
+    public void test_close() throws Exception {
+        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, 11);
+        preader.close();
+        assertEquals("Read incorrect chars", "Hello World", new String(c));
+    }
+
+    /**
+     * java.io.PipedReader#connect(java.io.PipedWriter)
+     */
+    public void test_connectLjava_io_PipedWriter() throws Exception {
+        char[] c = null;
+
+        preader = new PipedReader();
+        t = new Thread(pwriter = new PWriter(), "");
+        preader.connect(pwriter.pw);
+        t.start();
+        Thread.sleep(500); // Allow writer to start
+        c = new char[11];
+        preader.read(c, 0, 11);
+
+        assertEquals("Read incorrect chars", "Hello World", new String(c));
+        try {
+            preader.connect(pwriter.pw);
+            fail("Failed to throw exception connecting to pre-connected reader");
+        } catch (IOException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.io.PipedReader#read()
+     */
+    public void test_read() throws Exception {
+        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];
+        for (int i = 0; i < c.length; i++) {
+            c[i] = (char) preader.read();
+        }
+        assertEquals("Read incorrect chars", "Hello World", new String(c));
+    }
+
+    /**
+     * 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), "");
+        t.start();
+        Thread.sleep(500); // Allow writer to start
+        c = new char[11];
+        int n = 0;
+        int x = n;
+        while (x < 11) {
+            n = preader.read(c, x, 11 - x);
+            x = x + n;
+        }
+        assertEquals("Read incorrect chars", "Hello World", new String(c));
+        try {
+            preader.close();
+            preader.read(c, 8, 7);
+            fail("Failed to throw exception reading from closed reader");
+        } catch (IOException e) {
+            // Expected
+        }
+    }
+
+    public void test_read$CII_ExceptionPriority() throws IOException {
+        // Regression for HARMONY-387
+        PipedWriter pw = new PipedWriter();
+        PipedReader obj = null;
+        try {
+            obj = new PipedReader(pw);
+            obj.read(new char[0], (int) 0, (int) -1);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+    }
+
+    public void test_read$CII_ExceptionPriority2() throws IOException {
+        PipedWriter pw = new PipedWriter();
+        PipedReader obj = null;
+        try {
+            obj = new PipedReader(pw);
+            obj.read(new char[0], (int) -1, (int) 0);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+    }
+
+    public void test_read$CII_ExceptionPriority3() throws IOException {
+        PipedWriter pw = new PipedWriter();
+        PipedReader obj = null;
+        try {
+            obj = new PipedReader(pw);
+            obj.read(new char[0], (int) -1, (int) -1);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+    }
+
+    public void test_read$CII_ExceptionPriority4() throws IOException {
+        PipedWriter pw = new PipedWriter();
+        PipedReader pr = new PipedReader(pw);
+        try {
+            pr.read(null, -1, 1);
+            fail();
+        } catch (NullPointerException expected) {
+        } catch (IndexOutOfBoundsException expected) {
+        }
+    }
+
+    public void test_read_$CII_IOException() throws IOException {
+        PipedWriter pw = new PipedWriter();
+        PipedReader pr = new PipedReader(pw);
+        pr.close();
+        try {
+            pr.read(null, 0, 10);
+            fail("Should throws IOException"); //$NON-NLS-1$
+        } catch (IOException e) {
+            // expected
+        } finally {
+            pw = null;
+            pr = null;
+        }
+
+        pr = new PipedReader();
+        pr.close();
+        try {
+            pr.read(null, 0, 10);
+            fail("Should throws IOException"); //$NON-NLS-1$
+        } catch (IOException e) {
+            // expected
+        } finally {
+            pr = null;
+        }
+
+        pw = new PipedWriter();
+        pr = new PipedReader(pw);
+        pr.close();
+        try {
+            pr.read(new char[10], -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);
+        pr.close();
+        try {
+            pr.read(new char[10], 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);
+        pr.close();
+        try {
+            pr.read(new char[10], 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, 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;
+        }
+    }
+
+    /**
+     * java.io.PipedReader#ready()
+     */
+    public void test_ready() throws Exception {
+        char[] c = null;
+        preader = new PipedReader();
+        t = new Thread(new PWriter(preader), "");
+        t.start();
+        Thread.sleep(500); // Allow writer to start
+        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("Reader should not be ready after reading all chars",
+                preader.ready());
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    protected void tearDown() throws Exception {
+        if (t != null) {
+            t.interrupt();
+        }
+        super.tearDown();
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/PipedWriterTest.java b/luni/src/test/java/tests/api/java/io/PipedWriterTest.java
new file mode 100644
index 0000000..eb66e86
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/PipedWriterTest.java
@@ -0,0 +1,480 @@
+/*
+ *  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.io;
+
+import java.io.IOException;
+import java.io.PipedReader;
+import java.io.PipedWriter;
+
+public class PipedWriterTest extends junit.framework.TestCase {
+
+    static class PReader implements Runnable {
+        public PipedReader pr;
+
+        public char[] buf = new char[10];
+
+        public PReader(PipedWriter pw) {
+            try {
+                pr = new PipedReader(pw);
+            } catch (IOException e) {
+                System.out.println("Exception setting up reader: "
+                        + e.toString());
+            }
+        }
+
+        public PReader(PipedReader pr) {
+            this.pr = pr;
+        }
+
+        public void run() {
+            try {
+                int r = 0;
+                for (int i = 0; i < buf.length; i++) {
+                    r = pr.read();
+                    if (r == -1)
+                        break;
+                    buf[i] = (char) r;
+                }
+            } catch (Exception e) {
+                System.out.println("Exception reading ("
+                        + Thread.currentThread().getName() + "): "
+                        + e.toString());
+            }
+        }
+    }
+
+    Thread rdrThread;
+
+    PReader reader;
+
+    PipedWriter pw;
+
+    /**
+     * java.io.PipedWriter#PipedWriter()
+     */
+    public void test_Constructor() {
+        // Test for method java.io.PipedWriter()
+        // Used in tests
+    }
+
+    /**
+     * java.io.PipedWriter#PipedWriter(java.io.PipedReader)
+     */
+    public void test_ConstructorLjava_io_PipedReader() throws Exception {
+        // Test for method java.io.PipedWriter(java.io.PipedReader)
+        char[] buf = new char[10];
+        "HelloWorld".getChars(0, 10, buf, 0);
+        PipedReader rd = new PipedReader();
+        pw = new PipedWriter(rd);
+        rdrThread = new Thread(reader = new PReader(rd), "Constructor(Reader)");
+        rdrThread.start();
+        pw.write(buf);
+        pw.close();
+        rdrThread.join(500);
+        assertEquals("Failed to construct writer", "HelloWorld", new String(
+                reader.buf));
+    }
+
+    /**
+     * java.io.PipedWriter#close()
+     */
+    public void test_close() throws Exception {
+        // Test for method void java.io.PipedWriter.close()
+        char[] buf = new char[10];
+        "HelloWorld".getChars(0, 10, buf, 0);
+        PipedReader rd = new PipedReader();
+        pw = new PipedWriter(rd);
+        reader = new PReader(rd);
+        pw.close();
+        try {
+            pw.write(buf);
+            fail("Should have thrown exception when attempting to write to closed writer.");
+        } catch (Exception e) {
+            // correct
+        }
+    }
+
+    /**
+     * java.io.PipedWriter#connect(java.io.PipedReader)
+     */
+    public void test_connectLjava_io_PipedReader() throws Exception {
+        // Test for method void java.io.PipedWriter.connect(java.io.PipedReader)
+        char[] buf = new char[10];
+        "HelloWorld".getChars(0, 10, buf, 0);
+        PipedReader rd = new PipedReader();
+        pw = new PipedWriter();
+        pw.connect(rd);
+        rdrThread = new Thread(reader = new PReader(rd), "connect");
+        rdrThread.start();
+        pw.write(buf);
+        pw.close();
+        rdrThread.join(500);
+        assertEquals("Failed to write correct chars", "HelloWorld", new String(
+                reader.buf));
+    }
+
+    /**
+     * java.io.PipedWriter#flush()
+     */
+    public void test_flush() throws Exception {
+        // Test for method void java.io.PipedWriter.flush()
+        char[] buf = new char[10];
+        "HelloWorld".getChars(0, 10, buf, 0);
+        pw = new PipedWriter();
+        rdrThread = new Thread(reader = new PReader(pw), "flush");
+        rdrThread.start();
+        pw.write(buf);
+        pw.flush();
+        rdrThread.join(700);
+        assertEquals("Failed to flush chars", "HelloWorld", new String(
+                reader.buf));
+    }
+
+    /**
+     * java.io.PipedWriter#flush()
+     * Regression HARMONY-6293
+     */
+    public void test_flushAfterClose() throws Exception {
+
+        PipedReader pr = new PipedReader();
+        pw = new PipedWriter(pr);
+        pw.close();
+        try {
+            pw.flush();
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+
+        pr = new PipedReader();
+        pw = new PipedWriter(pr);
+        pr.close();
+
+        try {
+            pw.flush();
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.PipedWriter#write(char[], int, int)
+     */
+    public void test_write$CII() throws Exception {
+        // Test for method void java.io.PipedWriter.write(char [], int, int)
+        char[] buf = new char[10];
+        "HelloWorld".getChars(0, 10, buf, 0);
+        pw = new PipedWriter();
+        rdrThread = new Thread(reader = new PReader(pw), "writeCII");
+        rdrThread.start();
+        pw.write(buf, 0, 10);
+        pw.close();
+        rdrThread.join(1000);
+        assertEquals("Failed to write correct chars", "HelloWorld", new String(
+                reader.buf));
+    }
+
+    /**
+     * java.io.PipedWriter#write(char[], int, int) Regression for
+     * HARMONY-387
+     */
+    public void test_write$CII_2() throws IOException {
+        PipedReader pr = new PipedReader();
+        PipedWriter obj = null;
+        try {
+            obj = new java.io.PipedWriter(pr);
+            obj.write(new char[0], (int) 0, (int) -1);
+            fail("IndexOutOfBoundsException expected");
+        } catch (IndexOutOfBoundsException expected) {
+        }
+    }
+
+    /**
+     * java.io.PipedWriter#write(char[], int, int)
+     */
+    public void test_write$CII_3() throws IOException {
+        PipedReader pr = new PipedReader();
+        PipedWriter obj = null;
+        try {
+            obj = new java.io.PipedWriter(pr);
+            obj.write(new char[0], (int) -1, (int) 0);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+    }
+
+    /**
+     * java.io.PipedWriter#write(char[], int, int)
+     */
+    public void test_write$CII_4() throws IOException {
+        PipedReader pr = new PipedReader();
+        PipedWriter obj = null;
+        try {
+            obj = new java.io.PipedWriter(pr);
+            obj.write(new char[0], (int) -1, (int) -1);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+    }
+
+    /**
+     * java.io.PipedWriter#write(char[], int, int)
+     */
+    public void test_write$CII_5() throws IOException {
+        PipedReader pr = new PipedReader();
+        PipedWriter obj = null;
+        try {
+            obj = new PipedWriter(pr);
+            obj.write((char[]) null, (int) -1, (int) 0);
+            fail("NullPointerException expected");
+        } catch (IndexOutOfBoundsException t) {
+            fail("NullPointerException expected");
+        } catch (NullPointerException t) {
+        }
+    }
+
+    /**
+     * java.io.PipedWriter#write(char[], int, int)
+     */
+    public void test_write$CII_6() throws IOException {
+        PipedReader pr = new PipedReader();
+        PipedWriter obj = null;
+        try {
+            obj = new PipedWriter(pr);
+            obj.write((char[]) null, (int) -1, (int) -1);
+            fail("NullPointerException expected");
+        } catch (IndexOutOfBoundsException t) {
+            fail("NullPointerException expected");
+        } catch (NullPointerException t) {
+        }
+    }
+
+    /**
+     * java.io.PipedWriter#write(char[], int, int)
+     */
+    public void test_write$CII_notConnected() throws IOException {
+        // Regression test for Harmony-2404
+        // create not connected pipe
+        PipedWriter obj = new PipedWriter();
+
+        // char array is null
+        try {
+            obj.write((char[]) null, 0, 1);
+            fail("IOException expected");
+        } catch (IOException ioe) {
+            // expected
+        }
+
+        // negative offset
+        try {
+            obj.write(new char[] { 1 }, -10, 1);
+            fail("IOException expected");
+        } catch (IOException ioe) {
+            // expected
+        }
+
+        // wrong offset
+        try {
+            obj.write(new char[] { 1 }, 10, 1);
+            fail("IOException expected");
+        } catch (IOException ioe) {
+            // expected
+        }
+
+        // negative length
+        try {
+            obj.write(new char[] { 1 }, 0, -10);
+            fail("IOException expected");
+        } catch (IOException ioe) {
+            // expected
+        }
+
+        // all valid params
+        try {
+            obj.write(new char[] { 1, 1 }, 0, 1);
+            fail("IOException expected");
+        } catch (IOException ioe) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.PipedWriter#write(int)
+     */
+    public void test_write_I_MultiThread() throws IOException {
+        final PipedReader pr = new PipedReader();
+        final PipedWriter pw = new PipedWriter();
+        // test if writer recognizes dead reader
+        pr.connect(pw);
+
+        class WriteRunnable implements Runnable {
+            boolean pass = false;
+            volatile boolean readerAlive = true;
+
+            public void run() {
+                try {
+                    pw.write(1);
+                    while (readerAlive) {
+                        // wait the reader thread dead
+                    }
+                    try {
+                        // should throw exception since reader thread
+                        // is now dead
+                        pw.write(1);
+                    } catch (IOException e) {
+                        pass = true;
+                    }
+                } catch (IOException e) {
+                    //ignore
+                }
+            }
+        }
+        WriteRunnable writeRunnable = new WriteRunnable();
+        Thread writeThread = new Thread(writeRunnable);
+        class ReadRunnable implements Runnable {
+            boolean pass;
+
+            public void run() {
+                try {
+                    pr.read();
+                    pass = true;
+                } catch (IOException e) {
+                    //ignore
+                }
+            }
+        }
+        ReadRunnable readRunnable = new ReadRunnable();
+        Thread readThread = new Thread(readRunnable);
+        writeThread.start();
+        readThread.start();
+        while (readThread.isAlive()) {
+            //wait the reader thread dead
+        }
+        writeRunnable.readerAlive = false;
+        assertTrue("reader thread failed to read", readRunnable.pass);
+        while (writeThread.isAlive()) {
+            //wait the writer thread dead
+        }
+        assertTrue("writer thread failed to recognize dead reader",
+                writeRunnable.pass);
+    }
+
+    /**
+     * java.io.PipedWriter#write(char[], int, int)
+     */
+    public void test_write_$CII_MultiThread() throws Exception {
+        final PipedReader pr = new PipedReader();
+        final PipedWriter pw = new PipedWriter();
+
+        // test if writer recognizes dead reader
+        pr.connect(pw);
+
+        class WriteRunnable implements Runnable {
+            boolean pass = false;
+
+            volatile boolean readerAlive = true;
+
+            public void run() {
+                try {
+                    pw.write(1);
+                    while (readerAlive) {
+                        // wait the reader thread dead
+                    }
+                    try {
+                        // should throw exception since reader thread
+                        // is now dead
+                        char[] buf = new char[10];
+                        pw.write(buf, 0, 10);
+                    } catch (IOException e) {
+                        pass = true;
+                    }
+                } catch (IOException e) {
+                    //ignore
+                }
+            }
+        }
+        WriteRunnable writeRunnable = new WriteRunnable();
+        Thread writeThread = new Thread(writeRunnable);
+        class ReadRunnable implements Runnable {
+            boolean pass;
+
+            public void run() {
+                try {
+                    pr.read();
+                    pass = true;
+                } catch (IOException e) {
+                    //ignore
+                }
+            }
+        }
+        ReadRunnable readRunnable = new ReadRunnable();
+        Thread readThread = new Thread(readRunnable);
+        writeThread.start();
+        readThread.start();
+        while (readThread.isAlive()) {
+            //wait the reader thread dead
+        }
+        writeRunnable.readerAlive = false;
+        assertTrue("reader thread failed to read", readRunnable.pass);
+        while (writeThread.isAlive()) {
+            //wait the writer thread dead
+        }
+        assertTrue("writer thread failed to recognize dead reader",
+                writeRunnable.pass);
+    }
+
+    /**
+     * java.io.PipedWriter#write(int)
+     */
+    public void test_writeI() throws Exception {
+        // Test for method void java.io.PipedWriter.write(int)
+
+        pw = new PipedWriter();
+        rdrThread = new Thread(reader = new PReader(pw), "writeI");
+        rdrThread.start();
+        pw.write(1);
+        pw.write(2);
+        pw.write(3);
+        pw.close();
+        rdrThread.join(1000);
+        assertTrue("Failed to write correct chars: " + (int) reader.buf[0]
+                + " " + (int) reader.buf[1] + " " + (int) reader.buf[2],
+                reader.buf[0] == 1 && reader.buf[1] == 2 && reader.buf[2] == 3);
+    }
+
+    /**
+     * 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 (rdrThread != null) {
+                rdrThread.interrupt();
+            }
+        } catch (Exception ignore) {
+        }
+        try {
+            if (pw != null) {
+                pw.close();
+            }
+        } catch (Exception ignore) {
+        }
+        super.tearDown();
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/PrintStreamTest.java b/luni/src/test/java/tests/api/java/io/PrintStreamTest.java
new file mode 100644
index 0000000..1b74059
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/PrintStreamTest.java
@@ -0,0 +1,673 @@
+/*
+ *  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.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStreamReader;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Locale;
+
+public class PrintStreamTest extends junit.framework.TestCase {
+
+    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);
+        }
+
+        @Override
+        public void clearError() {
+            super.clearError();
+        }
+
+        @Override
+        public void setError() {
+            super.setError();
+        }
+    }
+
+    /**
+     * {@link java.io.PrintStream#PrintStream(String)}
+     */
+    public void test_Constructor_Ljava_lang_String() throws IOException {
+        MockPrintStream os = new MockPrintStream(testFilePath);
+        assertNotNull(os);
+        os.close();
+    }
+
+    /**
+     * {@link java.io.PrintStream#PrintStream(String, String)}
+     */
+    public void test_Constructor_Ljava_lang_String_Ljava_lang_String() throws Exception {
+        MockPrintStream os = new MockPrintStream(testFilePath, "utf-8");
+        assertNotNull(os);
+        os.close();
+
+        // Test that a bogus charset is mentioned in the exception
+        try {
+            new PrintStream(testFilePath, "Bogus");
+            fail("Exception expected");
+        } catch (UnsupportedEncodingException e) {
+            assertNotNull(e.getMessage());
+        }
+    }
+
+    /**
+     * java.io.PrintStream#PrintStream(java.io.OutputStream)
+     */
+    public void test_ConstructorLjava_io_OutputStream() throws Exception {
+        // Test for method java.io.PrintStream(java.io.OutputStream)
+        PrintStream os = new PrintStream(bos);
+        os.print(2345.76834720202);
+        os.close();
+
+        // regression for HARMONY-1195
+        try {
+            os = new PrintStream(bos, true, null);
+            fail("Should throw NPE");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    /**
+     * java.io.PrintStream#PrintStream(java.io.OutputStream, boolean)
+     */
+    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();
+    }
+
+    /**
+     * java.io.PrintStream#PrintStream(java.io.OutputStream, boolean, String)
+     */
+    public void test_ConstructorLjava_io_OutputStreamZLjava_lang_String() {
+        try {
+            new PrintStream(new ByteArrayOutputStream(), false,
+                    "%Illegal_name!");
+            fail("Expected UnsupportedEncodingException");
+        } catch (UnsupportedEncodingException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.PrintStream#checkError()
+     */
+    public void test_checkError() throws Exception {
+        // Test for method boolean java.io.PrintStream.checkError()
+        PrintStream os = new PrintStream(new OutputStream() {
+
+            public void write(int b) throws IOException {
+                throw new IOException();
+            }
+
+            public void write(byte[] b, int o, int l) throws IOException {
+                throw new IOException();
+            }
+        });
+        os.print(fileString.substring(0, 501));
+
+        assertTrue("Checkerror should return true", os.checkError());
+    }
+
+    /**
+     * {@link java.io.PrintStream#clearError()}
+     */
+    public void test_clearError() throws FileNotFoundException {
+        MockPrintStream os = new MockPrintStream(testFilePath);
+        assertFalse(os.checkError());
+        os.setError();
+        assertTrue(os.checkError());
+        os.clearError();
+        assertFalse(os.checkError());
+        os.close();
+    }
+
+    /**
+     * java.io.PrintStream#close()
+     */
+    public void test_close() throws Exception {
+        // Test for method void java.io.PrintStream.close()
+        PrintStream os = new PrintStream(bos);
+        os.close();
+        bos.close();
+    }
+
+    /**
+     * java.io.PrintStream#flush()
+     */
+    public void test_flush() throws Exception {
+        // Test for method void java.io.PrintStream.flush()
+        PrintStream os = new PrintStream(bos);
+        os.print(fileString.substring(0, 501));
+        os.flush();
+        assertEquals("Bytes not written after flush", 501, bos.size());
+        bos.close();
+        os.close();
+    }
+
+    /**
+     * java.io.PrintStream#print(char[])
+     */
+    public void test_print$C() {
+        // Test for method void java.io.PrintStream.print(char [])
+        PrintStream os = new PrintStream(bos, true);
+        try {
+            os.print((char[]) null);
+            fail("NPE expected");
+        } catch (NullPointerException ok) {
+        }
+
+        os = new PrintStream(bos, true);
+        char[] sc = new char[4000];
+        fileString.getChars(0, fileString.length(), sc, 0);
+        os.print(sc);
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        os.close();
+
+        byte[] rbytes = new byte[4000];
+        bis.read(rbytes, 0, fileString.length());
+        assertEquals("Incorrect char[] written", fileString, new String(rbytes,
+                0, fileString.length()));
+    }
+
+    /**
+     * java.io.PrintStream#print(char)
+     */
+    public void test_printC() throws Exception {
+        // Test for method void java.io.PrintStream.print(char)
+        PrintStream os = new PrintStream(bos, true);
+        os.print('t');
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        InputStreamReader isr = new InputStreamReader(bis);
+        assertEquals("Incorrect char written", 't', isr.read());
+    }
+
+    /**
+     * java.io.PrintStream#print(double)
+     */
+    public void test_printD() {
+        // Test for method void java.io.PrintStream.print(double)
+        byte[] rbuf = new byte[100];
+        PrintStream os = new PrintStream(bos, true);
+        os.print(2345.76834720202);
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        bis.read(rbuf, 0, 16);
+        assertEquals("Incorrect double written", "2345.76834720202",
+                new String(rbuf, 0, 16));
+    }
+
+    /**
+     * java.io.PrintStream#print(float)
+     */
+    public void test_printF() {
+        // Test for method void java.io.PrintStream.print(float)
+        PrintStream os = new PrintStream(bos, true);
+        byte rbuf[] = new byte[10];
+        os.print(29.08764f);
+        os.flush();
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        bis.read(rbuf, 0, 8);
+        assertEquals("Incorrect float written", "29.08764", new String(rbuf, 0,
+                8));
+
+    }
+
+    /**
+     * java.io.PrintStream#print(int)
+     */
+    public void test_printI() {
+        // Test for method void java.io.PrintStream.print(int)
+        PrintStream os = new PrintStream(bos, true);
+        os.print(768347202);
+        byte[] rbuf = new byte[18];
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        bis.read(rbuf, 0, 9);
+        assertEquals("Incorrect int written", "768347202", new String(rbuf, 0,
+                9));
+    }
+
+    /**
+     * java.io.PrintStream#print(long)
+     */
+    public void test_printJ() {
+        // Test for method void java.io.PrintStream.print(long)
+        byte[] rbuf = new byte[100];
+        PrintStream os = new PrintStream(bos, true);
+        os.print(9875645283333L);
+        os.close();
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        bis.read(rbuf, 0, 13);
+        assertEquals("Incorrect long written", "9875645283333", new String(
+                rbuf, 0, 13));
+    }
+
+    /**
+     * java.io.PrintStream#print(java.lang.Object)
+     */
+    public void test_printLjava_lang_Object() throws Exception {
+        // Test for method void java.io.PrintStream.print(java.lang.Object)
+        PrintStream os = new PrintStream(bos, true);
+        os.print((Object) null);
+        os.flush();
+        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();
+        bos.close();
+        os.close();
+
+        ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
+        os = new PrintStream(bos1, true);
+        os.print(new java.util.Vector());
+        bis = new ByteArrayInputStream(bos1.toByteArray());
+        byte[] rbytes = new byte[2];
+        bis.read(rbytes, 0, 2);
+        assertEquals("Incorrect Object written", "[]", new String(rbytes, 0, 2));
+    }
+
+    /**
+     * java.io.PrintStream#print(java.lang.String)
+     */
+    public void test_printLjava_lang_String() throws Exception {
+        // Test for method void java.io.PrintStream.print(java.lang.String)
+        PrintStream os = new PrintStream(bos, true);
+        os.print((String) null);
+        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();
+        bos.close();
+        os.close();
+
+        ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
+        os = new PrintStream(bos1, true);
+        os.print("Hello World");
+        bis = new ByteArrayInputStream(bos1.toByteArray());
+        byte rbytes[] = new byte[100];
+        bis.read(rbytes, 0, 11);
+        assertEquals("Incorrect string written", "Hello World", new String(
+                rbytes, 0, 11));
+    }
+
+    /**
+     * java.io.PrintStream#print(boolean)
+     */
+    public void test_printZ() throws Exception {
+        // Test for method void java.io.PrintStream.print(boolean)
+        PrintStream os = new PrintStream(bos, true);
+        os.print(true);
+        DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bos
+                .toByteArray()));
+
+        assertTrue("Incorrect boolean written", dis.readBoolean());
+    }
+
+    /**
+     * java.io.PrintStream#println()
+     */
+    public void test_println() throws Exception {
+        // Test for method void java.io.PrintStream.println()
+        char c;
+        PrintStream os = new PrintStream(bos, true);
+        os.println("");
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        InputStreamReader isr = new InputStreamReader(bis);
+        assertTrue("Newline not written", (c = (char) isr.read()) == '\r'
+                || c == '\n');
+    }
+
+    /**
+     * java.io.PrintStream#println(char[])
+     */
+    public void test_println$C() throws Exception {
+        // Test for method void java.io.PrintStream.println(char [])
+        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(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,
+                0, fileString.length()));
+
+        // In this particular test method, the end of data is not immediately
+        // followed by newLine separator in the reading buffer, instead its
+        // followed by zeros. The newline is written as the last entry
+        // in the inputStream buffer. Therefore, we must keep reading until we
+        // hit a new line.
+        int r;
+        boolean newline = false;
+        while ((r = isr.read()) != -1) {
+            if (r == '\r' || r == '\n')
+                newline = true;
+        }
+        assertTrue("Newline not written", newline);
+    }
+
+    /**
+     * java.io.PrintStream#println(char)
+     */
+    public void test_printlnC() throws Exception {
+        // Test for method void java.io.PrintStream.println(char)
+        int c;
+        PrintStream os = new PrintStream(bos, true);
+        os.println('t');
+        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');
+    }
+
+    /**
+     * java.io.PrintStream#println(double)
+     */
+    public void test_printlnD() throws Exception {
+        // Test for method void java.io.PrintStream.println(double)
+        int c;
+        PrintStream os = new PrintStream(bos, true);
+        os.println(2345.76834720202);
+        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 = isr.read()) == '\r' || c == '\n');
+    }
+
+    /**
+     * java.io.PrintStream#println(float)
+     */
+    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(bos, true);
+        os.println(29.08764f);
+        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 = isr.read()) == '\r' || c == '\n');
+    }
+
+    /**
+     * java.io.PrintStream#println(int)
+     */
+    public void test_printlnI() throws Exception {
+        // Test for method void java.io.PrintStream.println(int)
+        int c;
+        PrintStream os = new PrintStream(bos, true);
+        os.println(768347202);
+        byte[] rbuf = new byte[100];
+        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 = isr.read()) == '\r' || c == '\n');
+    }
+
+    /**
+     * java.io.PrintStream#println(long)
+     */
+    public void test_printlnJ() throws Exception {
+        // Test for method void java.io.PrintStream.println(long)
+        int c;
+        PrintStream os = new PrintStream(bos, true);
+        os.println(9875645283333L);
+        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 = isr.read()) == '\r' || c == '\n');
+    }
+
+    /**
+     * java.io.PrintStream#println(java.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(bos, true);
+        os.println(new java.util.Vector());
+        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) isr.read()) == '\r'
+                || c == '\n');
+    }
+
+    /**
+     * java.io.PrintStream#println(java.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(bos, true);
+        os.println("Hello World");
+        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) isr.read()) == '\r'
+                || c == '\n');
+    }
+
+    /**
+     * java.io.PrintStream#println(boolean)
+     */
+    public void test_printlnZ() throws Exception {
+        // Test for method void java.io.PrintStream.println(boolean)
+        int c;
+        PrintStream os = new PrintStream(bos, true);
+        os.println(true);
+        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 = isr.read()) == '\r' || c == '\n');
+    }
+
+    /**
+     * java.io.PrintStream#write(byte[], int, int)
+     */
+    public void test_write$BII() {
+        // Test for method void java.io.PrintStream.write(byte [], int, int)
+        PrintStream os = new PrintStream(bos, true);
+        os.write(fileString.getBytes(), 0, fileString.length());
+        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));
+    }
+
+    /**
+     * java.io.PrintStream#write(int)
+     */
+    public void test_writeI() {
+        // Test for method void java.io.PrintStream.write(int)
+        PrintStream os = new PrintStream(bos, true);
+        os.write('t');
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        assertEquals("Incorrect char written", 't', bis.read());
+    }
+
+    /**
+     * java.io.PrintStream#append(char)
+     */
+    public void test_appendChar() throws IOException {
+        char testChar = ' ';
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        PrintStream printStream = new PrintStream(out);
+        printStream.append(testChar);
+        printStream.flush();
+        assertEquals(String.valueOf(testChar), out.toString());
+        printStream.close();
+    }
+
+    /**
+     * java.io.PrintStream#append(CharSequence)
+     */
+    public void test_appendCharSequence() {
+        String testString = "My Test String";
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        PrintStream printStream = new PrintStream(out);
+        printStream.append(testString);
+        printStream.flush();
+        assertEquals(testString, out.toString());
+        printStream.close();
+    }
+
+    /**
+     * java.io.PrintStream#append(CharSequence, int, int)
+     */
+    public void test_appendCharSequenceIntInt() {
+        String testString = "My Test String";
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        PrintStream printStream = new PrintStream(out);
+        printStream.append(testString, 1, 3);
+        printStream.flush();
+        assertEquals(testString.substring(1, 3), out.toString());
+        printStream.close();
+    }
+
+    /**
+     * java.io.PrintStream#format(java.lang.String, java.lang.Object...)
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object() {
+        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));
+
+    }
+
+    /**
+     * java.io.PrintStream#format(java.util.Locale, java.lang.String,
+     *java.lang.Object...)
+     */
+    public void test_formatLjava_util_Locale_Ljava_lang_String_$Ljava_lang_Object() {
+        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));
+    }
+
+    /**
+     * java.io.PrintStream#printf(java.lang.String, java.lang.Object...)
+     */
+    public void test_printfLjava_lang_String$Ljava_lang_Object() {
+        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));
+    }
+
+    /**
+     * java.io.PrintStream#printf(java.util.Locale, java.lang.String,
+     *java.lang.Object...)
+     */
+    public void test_printfLjava_util_Locale_Ljava_lang_String_$Ljava_lang_Object() {
+        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));
+    }
+
+    @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();
+    }
+
+
+}
diff --git a/luni/src/test/java/tests/api/java/io/PrintWriterTest.java b/luni/src/test/java/tests/api/java/io/PrintWriterTest.java
new file mode 100644
index 0000000..8866212
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/PrintWriterTest.java
@@ -0,0 +1,779 @@
+/*
+ *  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.io;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.nio.charset.Charset;
+import java.util.Locale;
+
+import tests.support.Support_StringReader;
+import tests.support.Support_StringWriter;
+
+public class PrintWriterTest extends junit.framework.TestCase {
+
+    static class Bogus {
+        public String toString() {
+            return "Bogus";
+        }
+    }
+
+    /**
+     * @since 1.6
+     */
+    static class MockPrintWriter extends PrintWriter {
+
+        public MockPrintWriter(OutputStream out, boolean autoflush) {
+            super(out, autoflush);
+        }
+
+        @Override
+        public void clearError() {
+            super.clearError();
+        }
+
+    }
+
+    PrintWriter pw;
+
+    ByteArrayOutputStream bao;
+
+    ByteArrayInputStream bai;
+
+    BufferedReader br;
+
+    /**
+     * 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());
+        }
+    }
+
+    /**
+     * 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());
+        }
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * java.io.PrintWriter#PrintWriter(java.io.File)
+     */
+    public void test_ConstructorLjava_io_File() throws Exception {
+        File file = File.createTempFile(getClass().getName(), null);
+        try {
+            PrintWriter writer = new PrintWriter(file);
+            writer.close();
+        } finally {
+            file.delete();
+        }
+    }
+
+    /**
+     * java.io.PrintWriter#PrintWriter(java.io.File, java.lang.String)
+     */
+    public void test_ConstructorLjava_io_File_Ljava_lang_String() throws Exception {
+        File file = File.createTempFile(getClass().getName(), null);
+        try {
+            PrintWriter writer = new PrintWriter(file,
+                    Charset.defaultCharset().name());
+            writer.close();
+        } finally {
+            file.delete();
+        }
+    }
+
+    /**
+     * java.io.PrintWriter#PrintWriter(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() throws Exception {
+        File file = File.createTempFile(getClass().getName(), null);
+        try {
+            PrintWriter writer = new PrintWriter(file.getPath());
+            writer.close();
+        } finally {
+            file.delete();
+        }
+    }
+
+    /**
+     * java.io.PrintWriter#PrintWriter(java.lang.String, java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String_Ljava_lang_String() throws Exception {
+        File file = File.createTempFile(getClass().getName(), null);
+        try {
+            PrintWriter writer = new PrintWriter(file.getPath(),
+                    Charset.defaultCharset().name());
+            writer.close();
+        } finally {
+            file.delete();
+        }
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * java.io.PrintWriter#clearError()
+     * @since 1.6
+     */
+    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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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)));
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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())
+        );
+    }
+
+    /**
+     * 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)));
+    }
+
+    /**
+     * 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)));
+    }
+
+    /**
+     * 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())
+        );
+    }
+
+    /**
+     * 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())
+        );
+    }
+
+    /**
+     * 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(bao
+                .toByteArray()));
+    }
+
+    /**
+     * 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(bao.toByteArray())
+        );
+    }
+
+    /**
+     * 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()));
+    }
+
+    /**
+     * 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());
+        }
+    }
+
+    /**
+     * 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"));
+    }
+
+    /**
+     * 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"));
+    }
+
+    /**
+     * 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)));
+    }
+
+    /**
+     * 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());
+        }
+
+    }
+
+    /**
+     * 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"));
+    }
+
+    /**
+     * 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"));
+    }
+
+    /**
+     * 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"));
+    }
+
+    /**
+     * 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"));
+    }
+
+    /**
+     * 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"));
+    }
+
+    /**
+     * 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"));
+    }
+
+    /**
+     * 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"));
+    }
+
+    /**
+     * 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');
+
+    }
+
+    /**
+     * 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"));
+    }
+
+    /**
+     * 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"));
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+
+    }
+
+    /**
+     * 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();
+
+    }
+
+    /**
+     * java.io.PrintWriter#format(java.lang.String, java.lang.Object...)
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object() {
+        pw.format("%s %s", "Hello", "World");
+        pw.flush();
+        assertEquals("Wrote incorrect string", "Hello World",
+                new String(bao.toByteArray()));
+    }
+
+    /**
+     * java.io.PrintWriter#format(java.util.Locale, java.lang.String, java.lang.Object...)
+     */
+    public void test_formatLjava_util_Locale_Ljava_lang_String_$Ljava_lang_Object() {
+        pw.format(Locale.US, "%s %s", "Hello", "World");
+        pw.flush();
+        assertEquals("Wrote incorrect string", "Hello World",
+                new String(bao.toByteArray()));
+    }
+
+    /**
+     * java.io.PrintWriter#printf(java.lang.String, java.lang.Object...)
+     */
+    public void test_printfLjava_lang_String$Ljava_lang_Object() {
+        pw.printf("%s %s", "Hello", "World");
+        pw.flush();
+        assertEquals("Wrote incorrect string", "Hello World",
+                new String(bao.toByteArray()));
+    }
+
+    /**
+     * java.io.PrintWriter#printf(java.util.Locale, java.lang.String, java.lang.Object...)
+     */
+    public void test_printfLjava_util_Locale_Ljava_lang_String_$Ljava_lang_Object() {
+        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.
+     */
+    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.
+     */
+    protected void tearDown() {
+        try {
+            pw.close();
+        } catch (Exception e) {
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/PushbackInputStreamTest.java b/luni/src/test/java/tests/api/java/io/PushbackInputStreamTest.java
new file mode 100644
index 0000000..683d6f7
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/PushbackInputStreamTest.java
@@ -0,0 +1,256 @@
+/*
+ *  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.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.PushbackInputStream;
+import java.io.UnsupportedEncodingException;
+
+public class PushbackInputStreamTest extends junit.framework.TestCase {
+
+    PushbackInputStream pis;
+
+    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_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";
+
+    public void test_reset() {
+        PushbackInputStream pb = new PushbackInputStream(
+                new ByteArrayInputStream(new byte[] { 0 }), 2);
+        try {
+            pb.reset();
+            fail("Should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+    }
+
+    public void test_mark() {
+        PushbackInputStream pb = new PushbackInputStream(
+                new ByteArrayInputStream(new byte[] { 0 }), 2);
+        pb.mark(Integer.MAX_VALUE);
+        pb.mark(0);
+        pb.mark(-1);
+        pb.mark(Integer.MIN_VALUE);
+    }
+
+
+    /**
+     * java.io.PushbackInputStream#PushbackInputStream(java.io.InputStream)
+     */
+    public void test_ConstructorLjava_io_InputStream() {
+        try {
+            PushbackInputStream str = new PushbackInputStream(null);
+            str.read();
+            fail("Expected IOException");
+        } catch (IOException e) {
+            // Expected
+        }
+
+        try {
+            pis = new PushbackInputStream(new ByteArrayInputStream("Hello"
+                    .getBytes()));
+            pis.unread("He".getBytes());
+            fail("Failed to throw exception on unread when buffer full");
+        } catch (IOException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.io.PushbackInputStream#PushbackInputStream(java.io.InputStream,
+     *int)
+     */
+    public void test_ConstructorLjava_io_InputStreamI() {
+        // Test for method java.io.PushbackInputStream(java.io.InputStream, int)
+        try {
+            pis = new PushbackInputStream(new ByteArrayInputStream("Hello"
+                    .getBytes()), 5);
+            pis.unread("Hellos".getBytes());
+        } catch (IOException e) {
+            // Correct
+            // Pushback buffer should be full
+            return;
+
+        }
+        fail("Failed to throw exception on unread when buffer full");
+    }
+
+    /*
+     * java.io.PushBackInputStream(InputStream, int)
+     */
+    public void test_ConstructorLjava_io_InputStreamL() {
+        try {
+            PushbackInputStream str = new PushbackInputStream(null, 1);
+            str.read();
+            fail("Expected IOException");
+        } catch (IOException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.io.PushbackInputStream#available()
+     */
+    public void test_available() {
+        // Test for method int java.io.PushbackInputStream.available()
+        try {
+            assertTrue("Available returned incorrect number of bytes", pis
+                    .available() == fileString.getBytes().length);
+        } catch (IOException e) {
+            fail("Exception during available test: " + e.toString());
+        }
+    }
+
+    /**
+     * java.io.PushbackInputStream#markSupported()
+     */
+    public void test_markSupported() {
+        // Test for method boolean java.io.PushbackInputStream.markSupported()
+        assertTrue("markSupported returned true", !pis.markSupported());
+    }
+
+    /**
+     * java.io.PushbackInputStream#read()
+     */
+    public void test_read() {
+        // Test for method int java.io.PushbackInputStream.read()
+        try {
+            assertTrue("Incorrect byte read", pis.read() == fileString
+                    .getBytes("UTF-8")[0]);
+        } catch (IOException e) {
+            fail("Exception during read test : " + e.getMessage());
+        }
+    }
+
+    /**
+     * java.io.PushbackInputStream#read(byte[], int, int)
+     */
+    public void test_read$BII() {
+        // Test for method int java.io.PushbackInputStream.read(byte [], int,
+        // int)
+        try {
+            byte[] buf = new byte[100];
+            pis.read(buf, 0, buf.length);
+            assertTrue("Incorrect bytes read", new String(buf, "UTF-8")
+                    .equals(fileString.substring(0, 100)));
+        } catch (IOException e) {
+            fail("Exception during read test : " + e.getMessage());
+        }
+    }
+
+    /**
+     * java.io.PushbackInputStream#skip(long)
+     */
+    public void test_skipJ() throws Exception {
+        // Test for method long java.io.PushbackInputStream.skip(long)
+        byte[] buf = new byte[50];
+        pis.skip(50);
+        pis.read(buf, 0, buf.length);
+        assertTrue("a) Incorrect bytes read", new String(buf, "UTF-8")
+                .equals(fileString.substring(50, 100)));
+        pis.unread(buf);
+        pis.skip(25);
+        byte[] buf2 = new byte[25];
+        pis.read(buf2, 0, buf2.length);
+        assertTrue("b) Incorrect bytes read", new String(buf2, "UTF-8")
+                .equals(fileString.substring(75, 100)));
+    }
+
+    /**
+     * java.io.PushbackInputStream#unread(byte[])
+     */
+    public void test_unread$B() {
+        // Test for method void java.io.PushbackInputStream.unread(byte [])
+        try {
+            byte[] buf = new byte[100];
+            pis.read(buf, 0, buf.length);
+            assertTrue("Incorrect bytes read", new String(buf, "UTF-8")
+                    .equals(fileString.substring(0, 100)));
+            pis.unread(buf);
+            pis.read(buf, 0, 50);
+            assertTrue("Failed to unread bytes", new String(buf, 0, 50, "UTF-8")
+                    .equals(fileString.substring(0, 50)));
+        } catch (IOException e) {
+            fail("IOException during unread test : " + e.getMessage());
+        }
+    }
+
+    /**
+     * java.io.PushbackInputStream#unread(byte[], int, int)
+     */
+    public void test_unread$BII() throws IOException {
+        // Test for method void java.io.PushbackInputStream.unread(byte [], int,
+        // int)
+        byte[] buf = new byte[100];
+        pis.read(buf, 0, buf.length);
+        assertTrue("Incorrect bytes read", new String(buf, "UTF-8")
+                .equals(fileString.substring(0, 100)));
+        pis.unread(buf, 50, 50);
+        pis.read(buf, 0, 50);
+        assertTrue("Failed to unread bytes", new String(buf, 0, 50, "UTF-8")
+                .equals(fileString.substring(50, 100)));
+
+        // Regression for HARMONY-49
+        try {
+            PushbackInputStream pb = new PushbackInputStream(
+                    new ByteArrayInputStream(new byte[] { 0 }), 2);
+            pb.unread(new byte[1], 0, 5);
+            fail("Assert 0: should throw IOE");
+        } catch (IOException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.PushbackInputStream#unread(int)
+     */
+    public void test_unreadI() {
+        // Test for method void java.io.PushbackInputStream.unread(int)
+        try {
+            int x;
+            assertTrue("Incorrect byte read", (x = pis.read()) == fileString
+                    .getBytes("UTF-8")[0]);
+            pis.unread(x);
+            assertTrue("Failed to unread", pis.read() == x);
+        } catch (IOException e) {
+            fail("IOException during read test : " + e.getMessage());
+        }
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() throws UnsupportedEncodingException {
+
+        pis = new PushbackInputStream(new ByteArrayInputStream(fileString
+                .getBytes("UTF-8")), 65535);
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    protected void tearDown() {
+        try {
+            pis.close();
+        } catch (IOException e) {
+            fail("IOException during tearDown : " + e.getMessage());
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/PushbackReaderTest.java b/luni/src/test/java/tests/api/java/io/PushbackReaderTest.java
new file mode 100644
index 0000000..973c029
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/PushbackReaderTest.java
@@ -0,0 +1,381 @@
+/*
+ *  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.io;
+
+import java.io.CharArrayReader;
+import java.io.FilterReader;
+import java.io.IOException;
+import java.io.PushbackReader;
+import java.io.Reader;
+import java.io.StringReader;
+
+public class PushbackReaderTest extends junit.framework.TestCase {
+
+    PushbackReader pbr;
+
+    String pbString = "Hello World";
+
+    /**
+     * java.io.PushbackReader#PushbackReader(java.io.Reader)
+     */
+    public void test_ConstructorLjava_io_Reader() {
+        // Test for method java.io.PushbackReader(java.io.Reader)
+        try {
+            pbr.close();
+            pbr = new PushbackReader(new StringReader(pbString));
+            char buf[] = new char[5];
+            pbr.read(buf, 0, 5);
+            pbr.unread(buf);
+        } catch (IOException e) {
+            // Correct
+            return;
+        }
+        fail("Created reader with buffer larger than 1");
+    }
+
+    /**
+     * java.io.PushbackReader#PushbackReader(java.io.Reader, int)
+     */
+    public void test_ConstructorLjava_io_ReaderI() {
+        // Test for method java.io.PushbackReader(java.io.Reader, int)
+        assertTrue("Used to test", true);
+    }
+
+    /**
+     * java.io.PushbackReader#close()
+     */
+    public void test_close() {
+        // Test for method void java.io.PushbackReader.close()
+        try {
+            pbr.close();
+            pbr.read();
+        } catch (Exception e) {
+            return;
+        }
+        fail("Failed to throw exception reading from closed reader");
+    }
+
+    /**
+     * java.io.PushbackReader#mark(int)
+     */
+    public void test_markI() {
+        try {
+            pbr.mark(3);
+        } catch (IOException e) {
+            // correct
+            return;
+        }
+        fail("mark failed to throw expected IOException");
+    }
+
+    /**
+     * java.io.PushbackReader#markSupported()
+     */
+    public void test_markSupported() {
+        // Test for method boolean java.io.PushbackReader.markSupported()
+        assertTrue("markSupported returned true", !pbr.markSupported());
+    }
+
+    /**
+     * java.io.PushbackReader#read()
+     */
+    public void test_read() {
+        // Test for method int java.io.PushbackReader.read()
+        try {
+            char c;
+            pbr.read();
+            c = (char) pbr.read();
+            assertTrue("Failed to read char: " + c, c == pbString.charAt(1));
+            Reader reader = new PushbackReader(new CharArrayReader(
+                    new char[] { '\u8765' }));
+            assertTrue("Wrong double byte character", reader.read() == '\u8765');
+        } catch (IOException e) {
+            fail("IOException during read test : " + e.getMessage());
+        }
+    }
+
+    /**
+     * java.io.PushbackReader#read(char[], int, int)
+     */
+    public void test_read$CII() {
+        // Test for method int java.io.PushbackReader.read(char [], int, int)
+        try {
+            char[] c = new char[5];
+            pbr.read(c, 0, 5);
+            assertTrue("Failed to read chars", new String(c).equals(pbString
+                    .substring(0, 5)));
+        } catch (IOException e) {
+            fail("IOException during read test : " + e.getMessage());
+        }
+    }
+
+    public void test_read_$CII_Exception() throws IOException {
+        pbr = new PushbackReader(new StringReader(pbString), 10);
+
+        char[] charArray = new char[10];
+
+        try {
+            pbr.read(null, 1, 0);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+        try {
+            pbr.read(charArray, 0, -1);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+        try {
+            pbr.read(charArray, -1, 0);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        pbr.read(charArray, 0, 0);
+        pbr.read(charArray, 0, charArray.length);
+        pbr.read(charArray, charArray.length, 0);
+
+        try {
+            pbr.read(charArray, charArray.length + 1, 0);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+        try {
+            pbr.read(charArray, 0, charArray.length + 1);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        // Can't read from a closed PushbackReader.
+        pbr.close();
+        try {
+            pbr.read(charArray, 0, 1);
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    /**
+     * java.io.PushbackReader#ready()
+     */
+    public void test_ready() {
+        // Test for method boolean java.io.PushbackReader.ready()
+        try {
+            char[] c = new char[11];
+            if (c.length > 0)
+                ;// use c to avoid warning msg
+            assertTrue("Ready stream returned false to ready()", pbr.ready());
+        } catch (IOException e) {
+            fail("IOException during ready() test : " + e.getMessage());
+        }
+    }
+
+    /**
+     * java.io.PushbackReader#reset()
+     */
+    public void test_reset() {
+        try {
+            pbr.reset();
+        } catch (IOException e) {
+            // correct
+            return;
+        }
+        fail("mark failed to throw expected IOException");
+    }
+
+    /**
+     * java.io.PushbackReader#unread(char[])
+     */
+    public void test_unread$C() {
+        // Test for method void java.io.PushbackReader.unread(char [])
+        try {
+            char[] c = new char[5];
+            pbr.read(c, 0, 5);
+            pbr.unread(c);
+            pbr.read(c, 0, 5);
+            assertTrue("Failed to unread chars", new String(c).equals(pbString
+                    .substring(0, 5)));
+        } catch (IOException e) {
+            fail("IOException during read test : " + e.getMessage());
+        }
+    }
+
+    /**
+     * java.io.PushbackReader#skip(long)
+     */
+    public void test_skip$J() {
+        char chars[] = new char[] { 'h', 'e', 'l', 'l', 'o' };
+        for (int i = 0; i < 3; i++) {
+            Reader reader, reader2;
+            switch (i) {
+                case 0:
+                    reader = new StringReader(new String(chars));
+                    reader2 = new StringReader(new String(chars));
+                    break;
+                case 1:
+                    reader = new FilterReader(new StringReader(new String(chars))) {
+                    };
+                    reader2 = new FilterReader(new StringReader(new String(chars))) {
+                    };
+                    break;
+                default:
+                    reader = new CharArrayReader(chars);
+                    reader2 = new CharArrayReader(chars);
+            }
+            PushbackReader pReader = new PushbackReader(reader, 2);
+            PushbackReader pReader2 = new PushbackReader(reader2, 2);
+            boolean skipped = false;
+            long numSkipped = 0;
+            try {
+                numSkipped = pReader2.skip(3);
+                pReader2.unread('a');
+                pReader2.unread('b');
+                numSkipped += pReader2.skip(10);
+                numSkipped += pReader2.skip(10);
+                numSkipped += pReader2.skip(10);
+                numSkipped += pReader2.skip(10);
+                numSkipped += pReader2.skip(10);
+                numSkipped += pReader2.skip(10);
+                assertEquals("Did not skip correct number of characters",
+                        7, numSkipped);
+                numSkipped = 0;
+                numSkipped += pReader.skip(2);
+                pReader.unread('i');
+                numSkipped += pReader.skip(2);
+                numSkipped += pReader.skip(0);
+                skipped = true;
+                numSkipped += pReader.skip(-1);
+                fail("Failed to throw "
+                        + new IllegalArgumentException().getClass().getName());
+            } catch (IllegalArgumentException e) {
+                assertTrue("Failed to skip characters" + e, skipped);
+            } catch (IOException e) {
+                fail("Failed to skip characters" + e);
+            }
+            try {
+                numSkipped += pReader.skip(1);
+                numSkipped += pReader.skip(1);
+                numSkipped += pReader.skip(1);
+                assertEquals("Failed to skip all characters", 6, numSkipped);
+                long nextSkipped = pReader.skip(1);
+                assertEquals("skipped empty reader", 0, nextSkipped);
+            } catch (IOException e) {
+                fail("Failed to skip more characters" + e);
+            }
+        }
+    }
+
+    /**
+     * java.io.PushbackReader#unread(char[], int, int)
+     */
+    public void test_unread$CII() {
+        // Test for method void java.io.PushbackReader.unread(char [], int, int)
+        try {
+            char[] c = new char[5];
+            pbr.read(c, 0, 5);
+            pbr.unread(c, 0, 2);
+            pbr.read(c, 0, 5);
+            assertTrue("Failed to unread chars", new String(c).equals(pbString
+                    .substring(0, 2)
+                    + pbString.substring(5, 8)));
+        } catch (IOException e) {
+            fail("IOException during unread test : " + e.getMessage());
+        }
+    }
+
+    /**
+     * java.io.PushbackReader#unread(char[], int, int)
+     */
+    public void test_unread_$CII_NullPointerException() throws IOException {
+        //a pushback reader with one character buffer
+        pbr = new PushbackReader(new StringReader(pbString));
+
+        try {
+            pbr.unread(null, 0, 1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.PushbackReader#unread(char[], int, int)
+     */
+    public void test_unread_$CII_Exception_InsufficientBuffer() throws IOException {
+        //a pushback reader with one character buffer
+        pbr = new PushbackReader(new StringReader(pbString));
+
+        //if count > buffer's size , should throw IOException
+        try {
+            pbr.unread(new char[pbString.length()], 0, 2);
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.PushbackReader#unread(char[], int, int)
+     */
+    public void test_unread_$CII_ArrayIndexOutOfBoundsException() throws IOException {
+        //a pushback reader with one character buffer
+        pbr = new PushbackReader(new StringReader(pbString));
+
+        try {
+            pbr.unread(new char[pbString.length()], -1, -1);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.io.PushbackReader#unread(int)
+     */
+    public void test_unreadI() {
+        // Test for method void java.io.PushbackReader.unread(int)
+
+        try {
+            int c;
+            pbr.read();
+            c = pbr.read();
+            pbr.unread(c);
+            assertTrue("Failed to unread char", pbr.read() == c);
+        } catch (IOException e) {
+            fail("IOException during unread test : " + e.getMessage());
+        }
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() {
+        pbr = new PushbackReader(new StringReader(pbString), 10);
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    protected void tearDown() {
+        try {
+            pbr.close();
+        } catch (IOException e) {
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/RandomAccessFileTest.java b/luni/src/test/java/tests/api/java/io/RandomAccessFileTest.java
new file mode 100644
index 0000000..4b37616
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/RandomAccessFileTest.java
@@ -0,0 +1,1059 @@
+/*
+ *  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.io;
+
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+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";
+
+    /**
+     * java.io.RandomAccessFile#RandomAccessFile(java.io.File,
+     *java.lang.String)
+     */
+    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();
+        raf = new RandomAccessFile(f, "rws");
+        raf.close();
+
+        f = File.createTempFile("xxx", "yyy");
+        f.deleteOnExit();
+        raf = new RandomAccessFile(f, "rwd");
+        raf.close();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * java.io.RandomAccessFile#RandomAccessFile(java.lang.String,
+     *java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_StringLjava_lang_String_I()
+            throws IOException {
+        RandomAccessFile raf = null;
+        try {
+            raf = new RandomAccessFile("", "r");
+            fail("should throw FileNotFoundException.");
+        } catch (FileNotFoundException e) {
+            // Expected
+        } finally {
+            if (raf != null) {
+                raf.close();
+                raf = null;
+            }
+        }
+        try {
+            raf = new RandomAccessFile(new File(""), "r");
+            fail("should throw FileNotFoundException.");
+        } catch (FileNotFoundException e) {
+            // Expected
+        } finally {
+            if (raf != null) {
+                raf.close();
+                raf = null;
+            }
+        }
+        File dir = new File("/");
+        assertTrue(dir.isDirectory());
+        try {
+            raf = new RandomAccessFile(dir.getPath(), "r");
+            fail();
+        } catch (FileNotFoundException expected) {
+        } finally {
+            if (raf != null) {
+                raf.close();
+                raf = null;
+            }
+        }
+    }
+
+    /**
+     * 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) {
+        }
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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);
+    }
+
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * java.io.RandomAccessFile#seek(long)
+     * <p/>
+     * 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();
+    }
+
+    /**
+     * java.io.RandomAccessFile#read(byte[], int, int)
+     * <p/>
+     * 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();
+    }
+
+    /**
+     * 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
+        }
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * java.io.RandomAccessFile#write(byte[], int, int)
+     * <p/>
+     * 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();
+    }
+
+    // Regression test for HARMONY-6542
+    public void testRandomAccessFile_seekMoreThan2gb() throws IOException {
+        if (File.separator != "/") {
+            // skip windows until a test can be implemented that doesn't
+            // require 2GB of free disk space
+            return;
+        }
+        // (all?) unix platforms support sparse files so this should not
+        // need to have 2GB free disk space to pass
+        RandomAccessFile raf = new RandomAccessFile(f, "rw");
+        // write a few bytes so we get more helpful error messages
+        // if we land in the wrong places
+        raf.write(1);
+        raf.write(2);
+        raf.seek(2147483647);
+        raf.write(3);
+        raf.write(4);
+        raf.write(5);
+        raf.write(6);
+        raf.seek(0);
+        assertEquals("seek 0", 1, raf.read());
+        raf.seek(2147483649L);
+        assertEquals("seek >2gb", 5, raf.read());
+        raf.seek(0);
+        assertEquals("seek back to 0", 1, raf.read());
+        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/tests/api/java/io/ReaderTest.java b/luni/src/test/java/tests/api/java/io/ReaderTest.java
new file mode 100644
index 0000000..34f2599
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/ReaderTest.java
@@ -0,0 +1,205 @@
+/* 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.io;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.nio.CharBuffer;
+
+import junit.framework.TestCase;
+
+public class ReaderTest extends TestCase {
+
+    public void test_Reader_CharBuffer_null() throws IOException {
+        String s = "MY TEST STRING";
+        MockReader mockReader = new MockReader(s.toCharArray());
+        CharBuffer charBuffer = null;
+        try {
+            mockReader.read(charBuffer);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            //expected;
+        }
+    }
+
+    public void test_Reader_CharBuffer_ZeroChar() throws IOException {
+        //the charBuffer has the capacity of 0, then there the number of char read
+        // to the CharBuffer is 0. Furthermore, the MockReader is intact in its content.
+        String s = "MY TEST STRING";
+        char[] srcBuffer = s.toCharArray();
+        MockReader mockReader = new MockReader(srcBuffer);
+        CharBuffer charBuffer = CharBuffer.allocate(0);
+        int result = mockReader.read(charBuffer);
+        assertEquals(0, result);
+        char[] destBuffer = new char[srcBuffer.length];
+        mockReader.read(destBuffer);
+        assertEquals(s, String.valueOf(destBuffer));
+    }
+
+    public void test_Reader_CharBufferChar() throws IOException {
+        String s = "MY TEST STRING";
+        char[] srcBuffer = s.toCharArray();
+        final int CHARBUFFER_SIZE = 10;
+        MockReader mockReader = new MockReader(srcBuffer);
+        CharBuffer charBuffer = CharBuffer.allocate(CHARBUFFER_SIZE);
+        charBuffer.append('A');
+        final int CHARBUFFER_REMAINING = charBuffer.remaining();
+        int result = mockReader.read(charBuffer);
+        assertEquals(CHARBUFFER_REMAINING, result);
+        charBuffer.rewind();
+        assertEquals(s.substring(0, CHARBUFFER_REMAINING), charBuffer
+                .subSequence(CHARBUFFER_SIZE - CHARBUFFER_REMAINING,
+                        CHARBUFFER_SIZE).toString());
+        char[] destBuffer = new char[srcBuffer.length - CHARBUFFER_REMAINING];
+        mockReader.read(destBuffer);
+        assertEquals(s.substring(CHARBUFFER_REMAINING), String
+                .valueOf(destBuffer));
+    }
+
+    /**
+     * {@link java.io.Reader#mark(int)}
+     */
+    public void test_mark() {
+        MockReader mockReader = new MockReader();
+        try {
+            mockReader.mark(0);
+            fail("Should throw IOException for Reader do not support mark");
+        } catch (IOException e) {
+            // Excepted
+        }
+    }
+
+    /**
+     * {@link java.io.Reader#read()}
+     */
+    public void test_read() throws IOException {
+        MockReader reader = new MockReader();
+
+        // return -1 when the stream is null;
+        assertEquals("Should be equal to -1", -1, reader.read());
+
+        String string = "MY TEST STRING";
+        char[] srcBuffer = string.toCharArray();
+        MockReader mockReader = new MockReader(srcBuffer);
+
+        // normal read
+        for (char c : srcBuffer) {
+            assertEquals("Should be equal to \'" + c + "\'", c, mockReader
+                    .read());
+        }
+
+        // return -1 when read Out of Index
+        mockReader.read();
+        assertEquals("Should be equal to -1", -1, reader.read());
+
+    }
+
+    /**
+     * {@link java.io.Reader#ready()}
+     */
+    public void test_ready() throws IOException {
+        MockReader mockReader = new MockReader();
+        assertFalse("Should always return false", mockReader.ready());
+
+    }
+
+    /**
+     * {@link java.io.Reader#reset()}
+     */
+    public void test_reset() {
+        MockReader mockReader = new MockReader();
+        try {
+            mockReader.reset();
+            fail("Should throw IOException");
+        } catch (IOException e) {
+            // Excepted
+        }
+    }
+
+    /**
+     * {@link java.io.Reader#skip(long)}
+     */
+    public void test_skip() throws IOException {
+        String string = "MY TEST STRING";
+        char[] srcBuffer = string.toCharArray();
+        int length = srcBuffer.length;
+        MockReader mockReader = new MockReader(srcBuffer);
+        assertEquals("Should be equal to \'M\'", 'M', mockReader.read());
+
+        // normal skip
+        mockReader.skip(length / 2);
+        assertEquals("Should be equal to \'S\'", 'S', mockReader.read());
+
+        // try to skip a bigger number of characters than the total
+        // Should do nothing
+        mockReader.skip(length);
+
+        // try to skip a negative number of characters throw IllegalArgumentException
+        try {
+            mockReader.skip(-1);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Excepted
+        }
+    }
+
+    class MockReader extends Reader {
+
+        private char[] contents;
+
+        private int current_offset = 0;
+
+        private int length = 0;
+
+        public MockReader() {
+            super();
+        }
+
+        public MockReader(char[] data) {
+            contents = data;
+            length = contents.length;
+        }
+
+        @Override
+        public void close() throws IOException {
+
+            contents = null;
+        }
+
+        @Override
+        public int read(char[] buf, int offset, int count) throws IOException {
+
+            if (null == contents) {
+                return -1;
+            }
+            if (length <= current_offset) {
+                return -1;
+            }
+            if (buf.length < offset + count) {
+                throw new IndexOutOfBoundsException();
+            }
+
+            count = Math.min(count, length - current_offset);
+            for (int i = 0; i < count; i++) {
+                buf[offset + i] = contents[current_offset + i];
+            }
+            current_offset += count;
+            return count;
+        }
+
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/SequenceInputStreamTest.java b/luni/src/test/java/tests/api/java/io/SequenceInputStreamTest.java
new file mode 100644
index 0000000..8ee97f3
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/SequenceInputStreamTest.java
@@ -0,0 +1,193 @@
+/*
+ *  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.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.SequenceInputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Enumeration;
+
+public class SequenceInputStreamTest extends junit.framework.TestCase {
+
+    SequenceInputStream si;
+
+    String s1 = "Hello";
+
+    String s2 = "World";
+
+    /**
+     * java.io.SequenceInputStream#SequenceInputStream(java.io.InputStream,
+     *java.io.InputStream)
+     */
+    public void test_ConstructorLjava_io_InputStreamLjava_io_InputStream() {
+        // Test for method java.io.SequenceInputStream(java.io.InputStream,
+        // java.io.InputStream)
+        // Used in tests
+    }
+
+    /**
+     * SequenceInputStream#SequenceInputStream(java.io.InputStream,
+     *java.io.InputStream)
+     */
+    public void test_Constructor_LInputStreamLInputStream_Null() throws UnsupportedEncodingException {
+        try {
+            si = new SequenceInputStream(null, null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            //expected
+        }
+
+        //will not throw NullPointerException if the first InputStream is not null
+        InputStream is = new ByteArrayInputStream(s1.getBytes("UTF-8"));
+        si = new SequenceInputStream(is, null);
+    }
+
+    /**
+     * java.io.SequenceInputStream#SequenceInputStream(java.util.Enumeration)
+     */
+    @SuppressWarnings("unchecked")
+    public void test_ConstructorLjava_util_Enumeration() {
+        // Test for method java.io.SequenceInputStream(java.util.Enumeration)
+        class StreamEnumerator implements Enumeration {
+            InputStream streams[] = new InputStream[2];
+
+            int count = 0;
+
+            public StreamEnumerator() throws UnsupportedEncodingException {
+                streams[0] = new ByteArrayInputStream(s1.getBytes("UTF-8"));
+                streams[1] = new ByteArrayInputStream(s2.getBytes("UTF-8"));
+            }
+
+            public boolean hasMoreElements() {
+                return count < streams.length;
+            }
+
+            public Object nextElement() {
+                return streams[count++];
+            }
+        }
+
+        try {
+            si = new SequenceInputStream(new StreamEnumerator());
+            byte buf[] = new byte[s1.length() + s2.length()];
+            si.read(buf, 0, s1.length());
+            si.read(buf, s1.length(), s2.length());
+            assertTrue("Read incorrect bytes: " + new String(buf), new String(
+                    buf, "UTF-8").equals(s1 + s2));
+        } catch (IOException e) {
+            fail("IOException during read test : " + e.getMessage());
+        }
+
+    }
+
+    /**
+     * java.io.SequenceInputStream#available()
+     */
+    public void test_available() {
+        // Test for method int java.io.SequenceInputStream.available()
+        try {
+
+            assertTrue("Returned incorrect number of bytes: " + si.available(),
+                    si.available() == s1.length());
+        } catch (IOException e) {
+            fail("IOException during available test : " + e.getMessage());
+        }
+    }
+
+    /**
+     * java.io.SequenceInputStream#close()
+     */
+    public void test_close() throws IOException {
+        si.close();
+        //will not throw IOException to close a stream which is closed already
+        si.close();
+    }
+
+    /**
+     * java.io.SequenceInputStream#read()
+     */
+    public void test_read() throws IOException {
+        // Test for method int java.io.SequenceInputStream.read()
+        try {
+            si.read();
+            assertTrue("Read incorrect char", (char) si.read() == s1.charAt(1));
+        } catch (IOException e) {
+            fail("IOException during read test: " + e.getMessage());
+        }
+
+        //returns -1 if the stream is closed , do not throw IOException
+        si.close();
+        int result = si.read();
+        assertEquals(-1, result);
+    }
+
+    /**
+     * java.io.SequenceInputStream#read(byte[], int, int)
+     */
+    public void test_read$BII() throws IOException {
+        // Test for method int java.io.SequenceInputStream.read(byte [], int,
+        // int)
+        try {
+            byte buf[] = new byte[s1.length() + s2.length()];
+            si.read(buf, 0, s1.length());
+            si.read(buf, s1.length(), s2.length());
+            assertTrue("Read incorrect bytes: " + new String(buf), new String(
+                    buf, "UTF-8").equals(s1 + s2));
+        } catch (IOException e) {
+            fail("IOException during read test : " + e.getMessage());
+        }
+
+        ByteArrayInputStream bis1 = new ByteArrayInputStream(
+                new byte[] { 1, 2, 3, 4 });
+        ByteArrayInputStream bis2 = new ByteArrayInputStream(
+                new byte[] { 5, 6, 7, 8 });
+        SequenceInputStream sis = new SequenceInputStream(bis1, bis2);
+
+        try {
+            sis.read(null, 0, -1);
+            fail("Expected NullPointerException exception");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        //returns -1 if the stream is closed , do not throw IOException
+        byte[] array = new byte[] { 1, 2, 3, 4 };
+        sis.close();
+        int result = sis.read(array, 0, 5);
+        assertEquals(-1, result);
+
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() throws UnsupportedEncodingException {
+        si = new SequenceInputStream(new ByteArrayInputStream(s1.getBytes("UTF-8")),
+                new ByteArrayInputStream(s2.getBytes("UTF-8")));
+    }
+
+    /**
+     * 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/tests/api/java/io/SerializationStressTest.java b/luni/src/test/java/tests/api/java/io/SerializationStressTest.java
new file mode 100644
index 0000000..ef0e2ff
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/SerializationStressTest.java
@@ -0,0 +1,1022 @@
+/*
+ *  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.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InvalidObjectException;
+import java.io.NotActiveException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.io.StreamCorruptedException;
+import java.io.WriteAbortedException;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.IdentityHashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.PropertyPermission;
+import java.util.Set;
+import java.util.SimpleTimeZone;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TimeZone;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.Vector;
+import libcore.io.Streams;
+
+/**
+ * Automated Test Suite for class java.io.ObjectOutputStream
+ */
+@SuppressWarnings("serial")
+public class SerializationStressTest extends junit.framework.TestCase implements
+        Serializable {
+
+    // protected static final String MODE_XLOAD = "xload";
+
+    // protected static final String MODE_XDUMP = "xdump";
+
+    static final String FOO = "foo";
+
+    static final String MSG_TEST_FAILED = "Failed to write/read/assertion checking: ";
+
+    protected static final boolean DEBUG = false;
+
+    protected static boolean xload = false;
+
+    protected static boolean xdump = false;
+
+    protected static String xFileName = null;
+
+    protected transient int dumpCount = 0;
+
+    protected transient ObjectInputStream ois;
+
+    protected transient ObjectOutputStream oos;
+
+    protected transient ByteArrayOutputStream bao;
+
+    // -----------------------------------------------------------------------------------
+
+    private static class ObjectInputStreamSubclass extends ObjectInputStream {
+        private Vector<Class> resolvedClasses = new Vector<Class>();
+
+        public ObjectInputStreamSubclass(InputStream in) throws IOException,
+                StreamCorruptedException {
+            super(in);
+        }
+
+        public Class<?> resolveClass(ObjectStreamClass osClass)
+                throws IOException, ClassNotFoundException {
+            Class result = super.resolveClass(osClass);
+            resolvedClasses.addElement(result);
+            return result;
+        }
+
+        public Class[] resolvedClasses() {
+            return (Class[]) resolvedClasses.toArray(new Class[resolvedClasses
+                    .size()]);
+        }
+    }
+
+    static final Map<String, String> TABLE = new Hashtable<String, String>();
+
+    static final Map<String, String> MAP = new HashMap<String, String>();
+
+    static final SortedMap<String, String> TREE = new TreeMap<String, String>();
+
+    static final LinkedHashMap<String, String> LINKEDMAP = new LinkedHashMap<String, String>();
+
+    static final LinkedHashSet<String> LINKEDSET = new LinkedHashSet<String>();
+
+    static final IdentityHashMap<String, String> IDENTITYMAP = new IdentityHashMap<String, String>();
+
+    static final List<String> ALIST = Arrays.asList(new String[] { "a", "list", "of",
+            "strings" });
+
+    static final List<String> LIST = new ArrayList<String>(ALIST);
+
+    static final Set<String> SET = new HashSet<String>(Arrays.asList(new String[] { "one",
+            "two", "three" }));
+
+    static final SortedSet<String> SORTSET = new TreeSet<String>(Arrays.asList(new String[] {
+            "one", "two", "three" }));
+
+    static final java.text.DateFormat DATEFORM = java.text.DateFormat
+            .getInstance();
+
+    static final java.text.ChoiceFormat CHOICE = new java.text.ChoiceFormat(
+            "1#one|2#two|3#three");
+
+    static final java.text.NumberFormat NUMBERFORM = java.text.NumberFormat
+            .getInstance();
+
+    static final java.text.MessageFormat MESSAGE = new java.text.MessageFormat(
+            "the time: {0,time} and date {0,date}");
+
+    static final LinkedList<String> LINKEDLIST = new LinkedList<String>(Arrays
+            .asList(new String[] { "a", "linked", "list", "of", "strings" }));
+
+    static final SimpleTimeZone TIME_ZONE = new SimpleTimeZone(3600000,
+            "S-TEST");
+
+    static final Calendar CALENDAR = new GregorianCalendar(TIME_ZONE);
+
+    static {
+        TABLE.put("one", "1");
+        TABLE.put("two", "2");
+        TABLE.put("three", "3");
+        MAP.put("one", "1");
+        MAP.put("two", "2");
+        MAP.put("three", "3");
+        LINKEDMAP.put("one", "1");
+        LINKEDMAP.put("two", "2");
+        LINKEDMAP.put("three", "3");
+        IDENTITYMAP.put("one", "1");
+        IDENTITYMAP.put("two", "2");
+        IDENTITYMAP.put("three", "3");
+        LINKEDSET.add("one");
+        LINKEDSET.add("two");
+        LINKEDSET.add("three");
+        TREE.put("one", "1");
+        TREE.put("two", "2");
+        TREE.put("three", "3");
+        // To make sure they all use the same Calendar
+        CALENDAR.setTimeZone(new SimpleTimeZone(0, "GMT"));
+        CALENDAR.set(1999, Calendar.JUNE, 23, 15, 47, 13);
+        CALENDAR.set(Calendar.MILLISECOND, 553);
+        DATEFORM.setCalendar(CALENDAR);
+        java.text.DateFormatSymbols symbols = new java.text.DateFormatSymbols();
+        symbols.setZoneStrings(new String[][] { { "a", "b", "c", "d", "e" },
+                { "f", "g", "h", "i", "j" } });
+        ((java.text.SimpleDateFormat) DATEFORM).setDateFormatSymbols(symbols);
+        DATEFORM.setNumberFormat(new java.text.DecimalFormat("#.#;'-'#.#"));
+        DATEFORM.setTimeZone(TimeZone.getTimeZone("EST"));
+        ((java.text.DecimalFormat) NUMBERFORM).applyPattern("#.#;'-'#.#");
+        MESSAGE.setFormat(0, DATEFORM);
+        MESSAGE.setFormat(1, DATEFORM);
+    }
+
+    public SerializationStressTest() {
+    }
+
+    public SerializationStressTest(String name) {
+        super(name);
+    }
+
+    public String getDumpName() {
+        return getName() + dumpCount;
+    }
+
+    protected void dump(Object o) throws IOException, ClassNotFoundException {
+        if (dumpCount > 0)
+            setUp();
+        // Dump the object
+        try {
+            oos.writeObject(o);
+        } finally {
+            oos.close();
+        }
+    }
+
+    protected Object dumpAndReload(Object o) throws IOException,
+            ClassNotFoundException {
+        dump(o);
+        return reload();
+    }
+
+    protected InputStream loadStream() throws IOException {
+        // Choose the load stream
+        if (xload || xdump) {
+            // Load from pre-existing file
+            return new FileInputStream(xFileName + "-" + getDumpName() + ".ser");
+        } else {
+            // Just load from memory, we dumped to memory
+            return new ByteArrayInputStream(bao.toByteArray());
+        }
+    }
+
+    protected Object reload() throws IOException, ClassNotFoundException {
+        ois = new ObjectInputStream(loadStream());
+        dumpCount++;
+        try {
+            return ois.readObject();
+        } finally {
+            ois.close();
+        }
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() {
+        try {
+            if (xdump) {
+                oos = new ObjectOutputStream(new FileOutputStream(xFileName
+                        + "-" + getDumpName() + ".ser"));
+            } else {
+                oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
+            }
+        } catch (Exception e) {
+            fail("Exception thrown during setup : " + e.getMessage());
+        }
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    protected void tearDown() {
+        if (oos != null) {
+            try {
+                oos.close();
+            } catch (Exception e) {
+            }
+        }
+    }
+
+    public void test_1_Constructor() throws Exception {
+        // Test for method java.io.ObjectOutputStream(java.io.OutputStream)
+        oos.close();
+        oos = new ObjectOutputStream(new ByteArrayOutputStream());
+        oos.close();
+    }
+
+    public void test_2_close() {
+        // Test for method void java.io.ObjectOutputStream.close()
+        try {
+            oos.close();
+            oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
+            oos.close();
+            oos.writeChar('T');
+            oos.writeObject(FOO);
+            // Writing to a closed stream does not cause problems. This is
+            // the expected behavior
+        } catch (IOException e) {
+            fail("Operation on closed stream threw IOException : "
+                    + e.getMessage());
+        }
+    }
+
+    public void test_3_defaultWriteObject() {
+        // Test for method void java.io.ObjectOutputStream.defaultWriteObject()
+
+        try {
+            oos.defaultWriteObject();
+        } catch (NotActiveException e) {
+            // Correct
+            return;
+        } catch (IOException e) {
+        }
+        fail(
+                "Failed to throw NotActiveException when invoked outside readObject");
+    }
+
+    public void test_4_flush() {
+        // Test for method void java.io.ObjectOutputStream.flush()
+        try {
+            oos.close();
+            oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
+            int size = bao.size();
+            oos.writeByte(127);
+            assertTrue("Data flushed already", bao.size() == size);
+            oos.flush();
+            assertTrue("Failed to flush data", bao.size() > size);
+            // we don't know how many bytes are actually written for 1 byte,
+            // so we test > <before>
+            oos.close();
+            oos = null;
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_5_reset() {
+        // Test for method void java.io.ObjectOutputStream.reset()
+        try {
+            String o = "HelloWorld";
+            oos.writeObject(o);
+            oos.writeObject(o);
+            oos.reset();
+            oos.writeObject(o);
+            ois = new ObjectInputStream(loadStream());
+            ois.close();
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_6_write() {
+        // Test for method void java.io.ObjectOutputStream.write(byte [], int,
+        // int)
+        try {
+            byte[] buf = new byte[255];
+            byte[] output = new byte[255];
+            for (int i = 0; i < output.length; i++)
+                output[i] = (byte) i;
+            oos.write(output, 0, output.length);
+            oos.close();
+            ois = new ObjectInputStream(loadStream());
+            ois.readFully(buf);
+            ois.close();
+            for (int i = 0; i < output.length; i++)
+                if (buf[i] != output[i])
+                    fail("Read incorrect byte: " + i);
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_6a_write() {
+        // Test for method void java.io.ObjectOutputStream.write(byte [], int,
+        // int)
+        try {
+            byte[] buf = new byte[256];
+            byte[] output = new byte[256];
+            for (int i = 0; i < output.length; i++)
+                output[i] = (byte) (i & 0xff);
+            oos.write(output, 0, output.length);
+            oos.close();
+            ois = new ObjectInputStream(loadStream());
+            ois.readFully(buf);
+            ois.close();
+            for (int i = 0; i < output.length; i++)
+                if (buf[i] != output[i])
+                    fail("Read incorrect byte: " + i);
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_7_write() {
+        // Test for method void java.io.ObjectOutputStream.write(int)
+        try {
+            oos.write('T');
+            oos.close();
+            ois = new ObjectInputStream(loadStream());
+            assertEquals("Read incorrect byte", 'T', ois.read());
+            ois.close();
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_8_write() {
+        // Test for method void java.io.ObjectOutputStream.write(byte [])
+        try {
+            byte[] buf = new byte[10];
+            oos.write("HelloWorld".getBytes());
+            oos.close();
+            ois = new ObjectInputStream(loadStream());
+            ois.read(buf, 0, 10);
+            ois.close();
+            assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0, 10)
+            );
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_9_writeBoolean() {
+        // Test for method void java.io.ObjectOutputStream.writeBoolean(boolean)
+        try {
+            oos.writeBoolean(true);
+            oos.close();
+            ois = new ObjectInputStream(loadStream());
+            assertTrue("Wrote incorrect byte value", ois.readBoolean());
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_10_writeByte() {
+        // Test for method void java.io.ObjectOutputStream.writeByte(int)
+        try {
+            oos.writeByte(127);
+            oos.close();
+            ois = new ObjectInputStream(loadStream());
+            assertEquals("Wrote incorrect byte value", 127, ois.readByte());
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_11_writeBytes() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeBytes(java.lang.String)
+        try {
+            byte[] buf = new byte[10];
+            oos.writeBytes("HelloWorld");
+            oos.close();
+            ois = new ObjectInputStream(loadStream());
+            ois.readFully(buf);
+            ois.close();
+            assertEquals("Wrote incorrect bytes value", "HelloWorld", new String(buf, 0, 10, "UTF-8")
+            );
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_12_writeChar() {
+        // Test for method void java.io.ObjectOutputStream.writeChar(int)
+        try {
+            oos.writeChar('T');
+            oos.close();
+            ois = new ObjectInputStream(loadStream());
+            assertEquals("Wrote incorrect char value", 'T', ois.readChar());
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_13_writeChars() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeChars(java.lang.String)
+        try {
+            int avail = 0;
+            char[] buf = new char[10];
+            oos.writeChars("HelloWorld");
+            oos.close();
+            ois = new ObjectInputStream(loadStream());
+            // Number of prim data bytes in stream / 2 to give char index
+            avail = ois.available() / 2;
+            for (int i = 0; i < avail; ++i)
+                buf[i] = ois.readChar();
+            ois.close();
+            assertEquals("Wrote incorrect chars", "HelloWorld", new String(buf, 0, 10)
+            );
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_14_writeDouble() {
+        // Test for method void java.io.ObjectOutputStream.writeDouble(double)
+        try {
+            oos.writeDouble(Double.MAX_VALUE);
+            oos.close();
+            ois = new ObjectInputStream(loadStream());
+            assertTrue("Wrote incorrect double value",
+                    ois.readDouble() == Double.MAX_VALUE);
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_15_writeFloat() {
+        // Test for method void java.io.ObjectOutputStream.writeFloat(float)
+        try {
+            oos.writeFloat(Float.MAX_VALUE);
+            oos.close();
+            ois = new ObjectInputStream(loadStream());
+            assertTrue("Wrote incorrect double value",
+                    ois.readFloat() == Float.MAX_VALUE);
+            ois.close();
+            ois = null;
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_16_writeInt() {
+        // Test for method void java.io.ObjectOutputStream.writeInt(int)
+        try {
+            oos.writeInt(Integer.MAX_VALUE);
+            oos.close();
+            ois = new ObjectInputStream(loadStream());
+            assertTrue("Wrote incorrect double value",
+                    ois.readInt() == Integer.MAX_VALUE);
+            ois.close();
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_17_writeLong() {
+        // Test for method void java.io.ObjectOutputStream.writeLong(long)
+        try {
+            oos.writeLong(Long.MAX_VALUE);
+            oos.close();
+            ois = new ObjectInputStream(loadStream());
+            assertTrue("Wrote incorrect double value",
+                    ois.readLong() == Long.MAX_VALUE);
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_19_writeShort() {
+        // Test for method void java.io.ObjectOutputStream.writeShort(int)
+        try {
+            oos.writeShort(127);
+            oos.close();
+            ois = new ObjectInputStream(loadStream());
+            assertEquals("Wrote incorrect short value", 127, ois.readShort());
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_20_writeUTF() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeUTF(java.lang.String)
+        try {
+            oos.writeUTF("HelloWorld");
+            oos.close();
+            ois = new ObjectInputStream(loadStream());
+            assertEquals("Wrote incorrect UTF value",
+                    "HelloWorld", ois.readUTF());
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_25_available() {
+        try {
+            oos.writeObject(FOO);
+            oos.writeObject(FOO);
+            oos.flush();
+            int available1 = 0;
+            int available2 = 0;
+            Object obj1 = null;
+            Object obj2 = null;
+            ObjectInputStream ois = new ObjectInputStream(loadStream());
+            available1 = ois.available();
+            obj1 = ois.readObject();
+            available2 = ois.available();
+            obj2 = ois.readObject();
+
+            assertEquals("available returned incorrect value", 0, available1);
+            assertEquals("available returned incorrect value", 0, available2);
+
+            assertTrue("available caused incorrect reading", FOO.equals(obj1));
+            assertTrue("available returned incorrect value", FOO.equals(obj2));
+
+        } catch (IOException e) {
+            fail("IOException serializing object : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("Unable to read Object type : " + e.toString());
+        } catch (Error err) {
+            System.out.println("Error " + err);
+            throw err;
+        }
+
+    }
+
+    protected void t_MixPrimitivesAndObjects() throws IOException,
+            ClassNotFoundException {
+        int i = 7;
+        String s1 = "string 1";
+        String s2 = "string 2";
+        byte[] bytes = { 1, 2, 3 };
+
+        oos.writeInt(i);
+        oos.writeObject(s1);
+        oos.writeUTF(s2);
+        oos.writeObject(bytes);
+        oos.close();
+        try {
+            ois = new ObjectInputStream(loadStream());
+
+            int j = ois.readInt();
+            assertTrue("Wrong int :" + j, i == j);
+
+            String l1 = (String) ois.readObject();
+            assertTrue("Wrong obj String :" + l1, s1.equals(l1));
+
+            String l2 = (String) ois.readUTF();
+            assertTrue("Wrong UTF String :" + l2, s2.equals(l2));
+
+            byte[] bytes2 = (byte[]) ois.readObject();
+            assertTrue("Wrong byte[]", Arrays.equals(bytes, bytes2));
+
+        } finally {
+            ois.close();
+        }
+    }
+
+    public void test_resolveClass() {
+        try {
+            oos.writeObject(new Object[] { Integer.class, new Integer(1) });
+            oos.close();
+
+            ois = new ObjectInputStreamSubclass(loadStream());
+            ois.readObject();
+            ois.close();
+        } catch (IOException e1) {
+            fail("IOException : " + e1.getMessage());
+        } catch (ClassNotFoundException e2) {
+            fail("ClassNotFoundException : " + e2.getMessage());
+        }
+
+        Class[] resolvedClasses = ((ObjectInputStreamSubclass) ois)
+                .resolvedClasses();
+        assertEquals("missing resolved", 3, resolvedClasses.length);
+        assertTrue("resolved class 1", resolvedClasses[0] == Object[].class);
+        assertTrue("resolved class 2", resolvedClasses[1] == Integer.class);
+        assertTrue("resolved class 3", resolvedClasses[2] == Number.class);
+    }
+
+    public void test_reset() throws IOException, ClassNotFoundException {
+        oos.reset();
+        oos.writeObject("R");
+        oos.reset();
+        oos.writeByte(24);
+        oos.close();
+
+        DataInputStream dis = new DataInputStream(loadStream());
+        byte[] input = Streams.readFully(dis);
+        byte[] result = new byte[] { (byte) 0xac, (byte) 0xed, (byte) 0,
+                (byte) 5, (byte) 0x79, (byte) 0x74, (byte) 0, (byte) 1,
+                (byte) 'R', (byte) 0x79, (byte) 0x77, (byte) 1, (byte) 24 };
+        assertTrue("incorrect output", Arrays.equals(input, result));
+
+        ois = new ObjectInputStreamSubclass(loadStream());
+        assertEquals("Wrong result from readObject()", "R", ois.readObject());
+        assertEquals("Wrong result from readByte()", 24, ois.readByte());
+        ois.close();
+    }
+
+    private static class ResolveObjectTest implements Serializable {
+        Object field1, field2;
+    }
+
+    private static class ResolveObjectInputStream extends ObjectInputStream {
+        ResolveObjectInputStream(InputStream in)
+                throws StreamCorruptedException, IOException {
+            super(in);
+        }
+
+        public void enableResolve() {
+            enableResolveObject(true);
+        }
+
+        public Object resolveObject(Object obj) {
+            if (obj instanceof Vector) // test_1_resolveObject()
+                return new Hashtable();
+            else if ("abc".equals(obj)) // test_2_resolveObject()
+                return "ABC";
+            else if (obj instanceof String) // test_3_resolveObject()
+                return String.valueOf(((String) obj).length());
+            else if (obj instanceof int[]) // test_4_resolveObject()
+                return new Object[1];
+            else if (obj instanceof Object[] && ((Object[]) obj).length == 2) // test_5_resolveObject()
+                return new char[1];
+            return obj;
+        }
+    }
+
+    public void test_1_resolveObject() {
+        try {
+            ResolveObjectTest obj = new ResolveObjectTest();
+            obj.field1 = new Vector();
+            obj.field2 = obj.field1;
+            oos.writeObject(obj);
+            oos.close();
+            ois = new ResolveObjectInputStream(loadStream());
+            ((ResolveObjectInputStream) ois).enableResolve();
+            ResolveObjectTest result = null;
+            try {
+                result = (ResolveObjectTest) ois.readObject();
+            } catch (ClassNotFoundException e) {
+                fail(e.toString());
+            }
+            assertTrue("Object not resolved",
+                    result.field1 instanceof Hashtable);
+            assertTrue("Second reference not resolved",
+                    result.field1 == result.field2);
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_2_resolveObject() {
+        try {
+            ResolveObjectTest obj = new ResolveObjectTest();
+            obj.field1 = "abc";
+            obj.field2 = obj.field1;
+            oos.writeObject(obj);
+            oos.close();
+            ois = new ResolveObjectInputStream(loadStream());
+            ((ResolveObjectInputStream) ois).enableResolve();
+            ResolveObjectTest result = null;
+            try {
+                result = (ResolveObjectTest) ois.readObject();
+            } catch (ClassNotFoundException e) {
+                fail(e.toString());
+            }
+            assertEquals("String not resolved", "ABC", result.field1);
+            assertTrue("Second reference not resolved",
+                    result.field1 == result.field2);
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_3_resolveObject() {
+        try {
+            ResolveObjectTest obj = new ResolveObjectTest();
+            char[] lchars = new char[70000];
+            obj.field1 = new String(lchars);
+            obj.field2 = obj.field1;
+            oos.writeObject(obj);
+            oos.close();
+            ois = new ResolveObjectInputStream(loadStream());
+            ((ResolveObjectInputStream) ois).enableResolve();
+            ResolveObjectTest result = null;
+            try {
+                result = (ResolveObjectTest) ois.readObject();
+            } catch (ClassNotFoundException e) {
+                fail(e.toString());
+            }
+            assertTrue("Long String not resolved", "70000"
+                    .equals(result.field1));
+            assertTrue("Second reference not resolved",
+                    result.field1 == result.field2);
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_4_resolveObject() {
+        try {
+            ResolveObjectTest obj = new ResolveObjectTest();
+            obj.field1 = new int[5];
+            obj.field2 = obj.field1;
+            oos.writeObject(obj);
+            oos.close();
+            ois = new ResolveObjectInputStream(loadStream());
+            ((ResolveObjectInputStream) ois).enableResolve();
+            ResolveObjectTest result = null;
+            try {
+                result = (ResolveObjectTest) ois.readObject();
+            } catch (ClassNotFoundException e) {
+                fail(e.toString());
+            }
+            Class cl = new Object[0].getClass();
+            assertTrue("int[] not resolved", result.field1.getClass() == cl);
+            assertTrue("Second reference not resolved",
+                    result.field1 == result.field2);
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_5_resolveObject() {
+        try {
+            ResolveObjectTest obj = new ResolveObjectTest();
+            obj.field1 = new Object[2];
+            obj.field2 = obj.field1;
+            oos.writeObject(obj);
+            oos.close();
+            ois = new ResolveObjectInputStream(loadStream());
+            ((ResolveObjectInputStream) ois).enableResolve();
+            ResolveObjectTest result = null;
+            try {
+                result = (ResolveObjectTest) ois.readObject();
+            } catch (ClassNotFoundException e) {
+                fail(e.toString());
+            }
+            Class cl = new char[0].getClass();
+            assertTrue("int[] not resolved", result.field1.getClass() == cl);
+            assertTrue("Second reference not resolved",
+                    result.field1 == result.field2);
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        }
+    }
+
+    static class WriteReplaceTestA implements Serializable {
+        public Object writeReplace() throws ObjectStreamException {
+            return new ReadResolveTestB();
+        }
+    }
+
+    static class WriteReplaceTestB extends WriteReplaceTestA {
+    }
+
+    static class WriteReplaceTestC extends WriteReplaceTestA {
+        public Object writeReplace() throws ObjectStreamException {
+            return new ReadResolveTestC();
+        }
+    }
+
+    static class WriteReplaceTestD implements Serializable {
+        private Object writeReplace() throws ObjectStreamException {
+            return new ReadResolveTestD();
+        }
+    }
+
+    static class WriteReplaceTestE extends WriteReplaceTestD {
+    }
+
+    static class WriteReplaceTestF implements Serializable {
+        int type, readType;
+
+        public WriteReplaceTestF(int type, int readType) {
+            this.type = type;
+            this.readType = readType;
+        }
+
+        public Object writeReplace() throws ObjectStreamException {
+            switch (type) {
+                case 0:
+                    throw new InvalidObjectException("invalid");
+                case 1:
+                    throw new RuntimeException("runtime");
+                case 2:
+                    throw new Error("error");
+                default:
+                    return new ReadResolveTestE(readType);
+            }
+        }
+    }
+
+    static class ReadResolveTestA implements Serializable {
+        public Object readResolve() throws ObjectStreamException {
+            return new ReadResolveTestA();
+        }
+    }
+
+    static class ReadResolveTestB extends ReadResolveTestA {
+    }
+
+    static class ReadResolveTestC implements Serializable {
+        private Object readResolve() throws ObjectStreamException {
+            return new ReadResolveTestB();
+        }
+    }
+
+    static class ReadResolveTestD extends ReadResolveTestC {
+    }
+
+    static class ReadResolveTestE implements Serializable {
+        int type;
+
+        public ReadResolveTestE(int type) {
+            this.type = type;
+        }
+
+        public Object readResolve() throws ObjectStreamException {
+            switch (type) {
+                case 0:
+                    throw new InvalidObjectException("invalid");
+                case 1:
+                    throw new RuntimeException("runtime");
+                case 2:
+                    throw new Error("error");
+                case 3:
+                    return this;
+                default:
+                    return new ReadResolveTestF();
+            }
+        }
+    }
+
+    static class ReadResolveTestF implements Serializable {
+    }
+
+    public void test_1_writeReplace() {
+        try {
+            Vector<Object> v = new Vector<Object>();
+            v.addElement(new WriteReplaceTestA());
+            v.addElement(new WriteReplaceTestB());
+            v.addElement(new WriteReplaceTestB());
+            v.addElement(new WriteReplaceTestC());
+            v.addElement(new WriteReplaceTestD());
+            v.addElement(new WriteReplaceTestE());
+            oos.writeObject(v);
+            oos.close();
+            ois = new ObjectInputStream(loadStream());
+            Vector result = (Vector) ois.readObject();
+            assertTrue("invalid 0 : " + result.elementAt(0), result
+                    .elementAt(0).getClass() == ReadResolveTestA.class);
+            assertTrue("invalid 1 : " + result.elementAt(1), result
+                    .elementAt(1).getClass() == ReadResolveTestA.class);
+            assertTrue("invalid 2 : " + result.elementAt(2), result
+                    .elementAt(2).getClass() == ReadResolveTestA.class);
+            assertTrue("invalid 3 : " + result.elementAt(3), result
+                    .elementAt(3).getClass() == ReadResolveTestB.class);
+            assertTrue("invalid 4 : " + result.elementAt(4), result
+                    .elementAt(4).getClass() == ReadResolveTestD.class);
+            assertTrue("invalid 5 : " + result.elementAt(5), result
+                    .elementAt(5).getClass() == WriteReplaceTestE.class);
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException serializing data : " + e.getMessage());
+        }
+    }
+
+    public void test_2_writeReplace() {
+        try {
+            boolean exception = false;
+            try {
+                oos.writeObject(new WriteReplaceTestF(0, -1));
+            } catch (ObjectStreamException e) {
+                exception = true;
+            }
+            assertTrue("Should throw ObjectStreamException", exception);
+            exception = false;
+            try {
+                oos.writeObject(new WriteReplaceTestF(1, -1));
+            } catch (RuntimeException e) {
+                exception = true;
+            }
+            assertTrue("Should throw RuntimeException", exception);
+            exception = false;
+            try {
+                oos.writeObject(new WriteReplaceTestF(2, -1));
+            } catch (Error e) {
+                exception = true;
+            }
+            assertTrue("Should throw Error", exception);
+
+            oos.writeObject(new WriteReplaceTestF(3, 0));
+            oos.writeObject(new WriteReplaceTestF(3, 1));
+            oos.writeObject(new WriteReplaceTestF(3, 2));
+            WriteReplaceTestF test = new WriteReplaceTestF(3, 3);
+            oos.writeObject(test);
+            oos.writeObject(test);
+            WriteReplaceTestF test2 = new WriteReplaceTestF(3, 4);
+            oos.writeObject(test2);
+            oos.writeObject(test2);
+            oos.close();
+            ois = new ObjectInputStream(loadStream());
+            try {
+                ois.readObject();
+            } catch (WriteAbortedException e) {
+            }
+
+            exception = false;
+            try {
+                ois.readObject();
+            } catch (ObjectStreamException e) {
+                exception = true;
+            }
+            assertTrue("Expected ObjectStreamException", exception);
+            exception = false;
+            try {
+                ois.readObject();
+            } catch (RuntimeException e) {
+                exception = true;
+            }
+            assertTrue("Expected RuntimeException", exception);
+            exception = false;
+            try {
+                ois.readObject();
+            } catch (Error e) {
+                exception = true;
+            }
+            assertTrue("Expected Error", exception);
+
+            Object readE1 = ois.readObject();
+            Object readE2 = ois.readObject();
+            assertTrue("Replaced objects should be identical", readE1 == readE2);
+            Object readF1 = ois.readObject();
+            Object readF2 = ois.readObject();
+            assertTrue("Replaced resolved objects should be identical: "
+                    + readF1 + " " + readF2, readF1 == readF2);
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException serializing data : " + e.getMessage());
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/SerializationStressTest1.java b/luni/src/test/java/tests/api/java/io/SerializationStressTest1.java
new file mode 100644
index 0000000..283e9a1
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/SerializationStressTest1.java
@@ -0,0 +1,1658 @@
+/*
+ *  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.io;
+
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.Vector;
+
+@SuppressWarnings({ "serial", "unused" })
+public class SerializationStressTest1 extends SerializationStressTest {
+
+    // The purpose of these two classes is to test if serialization, when
+    // loading, runs the object's constructor (wrong) or the constructor defined
+    // at the topmost Serializable superclass(correct).
+    static final int INIT_INT_VALUE = 7;
+
+    // HAS to be static class so that our constructor signature will remain
+    // untouched (no synthetic param)
+    private static class SerializationTest implements java.io.Serializable {
+        int anInt = INIT_INT_VALUE;
+
+        public SerializationTest() {
+            super();
+        }
+    }
+
+    static final String INIT_STR_VALUE = "a string that is blortz";
+
+    // HAS to be static class so that our constructor signature will remain
+    // untouched (no synthetic param)
+    private static class SerializationTestSubclass1 extends SerializationTest {
+        String aString = INIT_STR_VALUE;
+
+        public SerializationTestSubclass1() {
+            super();
+            // Just to change default superclass init value
+            anInt = INIT_INT_VALUE / 2;
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+
+    private static class SpecTestSuperClass implements Runnable {
+        protected java.lang.String instVar;
+
+        public void run() {
+        }
+    }
+
+    private static class SpecTest extends SpecTestSuperClass implements
+            Cloneable, Serializable {
+        public java.lang.String instVar1;
+
+        public static java.lang.String staticVar1;
+
+        public static java.lang.String staticVar2;
+
+        {
+            instVar1 = "NonStaticInitialValue";
+        }
+
+        static {
+            staticVar1 = "StaticInitialValue";
+            staticVar1 = new String(staticVar1);
+        }
+
+        public Object method(Object objParam, Object objParam2) {
+            return new Object();
+        }
+
+        public boolean method(boolean bParam, Object objParam) {
+            return true;
+        }
+
+        public boolean method(boolean bParam, Object objParam, Object objParam2) {
+            return true;
+        }
+
+    }
+
+    private static class SpecTestSubclass extends SpecTest {
+        public transient java.lang.String transientInstVar = "transientValue";
+    }
+
+    // -----------------------------------------------------------------------------------
+
+    // This one tests what happens if the read/writeObject methods are defined
+    // Serialization should work fine.
+    private static class ReadWriteObject implements java.io.Serializable {
+        public boolean calledWriteObject = false;
+
+        public boolean calledReadObject = false;
+
+        public ReadWriteObject() {
+            super();
+        }
+
+        private void readObject(java.io.ObjectInputStream in)
+                throws java.io.IOException, ClassNotFoundException {
+            calledReadObject = true;
+            in.readObject();
+        }
+
+        private void writeObject(java.io.ObjectOutputStream out)
+                throws java.io.IOException {
+            calledWriteObject = true;
+            out.writeObject(FOO);
+        }
+    }
+
+    // This one tests what happens if the read/writeObject methods are not
+    // private.
+    // Serialization should fail.
+    private static class PublicReadWriteObject implements java.io.Serializable {
+        public boolean calledWriteObject = false;
+
+        public boolean calledReadObject = false;
+
+        public PublicReadWriteObject() {
+            super();
+        }
+
+        public void readObject(java.io.ObjectInputStream in)
+                throws java.io.IOException, ClassNotFoundException {
+            calledReadObject = true;
+            in.readObject();
+        }
+
+        public void writeObject(java.io.ObjectOutputStream out)
+                throws java.io.IOException {
+            calledWriteObject = true;
+            out.writeObject(FOO);
+        }
+    }
+
+    // This one tests if field names are serialized in the same way (sorting)
+    // across different VMs
+    private static class FieldOrder implements Serializable {
+        String aaa1NonPrimitive = "aaa1";
+
+        int bbb1PrimitiveInt = 5;
+
+        boolean aaa2PrimitiveBoolean = true;
+
+        String bbb2NonPrimitive = "bbb2";
+    }
+
+    // This one tests what happens if you define just readObject, but not
+    // writeObject.
+    // Does it run or not ?
+    private static class JustReadObject implements java.io.Serializable {
+        public boolean calledReadObject = false;
+
+        public JustReadObject() {
+            super();
+        }
+
+        private void readObject(java.io.ObjectInputStream in)
+                throws java.io.IOException, ClassNotFoundException {
+            calledReadObject = true;
+            in.defaultReadObject();
+        }
+    }
+
+    // This one tests what happens if you define just writeObject, but not
+    // readObject.
+    // Does it run or not ?
+    private static class JustWriteObject implements java.io.Serializable {
+        public boolean calledWriteObject = false;
+
+        public JustWriteObject() {
+            super();
+        }
+
+        private void writeObject(java.io.ObjectOutputStream out)
+                throws java.io.IOException, ClassNotFoundException {
+            calledWriteObject = true;
+            out.defaultWriteObject();
+        }
+    }
+
+    // This one tests class-based replacement when dumping
+    private static class ClassBasedReplacementWhenDumping implements
+            java.io.Serializable {
+        public boolean calledReplacement = false;
+
+        public ClassBasedReplacementWhenDumping() {
+            super();
+        }
+
+        private Object writeReplace() {
+            calledReplacement = true;
+            return FOO; // Replacement is a String
+        }
+    }
+
+    // This one tests whether class-based replacement supports multiple levels.
+    // MultipleClassBasedReplacementWhenDumping -> C1 -> C2 -> C3 -> FOO
+    private static class MultipleClassBasedReplacementWhenDumping implements
+            java.io.Serializable {
+        private static class C1 implements java.io.Serializable {
+            private Object writeReplace() {
+                return new C2();
+            }
+        }
+
+        private static class C2 implements java.io.Serializable {
+            private Object writeReplace() {
+                return new C3();
+            }
+        }
+
+        private static class C3 implements java.io.Serializable {
+            private Object writeReplace() {
+                return FOO;
+            }
+        }
+
+        public MultipleClassBasedReplacementWhenDumping() {
+            super();
+        }
+
+        private Object writeReplace() {
+            return new C1();
+        }
+    }
+
+    // This one tests class-based replacement when loading
+    private static class ClassBasedReplacementWhenLoading implements
+            java.io.Serializable {
+        public ClassBasedReplacementWhenLoading() {
+            super();
+        }
+
+        private Object readResolve() {
+            return FOO; // Replacement is a String
+        }
+    }
+
+    // This one tests what happens if a loading-replacement is not
+    // type-compatible with the original object
+    private static class ClassBasedReplacementWhenLoadingViolatesFieldType
+            implements java.io.Serializable {
+        public ClassBasedReplacementWhenLoading classBasedReplacementWhenLoading = new ClassBasedReplacementWhenLoading();
+
+        public ClassBasedReplacementWhenLoadingViolatesFieldType() {
+            super();
+        }
+    }
+
+    // What happens if dumping causes an error and you try to reload ?
+    // Should the load throw the same exception ?
+    private static class MyExceptionWhenDumping1 implements
+            java.io.Serializable {
+        private static class MyException extends java.io.IOException {
+        }
+
+        ;
+
+        // A primitive instance variable exposes a bug in the serialization
+        // spec.
+        // Primitive instance variables are written without primitive data tags
+        // and so are read without checking for tags. If an exception is
+        // written, reading primitive data will just read bytes from the stream
+        // which may be tags
+        public boolean anInstanceVar = false;
+
+        public MyExceptionWhenDumping1() {
+            super();
+        }
+
+        private void readObject(java.io.ObjectInputStream in)
+                throws java.io.IOException, ClassNotFoundException {
+            in.defaultReadObject();
+        }
+
+        private void writeObject(java.io.ObjectOutputStream out)
+                throws java.io.IOException, ClassNotFoundException {
+            throw new MyException();
+        }
+    }
+
+    // What happens if dumping causes an error and you try to reload ?
+    // Should the load throw the same exception ?
+    private static class MyExceptionWhenDumping2 implements
+            java.io.Serializable {
+        private static class MyException extends java.io.IOException {
+        }
+
+        ;
+
+        public Integer anInstanceVar = new Integer(0xA1);
+
+        public MyExceptionWhenDumping2() {
+            super();
+        }
+
+        private void readObject(java.io.ObjectInputStream in)
+                throws java.io.IOException, ClassNotFoundException {
+            in.defaultReadObject();
+        }
+
+        private void writeObject(java.io.ObjectOutputStream out)
+                throws java.io.IOException, ClassNotFoundException {
+            throw new MyException();
+        }
+    }
+
+    // What happens if dumping causes an error (NonSerializable inst var) and
+    // you try to reload ?
+    // Should the load throw the same exception ?
+    private static class NonSerializableExceptionWhenDumping implements
+            java.io.Serializable {
+        public Object anInstanceVar = new Object();
+
+        public NonSerializableExceptionWhenDumping() {
+            super();
+        }
+    }
+
+    // What happens if dumping causes an error (which is not serializable) and
+    // you try to reload ?
+    // Should the load throw the same exception ?
+    private static class MyUnserializableExceptionWhenDumping implements
+            java.io.Serializable {
+        private static class MyException extends java.io.IOException {
+            private Object notSerializable = new Object();
+        }
+
+        ;
+
+        public boolean anInstanceVar = false;
+
+        public MyUnserializableExceptionWhenDumping() {
+            super();
+        }
+
+        private void readObject(java.io.ObjectInputStream in)
+                throws java.io.IOException, ClassNotFoundException {
+            in.defaultReadObject();
+        }
+
+        private void writeObject(java.io.ObjectOutputStream out)
+                throws java.io.IOException, ClassNotFoundException {
+            throw new MyException();
+        }
+    }
+
+    public SerializationStressTest1(String name) {
+        super(name);
+    }
+
+    public void test_18_1_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = "HelloWorld";
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            assertTrue(MSG_TEST_FAILED + objToSave, (((String) objLoaded)
+                    .equals((String) objToSave)));
+
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_2_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = null;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            assertTrue(MSG_TEST_FAILED + objToSave, objLoaded == objToSave);
+
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_3_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            byte[] bytes = { 0, 1, 2, 3 };
+            objToSave = bytes;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(
+                    (byte[]) objLoaded, (byte[]) objToSave));
+
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_4_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            int[] ints = { 0, 1, 2, 3 };
+            objToSave = ints;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(
+                    (int[]) objLoaded, (int[]) objToSave));
+
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            throw err;
+        }
+    }
+
+    public void test_18_5_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+
+            short[] shorts = { 0, 1, 2, 3 };
+            objToSave = shorts;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(
+                    (short[]) objLoaded, (short[]) objToSave));
+
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_6_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            long[] longs = { 0, 1, 2, 3 };
+            objToSave = longs;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(
+                    (long[]) objLoaded, (long[]) objToSave));
+
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_7_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            float[] floats = { 0.0f, 1.1f, 2.2f, 3.3f };
+            objToSave = floats;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(
+                    (float[]) objLoaded, (float[]) objToSave));
+
+        } catch (IOException e) {
+            fail("IOException serializing data: " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_8_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            double[] doubles = { 0.0, 1.1, 2.2, 3.3 };
+            objToSave = doubles;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(
+                    (double[]) objLoaded, (double[]) objToSave));
+
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_9_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            boolean[] booleans = { true, false, false, true };
+            objToSave = booleans;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(
+                    (boolean[]) objLoaded, (boolean[]) objToSave));
+
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : " + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_10_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+
+            String[] strings = { "foo", "bar", "java" };
+            objToSave = strings;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(
+                    (Object[]) objLoaded, (Object[]) objToSave));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("Unable to read Object type: " + e.toString());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_11_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+
+            objToSave = new Object(); // Not serializable
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            boolean passed = false;
+            Throwable t = null;
+            try {
+                objLoaded = dumpAndReload(objToSave);
+            } catch (NotSerializableException ns) {
+                passed = true;
+                t = ns;
+            } catch (Exception wrongExc) {
+                passed = false;
+                t = wrongExc;
+            }
+            assertTrue(
+                    "Failed to throw NotSerializableException when serializing "
+                            + objToSave + " Threw(if non-null) this: " + t,
+                    passed);
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_12_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        try {
+            if (DEBUG)
+                System.out.println("Obj = <mixed>");
+            t_MixPrimitivesAndObjects();
+        } catch (IOException e) {
+            fail("IOException serializing data : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when dumping mixed types");
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_13_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            SerializationTestSubclass1 st = new SerializationTestSubclass1();
+            // Just change the default ivar values
+            st.anInt = Integer.MAX_VALUE;
+            st.aString = FOO;
+            objToSave = st;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // non-serializable inst var has to be initialized from top
+            // constructor
+            assertTrue(
+                    MSG_TEST_FAILED + objToSave,
+                    ((SerializationTestSubclass1) objLoaded).anInt == Integer.MAX_VALUE);
+            // but serialized var has to be restored as it was in the object
+            // when dumped
+            assertTrue(MSG_TEST_FAILED + objToSave,
+                    ((SerializationTestSubclass1) objLoaded).aString
+                            .equals(FOO));
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + "\t->"
+                    + e.toString());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_14_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            SpecTest specTest = new SpecTest();
+            // Just change the default ivar values
+            specTest.instVar = FOO;
+            specTest.instVar1 = specTest.instVar;
+            objToSave = specTest;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // non-serializable inst var has to be initialized from top
+            // constructor
+            assertNull(MSG_TEST_FAILED + objToSave,
+                    ((SpecTest) objLoaded).instVar);
+            // instVar from non-serialized class, cant  be  saved/restored
+            // by serialization but serialized ivar has to be restored as it
+            // was in the object when dumped
+            assertTrue(MSG_TEST_FAILED + objToSave,
+                    ((SpecTest) objLoaded).instVar1.equals(FOO));
+
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + "\t->"
+                    + e.toString());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_15_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            SpecTestSubclass specTestSubclass = new SpecTestSubclass();
+            // Just change the default ivar values
+            specTestSubclass.transientInstVar = FOO;
+            objToSave = specTestSubclass;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // non-serializable inst var cant be saved, and it is not init'ed
+            // from top constructor in this case
+            assertNull(MSG_TEST_FAILED + objToSave,
+                    ((SpecTestSubclass) objLoaded).transientInstVar);
+            // transient slot, cant be saved/restored by serialization
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + "\t->"
+                    + e.toString());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_16_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+
+            String[] strings = new String[2];
+            strings[0] = FOO;
+            strings[1] = (" " + FOO + " ").trim(); // Safe way to get a copy
+            // that is not ==
+            objToSave = strings;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            String[] stringsLoaded = (String[]) objLoaded;
+            // Serialization has to use identity-based table for assigning IDs
+            assertTrue(MSG_TEST_FAILED + objToSave,
+                    !(stringsLoaded[0] == stringsLoaded[1]));
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + "\t->"
+                    + e.toString());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_17_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+
+            ReadWriteObject readWrite = new ReadWriteObject();
+            objToSave = readWrite;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // has to have called the writeObject on the instance to dump
+            assertTrue(MSG_TEST_FAILED + objToSave, readWrite.calledWriteObject);
+            // has to have called the readObject on the instance loaded
+            assertTrue(MSG_TEST_FAILED + objToSave,
+                    ((ReadWriteObject) objLoaded).calledReadObject);
+
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + "\t->"
+                    + e.toString());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_18_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            PublicReadWriteObject publicReadWrite = new PublicReadWriteObject();
+            objToSave = publicReadWrite;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Can't have called the writeObject on the instance to dump
+            assertTrue(MSG_TEST_FAILED + objToSave,
+                    !publicReadWrite.calledWriteObject);
+            // Can't have called the readObject on the instance loaded
+            assertTrue(MSG_TEST_FAILED + objToSave,
+                    !((PublicReadWriteObject) objLoaded).calledReadObject);
+
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + "\t->"
+                    + e.toString());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_19_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            FieldOrder fieldOrder = new FieldOrder();
+            objToSave = fieldOrder;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // This test is only useful for X-loading, so if it managed to
+            // dump&load, we passed the test
+            assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_20_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = Class.forName("java.lang.Integer");
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Classes with the same name are unique, so test for ==
+            assertTrue(MSG_TEST_FAILED + objToSave, objLoaded == objToSave);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_21_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            // Even though instances of java.lang.Object are not Serializable,
+            // instances of java.lang.Class are. So, the object
+            // java.lang.Object.class
+            // should be serializable
+            objToSave = Class.forName("java.lang.Object");
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Classes with the same name are unique, so test for ==
+            assertTrue(MSG_TEST_FAILED + objToSave, objLoaded == objToSave);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_22_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            java.net.URL url = new java.net.URL("http://localhost/a.txt");
+            objToSave = url;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            assertTrue("URLs are not the same: " + url + "\t,\t" + objLoaded,
+                    url.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_23_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+
+            JustReadObject justReadObject = new JustReadObject();
+            objToSave = justReadObject;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Only calls readObject on the instance loaded if writeObject was
+            // also defined
+            assertTrue("Called readObject on an object without a writeObject",
+                    !((JustReadObject) objLoaded).calledReadObject);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_24_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+
+            JustWriteObject justWriteObject = new JustWriteObject();
+            objToSave = justWriteObject;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Call writeObject on the instance even if it does not define
+            // readObject
+            assertTrue(MSG_TEST_FAILED + objToSave,
+                    justWriteObject.calledWriteObject);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_25_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            Vector<String> vector = new Vector<String>(1);
+            vector.add(FOO);
+            objToSave = vector;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have the string there
+            assertTrue(MSG_TEST_FAILED + objToSave, FOO
+                    .equals(((java.util.Vector) objLoaded).elementAt(0)));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            throw err;
+        }
+    }
+
+    public void test_18_26_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            Hashtable<String, String> hashTable = new Hashtable<String, String>(
+                    5);
+            hashTable.put(FOO, FOO);
+            objToSave = hashTable;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            java.util.Hashtable loadedHashTable = (java.util.Hashtable) objLoaded;
+            // Has to have the key/value there (FOO -> FOO)
+            assertTrue(MSG_TEST_FAILED + objToSave, FOO.equals(loadedHashTable
+                    .get(FOO)));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            throw err;
+        }
+    }
+
+    public void test_18_27_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            ClassBasedReplacementWhenDumping classBasedReplacementWhenDumping = new ClassBasedReplacementWhenDumping();
+            objToSave = classBasedReplacementWhenDumping;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have run the replacement method
+            assertTrue("Did not run writeReplace",
+                    classBasedReplacementWhenDumping.calledReplacement);
+
+            // Has to have loaded a String (replacement object)
+            assertTrue("Did not replace properly", FOO.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_28_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            MultipleClassBasedReplacementWhenDumping multipleClassBasedReplacementWhenDumping = new MultipleClassBasedReplacementWhenDumping();
+            objToSave = multipleClassBasedReplacementWhenDumping;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have loaded a String (replacement object)
+            assertTrue(
+                    "Executed multiple levels of replacement (see PR 1F9RNT1), loaded= "
+                            + objLoaded,
+                    objLoaded instanceof MultipleClassBasedReplacementWhenDumping.C1);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.toString());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_29_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            ClassBasedReplacementWhenLoading classBasedReplacementWhenLoading = new ClassBasedReplacementWhenLoading();
+            objToSave = classBasedReplacementWhenLoading;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have loaded a String (replacement object)
+            assertTrue("Did not run readResolve", FOO.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_30_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            ClassBasedReplacementWhenLoadingViolatesFieldType classBasedReplacementWhenLoadingViolatesFieldType = new ClassBasedReplacementWhenLoadingViolatesFieldType();
+            objToSave = classBasedReplacementWhenLoadingViolatesFieldType;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // We cannot gere here, the load replacement must have caused a
+            // field type violation
+            fail(
+                    "Loading replacements can cause field type violation in this implementation");
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (ClassCastException e) {
+            assertTrue(
+                    "Loading replacements can NOT cause field type violation in this implementation",
+                    true);
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_31_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            MyExceptionWhenDumping1 exceptionWhenDumping = new MyExceptionWhenDumping1();
+            objToSave = exceptionWhenDumping;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            boolean causedException = false;
+            try {
+                dump(objToSave);
+            } catch (MyExceptionWhenDumping1.MyException e) {
+                causedException = true;
+            }
+            ;
+            assertTrue("Should have caused an exception when dumping",
+                    causedException);
+            causedException = false;
+            try {
+                objLoaded = reload();
+                // Although the spec says we should get a WriteAbortedException,
+                // the serialization format handle an Exception when reading
+                // primitive data so we get ClassCastException instead
+            } catch (ClassCastException e) {
+                causedException = true;
+            }
+            ;
+            assertTrue("Should have caused a ClassCastException when loading",
+                    causedException);
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_32_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            MyExceptionWhenDumping2 exceptionWhenDumping = new MyExceptionWhenDumping2();
+            objToSave = exceptionWhenDumping;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            boolean causedException = false;
+            try {
+                dump(objToSave);
+            } catch (MyExceptionWhenDumping2.MyException e) {
+                causedException = true;
+            }
+            ;
+            assertTrue("Should have caused an exception when dumping",
+                    causedException);
+            causedException = false;
+            try {
+                objLoaded = reload();
+            } catch (java.io.WriteAbortedException e) {
+                causedException = true;
+            }
+            ;
+            assertTrue(
+                    "Should have caused a java.io.WriteAbortedException when loading",
+                    causedException);
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (ClassCastException e) {
+            fail("ClassCastException : " + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            throw err;
+        }
+    }
+
+    public void test_NonSerializableExceptionWhenDumping() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            NonSerializableExceptionWhenDumping nonSerializableExceptionWhenDumping = new NonSerializableExceptionWhenDumping();
+            objToSave = nonSerializableExceptionWhenDumping;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            boolean causedException = false;
+            try {
+                dump(objToSave);
+            } catch (java.io.NotSerializableException e) {
+                causedException = true;
+            }
+            ;
+            assertTrue("Should have caused an exception when dumping",
+                    causedException);
+            causedException = false;
+            try {
+                objLoaded = reload();
+            } catch (java.io.WriteAbortedException e) {
+                causedException = true;
+            }
+            ;
+            assertTrue(
+                    "Should have caused a java.io.WriteAbortedException when loading",
+                    causedException);
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_33_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            MyUnserializableExceptionWhenDumping exceptionWhenDumping = new MyUnserializableExceptionWhenDumping();
+            objToSave = exceptionWhenDumping;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            boolean causedException = false;
+            try {
+                dump(objToSave);
+            } catch (java.io.StreamCorruptedException e) {
+                causedException = true;
+            }
+            ;
+            assertTrue("Should have caused an exception when dumping",
+                    causedException);
+            // As the stream is corrupted, reading the stream will have
+            // undefined results
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_34_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            java.io.IOException ioe = new java.io.IOException();
+            objToSave = ioe;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to be able to save/load an exception
+            assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_35_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = Class.forName("java.util.Hashtable");
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Classes with the same name are unique, so test for ==
+            assertTrue(MSG_TEST_FAILED + objToSave, objLoaded == objToSave);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_36_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            java.io.IOException ex = new java.io.InvalidClassException(FOO);
+            objToSave = ex;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to be able to save/load an exception
+            assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_37_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            java.io.IOException ex = new java.io.InvalidObjectException(FOO);
+            objToSave = ex;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to be able to save/load an exception
+            assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_38_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            java.io.IOException ex = new java.io.NotActiveException(FOO);
+            objToSave = ex;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to be able to save/load an exception
+            assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_39_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            java.io.IOException ex = new java.io.NotSerializableException(FOO);
+            objToSave = ex;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to be able to save/load an exception
+            assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_40_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            java.io.IOException ex = new java.io.StreamCorruptedException(FOO);
+            objToSave = ex;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to be able to save/load an exception
+            assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/SerializationStressTest2.java b/luni/src/test/java/tests/api/java/io/SerializationStressTest2.java
new file mode 100644
index 0000000..2e6beee
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/SerializationStressTest2.java
@@ -0,0 +1,2108 @@
+/*
+ *  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.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InvalidClassException;
+import java.io.NotActiveException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.ObjectStreamConstants;
+import java.io.ObjectStreamField;
+import java.io.OptionalDataException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Locale;
+
+
+@SuppressWarnings({ "serial", "unused" })
+public class SerializationStressTest2 extends SerializationStressTest {
+
+    private static class ReadWriteObjectAndPrimitiveData implements
+            java.io.Serializable {
+        transient long milliseconds;
+
+        public boolean calledWriteObject = false;
+
+        public boolean calledReadObject = false;
+
+        public ReadWriteObjectAndPrimitiveData() {
+            super();
+        }
+
+        private void readObject(java.io.ObjectInputStream in)
+                throws java.io.IOException, ClassNotFoundException {
+            in.defaultReadObject();
+            // This *has* to come after the call to defaultReadObject or the
+            // value from the stream will override
+            calledReadObject = true;
+            milliseconds = in.readLong();
+        }
+
+        private void writeObject(java.io.ObjectOutputStream out)
+                throws java.io.IOException {
+            calledWriteObject = true;
+            out.defaultWriteObject();
+            out.writeLong(milliseconds);
+        }
+    }
+
+    // What happens if a class defines serialPersistentFields that do not match
+    // real fields but does not override read/writeObject
+    private static class WithUnmatchingSerialPersistentFields implements
+            java.io.Serializable {
+        private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
+                "value", String.class) };
+
+        public int anInstanceVar = 5;
+
+        public WithUnmatchingSerialPersistentFields() {
+            super();
+        }
+    }
+
+    // What happens if a class defines serialPersistentFields which match actual
+    // fields
+    private static class WithMatchingSerialPersistentFields implements
+            java.io.Serializable {
+        private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
+                "anInstanceVar", String.class) };
+
+        public String anInstanceVar = FOO + FOO;
+
+        public WithMatchingSerialPersistentFields() {
+            super();
+        }
+    }
+
+    // Tests the oficial behavior for serialPersistentFields
+    private static class SerialPersistentFields implements java.io.Serializable {
+        private static final String SIMULATED_FIELD_NAME = "text";
+
+        private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
+                SIMULATED_FIELD_NAME, String.class) };
+
+        public int anInstanceVar = 5;
+
+        public SerialPersistentFields() {
+            super();
+        }
+
+        private void readObject(java.io.ObjectInputStream in)
+                throws java.io.IOException, ClassNotFoundException {
+            ObjectInputStream.GetField fields = in.readFields();
+            anInstanceVar = Integer.parseInt((String) fields.get(
+                    SIMULATED_FIELD_NAME, "-5"));
+        }
+
+        private void writeObject(java.io.ObjectOutputStream out)
+                throws java.io.IOException, ClassNotFoundException {
+            ObjectOutputStream.PutField fields = out.putFields();
+            fields.put(SIMULATED_FIELD_NAME, Integer.toString(anInstanceVar));
+            out.writeFields();
+        }
+    }
+
+    // Tests the behavior for serialPersistentFields when no fields are actually
+    // set
+    private static class WriteFieldsWithoutFetchingPutFields implements
+            java.io.Serializable {
+        private static final String SIMULATED_FIELD_NAME = "text";
+
+        private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
+                SIMULATED_FIELD_NAME, String.class) };
+
+        public int anInstanceVar = 5;
+
+        public WriteFieldsWithoutFetchingPutFields() {
+            super();
+        }
+
+        private void readObject(java.io.ObjectInputStream in)
+                throws java.io.IOException, ClassNotFoundException {
+            ObjectInputStream.GetField fields = in.readFields();
+        }
+
+        private void writeObject(java.io.ObjectOutputStream out)
+                throws java.io.IOException, ClassNotFoundException {
+            out.writeFields();
+        }
+    }
+
+    // Tests what happens if one asks for PutField/getField when the class does
+    // not declare one
+    private static class SerialPersistentFieldsWithoutField implements
+            java.io.Serializable {
+        public int anInstanceVar = 5;
+
+        public SerialPersistentFieldsWithoutField() {
+            super();
+        }
+
+        private void readObject(java.io.ObjectInputStream in)
+                throws java.io.IOException, ClassNotFoundException {
+            ObjectInputStream.GetField fields = in.readFields();
+        }
+
+        private void writeObject(java.io.ObjectOutputStream out)
+                throws java.io.IOException, ClassNotFoundException {
+            ObjectOutputStream.PutField fields = out.putFields();
+            out.writeFields();
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+
+    // writeObject writes extra primitive types and objects which readObject
+    // does not consume. Have to make sure we can load object properly AND
+    // object after it (to show the extra byte[] is consumed)
+    private static class OptionalDataNotRead implements java.io.Serializable {
+        private int field1, field2;
+
+        public OptionalDataNotRead() {
+        }
+
+        private static final ObjectStreamField[] serialPersistentFields = {
+                new ObjectStreamField("field1", Integer.TYPE),
+                new ObjectStreamField("field2", Integer.TYPE),
+                new ObjectStreamField("monthLength", byte[].class), };
+
+        private void writeObject(ObjectOutputStream stream) throws IOException {
+            ObjectOutputStream.PutField fields = stream.putFields();
+            fields.put("field1", 1);
+            fields.put("field2", 2);
+            fields.put("monthLength", new byte[] { 7, 8, 9 });
+            stream.writeFields();
+            stream.writeInt(4);
+            byte[] values = new byte[4];
+            values[0] = (byte) 16;
+            values[1] = (byte) 17;
+            values[2] = (byte) 18;
+            values[3] = (byte) 19;
+            stream.writeObject(values);
+        }
+
+        private void readObject(ObjectInputStream stream) throws IOException,
+                ClassNotFoundException {
+            ObjectInputStream.GetField fields = stream.readFields();
+            field1 = fields.get("field1", 0);
+            field2 = fields.get("field1", 0);
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+    private static class NestedPutField implements java.io.Serializable {
+        public OptionalDataNotRead field1;
+
+        public NestedPutField() {
+        }
+
+        private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
+                "field1", OptionalDataNotRead.class), };
+
+        private void writeObject(ObjectOutputStream stream) throws IOException {
+            ObjectOutputStream.PutField fields = stream.putFields();
+            fields.put("field1", new OptionalDataNotRead());
+            stream.writeFields();
+        }
+
+        private void readObject(ObjectInputStream stream) throws IOException,
+                ClassNotFoundException {
+            ObjectInputStream.GetField fields = stream.readFields();
+            field1 = (OptionalDataNotRead) fields.get("field1", null);
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+
+    // This one tests stream-based replacement when dumping
+    private static class StreamBasedReplacementWhenDumping extends
+            java.io.ObjectOutputStream {
+        public boolean calledArrayReplacement = false;
+
+        public boolean calledStringReplacement = false;
+
+        public boolean calledClassReplacement = false;
+
+        public boolean calledObjectStreamClassReplacement = false;
+
+        public StreamBasedReplacementWhenDumping(java.io.OutputStream output)
+                throws java.io.IOException {
+            super(output);
+            enableReplaceObject(true);
+        }
+
+        protected Object replaceObject(Object obj) throws IOException {
+            Class objClass = obj.getClass();
+            if (objClass == String.class)
+                calledStringReplacement = true;
+
+            if (objClass == Class.class)
+                calledClassReplacement = true;
+
+            if (objClass == ObjectStreamClass.class)
+                calledObjectStreamClassReplacement = true;
+
+            if (objClass.isArray())
+                calledArrayReplacement = true;
+
+            return obj;
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+
+    private static class ArrayOfSerializable implements Serializable {
+        private Serializable[] testField = null;
+
+        public ArrayOfSerializable() {
+            testField = new Serializable[2];
+            testField[0] = "Hi";
+            testField[1] = "there!";
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+
+    private static class ClassSubClassTest0 extends java.lang.Object implements
+            java.io.Serializable {
+        String stringVar;
+
+        public ClassSubClassTest0(String init) {
+            stringVar = init;
+        }
+    }
+
+    private static class ClassSubClassTest1 extends ClassSubClassTest0 {
+        String subStringVar;
+
+        public ClassSubClassTest1(String superString, String subString) {
+            super(superString);
+            subStringVar = subString;
+        }
+
+        public boolean equals(Object obj) {
+            if (obj == null)
+                return false;
+            if (!(obj instanceof ClassSubClassTest1))
+                return false;
+
+            ClassSubClassTest1 inst = (ClassSubClassTest1) obj;
+            return inst.subStringVar.equals(this.subStringVar)
+                    && inst.stringVar.equals(this.stringVar);
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+    private static class ConstructorTestA {
+        public String instVar_classA;
+
+        public final static String ConstrA = "Init in Constructor Class A";
+
+        public final static String ConstrB = "Init in Constructor Class B";
+
+        public final static String ConstrC = "Init in Constructor Class C";
+
+        public final static String ChangedC = "Changed before Serialize - Class C";
+
+        public ConstructorTestA() {
+            instVar_classA = ConstrA;
+        }
+    }
+
+    private static class ConstructorTestB extends ConstructorTestA implements
+            java.io.Serializable {
+        public String instVar_classB;
+
+        public ConstructorTestB() {
+            instVar_classA = ConstrB;
+            instVar_classB = ConstrB;
+        }
+    }
+
+    private static class ConstructorTestC extends ConstructorTestB {
+        public String instVar_classC;
+
+        public ConstructorTestC() {
+            instVar_classA = ConstrC;
+            instVar_classB = ConstrC;
+            instVar_classC = ConstrC;
+        }
+
+        public boolean verify(Object obj) {
+            if (obj == null)
+                return false;
+            if (!(obj instanceof ConstructorTestC))
+                return false;
+
+            ConstructorTestC inst = (ConstructorTestC) obj;
+            return inst.instVar_classC.equals(this.instVar_classC)
+                    && inst.instVar_classB.equals(this.instVar_classB)
+                    && inst.instVar_classA.equals(ConstrA);
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+    private static class HashCodeTest implements java.io.Serializable {
+        private boolean serializationUsesHashCode = false;
+
+        public int hashCode() {
+            serializationUsesHashCode = true;
+            return super.hashCode();
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+    private static class InitializerFieldsTest implements java.io.Serializable {
+        public java.lang.String toBeSerialized;
+
+        public static java.lang.String toBeNotSerialized;
+
+        public static java.lang.String toBeNotSerialized2;
+
+        {
+            toBeSerialized = "NonStaticInitialValue";
+        }
+
+        static {
+            toBeNotSerialized = "StaticInitialValue";
+            toBeNotSerialized2 = new String(toBeNotSerialized);
+        }
+
+        public boolean equals(Object obj) {
+            /*
+                * This method is not answering it the objs is equal. It is
+                * answering if the vars have the value that it have to have after
+                * dumping and loading
+                */
+
+            if (obj == null)
+                return false;
+            if (!(obj instanceof InitializerFieldsTest))
+                return false;
+
+            InitializerFieldsTest inst = (InitializerFieldsTest) obj;
+            return inst.toBeSerialized.equals(this.toBeSerialized)
+                    && InitializerFieldsTest.toBeNotSerialized.equals(toBeNotSerialized2);
+        }
+    }
+
+    private static class InitializerFieldsTest2 implements java.io.Serializable {
+        public java.lang.String toBeSerialized;
+
+        public static java.lang.String toBeNotSerialized;
+
+        public static java.lang.String toBeNotSerialized2;
+
+        {
+            toBeSerialized = "NonStaticInitialValue";
+        }
+
+        public java.lang.String toBeSerialized3;
+
+        public java.lang.String toBeSerialized4;
+
+        static {
+            toBeNotSerialized = "StaticInitialValue";
+            toBeNotSerialized2 = new String(toBeNotSerialized);
+        }
+
+        public java.lang.String toBeSerialized5;
+
+        public boolean equals(Object obj) {
+            /*
+                * This method is not answering it the objs is equal. It is
+                * answering if the vars have the value that it have to have after
+                * dumping and loading
+                */
+
+            if (obj == null)
+                return false;
+            if (!(obj instanceof InitializerFieldsTest2))
+                return false;
+
+            InitializerFieldsTest2 inst = (InitializerFieldsTest2) obj;
+            return inst.toBeSerialized.equals(this.toBeSerialized)
+                    && inst.toBeSerialized3.equals(this.toBeSerialized3)
+                    && inst.toBeSerialized4.equals(this.toBeSerialized4)
+                    && inst.toBeSerialized5.equals(this.toBeSerialized5)
+                    && InitializerFieldsTest2.toBeNotSerialized.equals(toBeNotSerialized2);
+        }
+    }
+
+    private static class InitializerFieldsTest3 extends InitializerFieldsTest2
+            implements java.io.Serializable {
+        public java.lang.String sub_toBeSerialized;
+
+        public static java.lang.String sub_toBeNotSerialized;
+
+        public static java.lang.String sub_toBeNotSerialized2;
+
+        {
+            sub_toBeSerialized = "NonStaticInitialValue";
+        }
+
+        public java.lang.String sub_toBeSerialized3;
+
+        public java.lang.String sub_toBeSerialized4;
+
+        static {
+            sub_toBeNotSerialized = "StaticInitialValue";
+            sub_toBeNotSerialized2 = new String(sub_toBeNotSerialized);
+        }
+
+        public java.lang.String sub_toBeSerialized5;
+
+        public boolean equals(Object obj) {
+            /*
+                * This method is not answering it the objs is equal. It is
+                * answering if the vars have the value that it have to have after
+                * dumping and loading
+                */
+
+            if (!super.equals(obj))
+                return false;
+            if (!(obj instanceof InitializerFieldsTest3))
+                return false;
+
+            InitializerFieldsTest3 inst = (InitializerFieldsTest3) obj;
+            return inst.sub_toBeSerialized.equals(this.sub_toBeSerialized)
+                    && inst.sub_toBeSerialized3
+                    .equals(this.sub_toBeSerialized3)
+                    && inst.sub_toBeSerialized4
+                    .equals(this.sub_toBeSerialized4)
+                    && inst.sub_toBeSerialized5
+                    .equals(this.sub_toBeSerialized5)
+                    && InitializerFieldsTest3.sub_toBeNotSerialized
+                    .equals(sub_toBeNotSerialized2);
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+    private static class DeepNesting implements java.io.Serializable {
+        public float id;
+
+        public DeepNesting next;
+
+        public boolean dump;
+
+        public boolean load;
+
+        public DeepNesting(float id) {
+            this.id = id;
+            next = null;
+            dump = false;
+            load = false;
+        }
+
+        public DeepNesting(int howMany) {
+            DeepNesting prev = new DeepNesting(0.0F);
+            next(prev);
+            for (int i = 1; i < howMany; i++) {
+                prev = prev.next(new DeepNesting(i * 1.0F));
+            }
+        }
+
+        public boolean equals(Object obj) {
+            if (obj == null)
+                return false;
+            if (!(obj instanceof DeepNesting))
+                return false;
+
+            DeepNesting inst = (DeepNesting) obj;
+            if (inst.dump != this.dump || inst.load != this.load)
+                return false;
+
+            if (inst.next == null || this.next == null)
+                return inst.next == this.next; // both null
+            return this.next.equals(inst.next);
+        }
+
+        public DeepNesting next(DeepNesting ivt) {
+            next = ivt;
+            return ivt;
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+    private static class DeepNestingWithWriteObject implements
+            java.io.Serializable {
+        public float id;
+
+        public DeepNestingWithWriteObject next;
+
+        public boolean dump;
+
+        public boolean load;
+
+        public DeepNestingWithWriteObject(float id) {
+            this.id = id;
+            next = null;
+            dump = false;
+            load = false;
+        }
+
+        public DeepNestingWithWriteObject(int howMany) {
+            DeepNestingWithWriteObject prev = new DeepNestingWithWriteObject(
+                    0.0F);
+            next(prev);
+            for (int i = 1; i < howMany; i++) {
+                prev = prev.next(new DeepNestingWithWriteObject(i * 1.0F));
+            }
+        }
+
+        public boolean equals(Object obj) {
+            if (obj == null)
+                return false;
+            if (!(obj instanceof DeepNestingWithWriteObject))
+                return false;
+
+            DeepNestingWithWriteObject inst = (DeepNestingWithWriteObject) obj;
+            if (inst.dump != this.dump || inst.load != this.load)
+                return false;
+
+            if (inst.next == null || this.next == null)
+                return inst.next == this.next; // both null;
+            return this.next.equals(inst.next);
+        }
+
+        public DeepNestingWithWriteObject next(DeepNestingWithWriteObject ivt) {
+            next = ivt;
+            return ivt;
+        }
+
+        private void writeObject(java.io.ObjectOutputStream s)
+                throws IOException {
+            s.defaultWriteObject();
+        }
+
+        private void readObject(java.io.ObjectInputStream s)
+                throws IOException, ClassNotFoundException {
+            s.defaultReadObject();
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+    static class NonPublicClassTest extends java.lang.Object implements
+            java.io.Serializable {
+        int field = 1;
+
+        public NonPublicClassTest() {
+            field = 10;
+        }
+
+        public boolean equals(Object o) {
+            if (o instanceof NonPublicClassTest)
+                return field == ((NonPublicClassTest) o).field;
+            return false;
+        }
+
+        public void x10() {
+            field *= 10;
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+    private static class SameInstVarNameSuperClass {
+        private int foo;
+
+        public SameInstVarNameSuperClass() {
+            super();
+        }
+
+        public SameInstVarNameSuperClass(int fooValue) {
+            foo = fooValue;
+        }
+
+        public String toString() {
+            return "foo = " + foo;
+        }
+    }
+
+    private static class SameInstVarNameSubClass extends
+            SameInstVarNameSuperClass implements java.io.Serializable {
+        protected int foo;
+
+        public SameInstVarNameSubClass() {
+            super();
+        }
+
+        public SameInstVarNameSubClass(int fooValue) {
+            super(-fooValue);
+            foo = fooValue;
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+    private static class SInterfaceTest implements java.io.Serializable {
+        public static int staticVar = 5;
+
+        public transient int[] transVar = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
+
+        public int instanceVar = 7;
+
+        public boolean equals(Object obj) {
+            if (obj == null)
+                return false;
+            if (!(obj instanceof SInterfaceTest))
+                return false;
+
+            SInterfaceTest inst = (SInterfaceTest) obj;
+            if (this.instanceVar != inst.instanceVar)
+                return false;
+            if (inst.transVar == null || this.transVar == null)
+                return inst.transVar == this.transVar; // both null
+            for (int i = 0; i < transVar.length; i++)
+                if (inst.transVar[i] != this.transVar[i])
+                    return false;
+            return true;
+        }
+
+        private void readObject(java.io.ObjectInputStream s)
+                throws IOException, ClassNotFoundException {
+            Object arr;
+            s.defaultReadObject();
+            arr = s.readObject();
+            transVar = (int[]) arr;
+        }
+
+        private void writeObject(java.io.ObjectOutputStream s)
+                throws IOException {
+            s.defaultWriteObject();
+            s.writeObject(transVar);
+        }
+
+        public void x10() {
+            for (int i = 0; i < transVar.length; i++)
+                transVar[i] = transVar[i] * 10;
+            instanceVar = instanceVar * 10;
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+    private static class SInterfaceTest2 extends SInterfaceTest {
+        private void readObject(java.io.ObjectInputStream s)
+                throws IOException, ClassNotFoundException {
+            Object arr;
+            instanceVar = s.readInt();
+            arr = s.readObject();
+            transVar = (int[]) arr;
+        }
+
+        private void writeObject(java.io.ObjectOutputStream s)
+                throws IOException {
+            s.writeInt(instanceVar);
+            s.writeObject(transVar);
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+    private static class SuperclassTest extends java.lang.Object implements
+            java.io.Serializable {
+        int superfield = 1;
+
+        public SuperclassTest() {
+            superfield = 10;
+        }
+
+        public boolean equals(Object o) {
+            if (o.getClass() == this.getClass())
+                return superfield == ((SuperclassTest) o).superfield;
+            return false;
+        }
+
+        private void readObject(java.io.ObjectInputStream s)
+                throws IOException, ClassNotFoundException {
+            superfield = s.readInt();
+        }
+
+        private void writeObject(java.io.ObjectOutputStream s)
+                throws IOException {
+            s.writeInt(superfield);
+        }
+
+        public void x10() {
+            superfield *= 10;
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+    private static class SuperclassTest2 extends SuperclassTest {
+        int subfield = 5;
+
+        public SuperclassTest2() {
+            subfield = 50;
+        }
+
+        public boolean equals(Object o) {
+            if (o instanceof SuperclassTest2)
+                if (subfield == ((SuperclassTest2) o).subfield)
+                    return super.equals(o);
+            return false;
+        }
+
+        private void readObject(java.io.ObjectInputStream s)
+                throws IOException, ClassNotFoundException {
+            subfield = s.readInt();
+        }
+
+        private void writeObject(java.io.ObjectOutputStream s)
+                throws IOException {
+            s.writeInt(subfield);
+        }
+
+        public void x10() {
+            subfield *= 10;
+            super.x10();
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+    private static class SyntheticFieldTest implements java.io.Serializable {
+        public boolean equals(Object obj) {
+            /*
+                * This method is not answering it the objs is equal. It is
+                * answering if the vars have the value that it have to have after
+                * dumping and loading
+                */
+            if (obj == null)
+                return false;
+            return obj instanceof SyntheticFieldTest;
+        }
+
+        public int hashCode() {
+            // Insert code to generate a hash code for the receiver here.
+            // This implementation forwards the message to super. You may
+            // replace or supplement this.
+            // NOTE: if two objects are equal (equals Object) returns true) they
+            // must have the same hash code
+            Class[] c = { String.class }; // *** synthetic field
+            return super.hashCode();
+        }
+    }
+
+    public SerializationStressTest2(String name) {
+        super(name);
+    }
+
+    public void test_18_41_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            java.io.IOException ex = new java.io.WriteAbortedException(FOO,
+                    null);
+            objToSave = ex;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to be able to save/load an exception
+            assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_42_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            WithUnmatchingSerialPersistentFields spf = new WithUnmatchingSerialPersistentFields();
+            objToSave = spf;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            boolean causedException = false;
+            try {
+                objLoaded = dumpAndReload(objToSave);
+            } catch (InvalidClassException ce) {
+                causedException = true;
+            }
+            assertTrue("serialPersistentFields do not match real fields",
+                    causedException);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_43_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            WithMatchingSerialPersistentFields spf = new WithMatchingSerialPersistentFields();
+            spf.anInstanceVar = FOO;
+            objToSave = spf;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            assertTrue(
+                    "serialPersistentFields do not work properly in this implementation",
+                    FOO
+                            .equals(((WithMatchingSerialPersistentFields) objLoaded).anInstanceVar));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_44_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            SerialPersistentFields spf = new SerialPersistentFields();
+            final int CONST = -500;
+            spf.anInstanceVar = CONST;
+            objToSave = spf;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            assertTrue(
+                    "serialPersistentFields do not work properly in this implementation",
+                    ((SerialPersistentFields) objLoaded).anInstanceVar == CONST);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_45_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            WriteFieldsWithoutFetchingPutFields spf = new WriteFieldsWithoutFetchingPutFields();
+            objToSave = spf;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            boolean causedException = false;
+            try {
+                objLoaded = dumpAndReload(objToSave);
+            } catch (NotActiveException ce) {
+                causedException = true;
+            }
+            assertTrue("WriteFieldsWithoutFetchingPutFields", causedException);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_46_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = SerialPersistentFields.class; // Test for 1FA7TA6
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to be able to save/load an exception
+            assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_47_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = ObjectStreamClass.lookup(SerialPersistentFields.class); // Test
+            // for
+            // 1FA7TA6
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to be able to save/load an exception
+            assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_48_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            SerialPersistentFieldsWithoutField spf = new SerialPersistentFieldsWithoutField();
+            final int CONST = -500;
+            spf.anInstanceVar = CONST;
+            objToSave = spf;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            assertTrue(
+                    "serialPersistentFields do not work properly in this implementation",
+                    ((SerialPersistentFieldsWithoutField) objLoaded).anInstanceVar != CONST);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_51_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+
+            ReadWriteObjectAndPrimitiveData readWrite = new ReadWriteObjectAndPrimitiveData();
+            objToSave = readWrite;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // has to have called the writeObject on the instance to dump
+            assertTrue(MSG_TEST_FAILED + objToSave, readWrite.calledWriteObject);
+            // has to have called the readObject on the instance loaded
+            assertTrue(
+                    MSG_TEST_FAILED + objToSave,
+                    ((ReadWriteObjectAndPrimitiveData) objLoaded).calledReadObject);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_52_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+
+            ArrayList list = new ArrayList<String>(Arrays.asList(new String[] { "a",
+                    "list", "of", "strings" }));
+            objToSave = list;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_53_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+
+            objToSave = Locale.CHINESE;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_OptionalDataNotRead() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            OptionalDataNotRead test = new OptionalDataNotRead();
+            // Have to save an object after the one above, and when we read it,
+            // it cannot be a byte[]
+            Date now = new Date();
+            Object[] twoObjects = new Object[2];
+            twoObjects[0] = test;
+            twoObjects[1] = now;
+            objToSave = twoObjects;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            Object[] twoLoadedObjects = (Object[]) objLoaded;
+            assertTrue(MSG_TEST_FAILED + objToSave, twoLoadedObjects[0]
+                    .getClass() == OptionalDataNotRead.class);
+            assertTrue(MSG_TEST_FAILED + objToSave, twoLoadedObjects[1]
+                    .getClass() == Date.class);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_55_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            Object[] threeObjects = new Object[3];
+            threeObjects[0] = new Integer(2);
+            threeObjects[1] = Date.class;
+            threeObjects[2] = threeObjects[0]; // has to be the same
+            objToSave = threeObjects;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            Object[] threeLoadedObjects = (Object[]) objLoaded;
+            assertTrue(MSG_TEST_FAILED + objToSave, threeLoadedObjects[0]
+                    .getClass() == Integer.class);
+            assertTrue(MSG_TEST_FAILED + objToSave,
+                    threeLoadedObjects[1] == Date.class);
+            assertTrue(MSG_TEST_FAILED + objToSave,
+                    threeLoadedObjects[0] == threeLoadedObjects[2]);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_56_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            // Test for 1FD24BY
+            NestedPutField test = new NestedPutField();
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertNotNull(MSG_TEST_FAILED + objToSave,
+                    ((NestedPutField) objLoaded).field1);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_57_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            ByteArrayOutputStream out;
+            StreamBasedReplacementWhenDumping streamBasedReplacementWhenDumping;
+
+            out = new ByteArrayOutputStream();
+            streamBasedReplacementWhenDumping = new StreamBasedReplacementWhenDumping(
+                    out);
+            ;
+            objToSave = FOO.getClass();
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            streamBasedReplacementWhenDumping.writeObject(objToSave);
+            // Has to have run the replacement method
+            assertTrue("Executed replacement when it should not: " + objToSave,
+                    !streamBasedReplacementWhenDumping.calledClassReplacement);
+
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + "\t->"
+                    + e.toString());
+        } catch (Error err) {
+            System.out.println("Error " + err + " when obj = " + objToSave);
+            throw err;
+        }
+    }
+
+    public void test_18_58_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            ByteArrayOutputStream out;
+            StreamBasedReplacementWhenDumping streamBasedReplacementWhenDumping;
+
+            out = new ByteArrayOutputStream();
+            streamBasedReplacementWhenDumping = new StreamBasedReplacementWhenDumping(
+                    out);
+            ;
+            objToSave = ObjectStreamClass.lookup(FOO.getClass());
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            streamBasedReplacementWhenDumping.writeObject(objToSave);
+            // Has to have run the replacement method
+            assertTrue(
+                    "Executed replacement when it should not: " + objToSave,
+                    !streamBasedReplacementWhenDumping.calledObjectStreamClassReplacement);
+
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + "\t->"
+                    + e.toString());
+        } catch (Error err) {
+            System.out.println("Error " + err + " when obj = " + objToSave);
+            throw err;
+        }
+    }
+
+    public void test_18_59_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            ByteArrayOutputStream out;
+            StreamBasedReplacementWhenDumping streamBasedReplacementWhenDumping;
+
+            out = new ByteArrayOutputStream();
+            streamBasedReplacementWhenDumping = new StreamBasedReplacementWhenDumping(
+                    out);
+            ;
+            objToSave = new int[3];
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            streamBasedReplacementWhenDumping.writeObject(objToSave);
+            // Has to have run the replacement method
+            assertTrue("DId not execute replacement when it should: "
+                    + objToSave,
+                    streamBasedReplacementWhenDumping.calledArrayReplacement);
+
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + "\t->"
+                    + e.toString());
+        } catch (Error err) {
+            System.out.println("Error " + err + " when obj = " + objToSave);
+            throw err;
+        }
+    }
+
+    public void test_18_60_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            ByteArrayOutputStream out;
+            StreamBasedReplacementWhenDumping streamBasedReplacementWhenDumping;
+
+            out = new ByteArrayOutputStream();
+            streamBasedReplacementWhenDumping = new StreamBasedReplacementWhenDumping(
+                    out);
+            ;
+            objToSave = FOO;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            streamBasedReplacementWhenDumping.writeObject(objToSave);
+            // Has to have run the replacement method
+            assertTrue("Did not execute replacement when it should: "
+                    + objToSave,
+                    streamBasedReplacementWhenDumping.calledStringReplacement);
+
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + "\t->"
+                    + e.toString());
+        } catch (Error err) {
+            System.out.println("Error " + err + " when obj = " + objToSave);
+            throw err;
+        }
+    }
+
+    public void test_18_61_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            ArrayOfSerializable test = new ArrayOfSerializable();
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, true);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_62_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            ClassSubClassTest1 test = new ClassSubClassTest1(
+                    "SuperInitialString", "SubInitialString");
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_63_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            ConstructorTestC test = new ConstructorTestC();
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, test.verify(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_64_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            HashCodeTest test = new HashCodeTest();
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave,
+                    !((HashCodeTest) objLoaded).serializationUsesHashCode);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_65_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            InitializerFieldsTest test = new InitializerFieldsTest();
+            test.toBeSerialized = "serializing";
+            InitializerFieldsTest.toBeNotSerialized = "It should not have this value after loaded from a File";
+            InitializerFieldsTest.toBeNotSerialized2 = "Good-This is the rigth value.";
+
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            dump(objToSave);
+            InitializerFieldsTest.toBeNotSerialized = new String(
+                    InitializerFieldsTest.toBeNotSerialized2);
+            objLoaded = reload();
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, (test.equals(objLoaded)));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_66_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            InitializerFieldsTest2 test = new InitializerFieldsTest2();
+            test.toBeSerialized = "serializing";
+            test.toBeSerialized3 = "serializing3";
+            test.toBeSerialized4 = "serializing4";
+            test.toBeSerialized5 = "serializing5";
+            InitializerFieldsTest2.toBeNotSerialized = "It should not have this value after loaded from a File";
+            InitializerFieldsTest2.toBeNotSerialized2 = "Good-This is the rigth value.";
+
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            dump(objToSave);
+            InitializerFieldsTest2.toBeNotSerialized = new String(
+                    InitializerFieldsTest2.toBeNotSerialized2);
+            objLoaded = reload();
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, (test.equals(objLoaded)));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_67_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            InitializerFieldsTest3 test = new InitializerFieldsTest3();
+            test.toBeSerialized = "serializing";
+            test.toBeSerialized3 = "serializing3";
+            test.toBeSerialized4 = "serializing4";
+            test.toBeSerialized5 = "serializing5";
+            InitializerFieldsTest2.toBeNotSerialized = "It should not have this value after loaded from a File";
+            InitializerFieldsTest2.toBeNotSerialized2 = "Good-This is the rigth value.";
+            test.sub_toBeSerialized = "serializingSub";
+            test.sub_toBeSerialized3 = "serializing3sub";
+            test.sub_toBeSerialized4 = "serializing4sub";
+            test.sub_toBeSerialized5 = "serializing5sub";
+            InitializerFieldsTest3.sub_toBeNotSerialized = "(Subclass) It should not have this value after loaded from a File";
+            InitializerFieldsTest3.sub_toBeNotSerialized2 = "(Subclass) Good-This is the rigth value.";
+            // Before dumping the two static vars are differents.
+            // After dumping the value of toBeNotSerialized2 is put in
+            // toBeNotSerialized
+            // After loading it must be the same.
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            dump(objToSave);
+            InitializerFieldsTest2.toBeNotSerialized = new String(
+                    InitializerFieldsTest2.toBeNotSerialized2);
+            InitializerFieldsTest3.sub_toBeNotSerialized = new String(
+                    InitializerFieldsTest3.sub_toBeNotSerialized2);
+            objLoaded = reload();
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, (test.equals(objLoaded)));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_DeepNesting() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            DeepNesting test = new DeepNesting(50);
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, (test.equals(objLoaded)));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            // err.printStackTrace();
+            System.out.println("Error " + err + " when obj = " + objToSave);
+            throw err;
+        }
+    }
+
+    public void test_DeepNestingWithWriteObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            DeepNestingWithWriteObject test = new DeepNestingWithWriteObject(50);
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, (test.equals(objLoaded)));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            // err.printStackTrace();
+            System.out.println("Error " + err + " when obj = " + objToSave);
+            throw err;
+        }
+    }
+
+    public void test_18_69_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            NonPublicClassTest test = new NonPublicClassTest();
+            test.x10();
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, (test.equals(objLoaded)));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_70_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            int[] test = new int[1];
+            int intValue = 0;
+            test[0] = intValue;
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(test,
+                    (int[]) objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_71_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            int i, j, maxJ = 3, maxI = 200;
+            byte[][] obj = new byte[maxJ][maxI];
+            for (j = 0; j < maxJ; j++) {
+                for (i = 0; i < maxI; i++)
+                    obj[j][i] = (byte) (i - 100);
+            }
+            objToSave = obj;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            byte[][] toCompare = (byte[][]) objLoaded;
+
+            boolean ok = true;
+            // Has to have worked
+            for (j = 0; j < maxJ; j++) {
+                for (i = 0; i < maxI; i++)
+                    if (obj[j][i] != toCompare[j][i]) {
+                        ok = false;
+                        break;
+                    }
+            }
+
+            assertTrue(MSG_TEST_FAILED + objToSave, ok);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_72_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            int i, j, maxJ = 3, maxI = 200;
+            int[][] obj = new int[maxJ][maxI];
+            for (j = 0; j < maxJ; j++) {
+                for (i = 0; i < maxI; i++)
+                    obj[j][i] = (i - 100);
+            }
+            objToSave = obj;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            int[][] toCompare = (int[][]) objLoaded;
+
+            boolean ok = true;
+            // Has to have worked
+            for (j = 0; j < maxJ; j++) {
+                for (i = 0; i < maxI; i++)
+                    if (obj[j][i] != toCompare[j][i]) {
+                        ok = false;
+                        break;
+                    }
+            }
+
+            assertTrue(MSG_TEST_FAILED + objToSave, ok);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_73_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            String org = "abcdefghijklmnopqrstuvxyz1234567890abcdefghijklmnopqrstuvxyz1234567890";
+            int i, j, maxJ = 3, maxI = 70;
+            String[][] obj = new String[maxJ][maxI];
+            for (j = 0; j < maxJ; j++) {
+                for (i = 0; i < maxI; i++)
+                    obj[j][i] = org.substring(0, i);
+            }
+            objToSave = obj;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            String[][] toCompare = (String[][]) objLoaded;
+
+            boolean ok = true;
+            // Has to have worked
+            for (j = 0; j < maxJ; j++) {
+                for (i = 0; i < maxI; i++)
+                    if (!obj[j][i].equals(toCompare[j][i])) {
+                        ok = false;
+                        break;
+                    }
+            }
+
+            assertTrue(MSG_TEST_FAILED + objToSave, ok);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_74_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            SameInstVarNameSubClass test = new SameInstVarNameSubClass(100);
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave,
+                    ((SameInstVarNameSubClass) objLoaded).foo == 100);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_75_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            SInterfaceTest test = new SInterfaceTest();
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_76_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            SInterfaceTest2 test = new SInterfaceTest2();
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_77_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            SuperclassTest test = new SuperclassTest();
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_78_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            SuperclassTest2 test = new SuperclassTest2();
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_79_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            SyntheticFieldTest test = new SyntheticFieldTest();
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_80_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        try {
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            DataOutputStream dos = new DataOutputStream(out);
+            new ObjectOutputStream(dos); // just to make sure we get a header
+            dos.writeByte(ObjectStreamConstants.TC_BLOCKDATA);
+            int length = 99;
+            dos.writeByte(length);
+            for (int i = 0; i < length; i++) {
+                dos.writeByte(0); // actual value does not matter
+            }
+            dos.flush();
+            int lengthRead = 0;
+            try {
+                ObjectInputStream ois = new ObjectInputStream(
+                        new ByteArrayInputStream(out.toByteArray()));
+                Object obj = ois.readObject();
+            } catch (OptionalDataException e) {
+                lengthRead = e.length;
+            }
+            assertTrue("Did not throw exception with optional data size ",
+                    length == lengthRead);
+        } catch (ClassNotFoundException e) {
+            fail("Unable to read BLOCKDATA: " + e.getMessage());
+        } catch (IOException e) {
+            fail("IOException testing BLOCKDATA : " + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error " + err + " when testing BLOCKDATA");
+            throw err;
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/SerializationStressTest3.java b/luni/src/test/java/tests/api/java/io/SerializationStressTest3.java
new file mode 100644
index 0000000..ff2e258
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/SerializationStressTest3.java
@@ -0,0 +1,1707 @@
+/*
+ *  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.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamConstants;
+import java.io.ObjectStreamField;
+import java.io.OptionalDataException;
+import java.math.BigInteger;
+import java.security.PermissionCollection;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.PropertyPermission;
+import java.util.TimeZone;
+import java.util.Vector;
+
+
+@SuppressWarnings({ "serial", "unused" })
+public class SerializationStressTest3 extends SerializationStressTest {
+
+    // -----------------------------------------------------------------------------------
+    private static class DefaultConstructor implements java.io.Serializable {
+        int f1;
+
+        static int valueAfterConstructor = 5;
+
+        DefaultConstructor() {
+            f1 = valueAfterConstructor;
+        }
+
+        public boolean equals(Object obj) {
+            /*
+                * This method is not answering it the objs is equal. It is
+                * answering if the vars have the value that it have to have after
+                * dumping and loading
+                */
+
+            if (obj == null)
+                return false;
+            if (!(obj instanceof DefaultConstructor))
+                return false;
+
+            DefaultConstructor inst = (DefaultConstructor) obj;
+            return inst.f1 == valueAfterConstructor;
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+    private static class NonSerDefaultConstructor {
+        public int f1;
+
+        public static int valueAfterConstructor = 5;
+
+        NonSerDefaultConstructor() {
+            f1 = valueAfterConstructor;
+        }
+
+        public NonSerDefaultConstructor(String notUsed) {
+        }
+    }
+
+    private static class NonSerPrivateConstructor {
+        public int f1;
+
+        public static int valueAfterConstructor = 5;
+
+        private NonSerPrivateConstructor() {
+            f1 = valueAfterConstructor;
+        }
+
+        public NonSerPrivateConstructor(String notUsed) {
+        }
+    }
+
+    private static class NonSerProtectedConstructor {
+        public int f1;
+
+        public static int valueAfterConstructor = 5;
+
+        protected NonSerProtectedConstructor() {
+            f1 = valueAfterConstructor;
+        }
+    }
+
+    private static class NonSerPublicConstructor {
+        public int f1;
+
+        public static int valueAfterConstructor = 5;
+
+        public NonSerPublicConstructor() {
+            f1 = valueAfterConstructor;
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+    private static class DefaultConstructorSub extends NonSerDefaultConstructor
+            implements java.io.Serializable {
+        int fsub;
+
+        static int subValueAfterConstructor = 11;
+
+        public DefaultConstructorSub() {
+            f1 = 7;
+            fsub = subValueAfterConstructor;
+        }
+
+        public boolean equals(Object obj) {
+            /*
+                * This method is not answering it the objs is equal. It is
+                * answering if the vars have the value that it have to have after
+                * dumping and loading
+                */
+
+            if (obj == null)
+                return false;
+            if (!(obj instanceof DefaultConstructorSub))
+                return false;
+
+            DefaultConstructorSub inst = (DefaultConstructorSub) obj;
+            if (inst.f1 != valueAfterConstructor)
+                return false;
+            return inst.fsub == subValueAfterConstructor;
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+    private static class PrivateConstructor implements java.io.Serializable {
+        int f1;
+
+        static int valueAfterConstructor = 5;
+
+        private PrivateConstructor() {
+            f1 = valueAfterConstructor;
+        }
+
+        public boolean equals(Object obj) {
+            /*
+                * This method is not answering it the objs is equal. Is is
+                * answering if the vars have the value that it have to have after
+                * dumping and loading
+                */
+
+            if (obj == null)
+                return false;
+            if (!(obj instanceof PrivateConstructor))
+                return false;
+
+            PrivateConstructor inst = (PrivateConstructor) obj;
+            return inst.f1 == valueAfterConstructor;
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+    private static class PrivateConstructorSub extends NonSerPrivateConstructor
+            implements java.io.Serializable {
+        int fsub;
+
+        static int subValueAfterConstructor = 11;
+
+        public PrivateConstructorSub() {
+            super("notUsed");
+            f1 = 7;
+            fsub = subValueAfterConstructor;
+        }
+
+        public boolean equals(Object obj) {
+            /*
+                * This method is not answering it the objs is equal. Is is
+                * answering if the vars have the value that it have to have after
+                * dumping and loading
+                */
+
+            if (obj == null)
+                return false;
+            if (!(obj instanceof PrivateConstructorSub))
+                return false;
+
+            PrivateConstructorSub inst = (PrivateConstructorSub) obj;
+            return inst.f1 == valueAfterConstructor
+                    && inst.fsub == subValueAfterConstructor;
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+    private static class ProtectedConstructor implements java.io.Serializable {
+        int f1;
+
+        static int valueAfterConstructor = 5;
+
+        protected ProtectedConstructor() {
+            f1 = valueAfterConstructor;
+        }
+
+        public boolean equals(Object obj) {
+            /*
+                * This method is not answering it the objs is equal. Is is
+                * answering if the vars have the value that it have to have after
+                * dumping and loading
+                */
+
+            if (obj == null)
+                return false;
+            if (!(obj instanceof ProtectedConstructor))
+                return false;
+
+            ProtectedConstructor inst = (ProtectedConstructor) obj;
+            return inst.f1 == valueAfterConstructor;
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+    private static class ProtectedConstructorSub extends
+            NonSerProtectedConstructor implements java.io.Serializable {
+        int fsub;
+
+        static int subValueAfterConstructor = 11;
+
+        public ProtectedConstructorSub() {
+            f1 = 7;
+            fsub = subValueAfterConstructor;
+        }
+
+        public boolean equals(Object obj) {
+            /*
+                * This method is not answering it the objs is equal. Is is
+                * answering if the vars have the value that it have to have after
+                * dumping and loading
+                */
+
+            if (obj == null)
+                return false;
+            if (!(obj instanceof ProtectedConstructorSub))
+                return false;
+
+            ProtectedConstructorSub inst = (ProtectedConstructorSub) obj;
+            return inst.f1 == valueAfterConstructor
+                    && inst.fsub == subValueAfterConstructor;
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+    private static class PublicConstructor implements java.io.Serializable {
+        int f1;
+
+        static int valueAfterConstructor = 5;
+
+        public PublicConstructor() {
+            f1 = valueAfterConstructor;
+        }
+
+        public boolean equals(Object obj) {
+            /*
+                * This method is not answering it the objs is equal. Is is
+                * answering if the vars have the value that it have to have after
+                * dumping and loading
+                */
+
+            if (obj == null)
+                return false;
+            if (!(obj instanceof PublicConstructor))
+                return false;
+
+            PublicConstructor inst = (PublicConstructor) obj;
+            return inst.f1 == valueAfterConstructor;
+        }
+    }
+
+    // -----------------------------------------------------------------------------------
+    private static class PublicConstructorSub extends NonSerPublicConstructor
+            implements java.io.Serializable {
+        int fsub;
+
+        static final int subValueAfterConstructor = 11;
+
+        public PublicConstructorSub() {
+            f1 = 7;
+            fsub = subValueAfterConstructor;
+        }
+
+        public boolean equals(Object obj) {
+            /*
+                * This method is not answering it the objs is equal. It is
+                * answering if the vars have the value that it have to have after
+                * dumping and loading
+                */
+
+            if (obj == null)
+                return false;
+            if (!(obj instanceof PublicConstructorSub))
+                return false;
+
+            PublicConstructorSub inst = (PublicConstructorSub) obj;
+            return inst.f1 == valueAfterConstructor
+                    && inst.fsub == subValueAfterConstructor;
+        }
+    }
+
+    // Tests the behavior of ObjectOutputStream.PutField.write()
+    private static class WriteFieldsUsingPutFieldWrite implements
+            java.io.Serializable {
+        private static final ObjectStreamField[] serialPersistentFields = {
+                new ObjectStreamField("object1", Vector.class),
+                new ObjectStreamField("int1", Integer.TYPE) };
+
+        private static Vector v1 = new Vector<String>(Arrays.asList(new String[] {
+                "1st", "2nd" }));
+
+        private boolean passed = false;
+
+        public WriteFieldsUsingPutFieldWrite() {
+            super();
+        }
+
+        public boolean passed() {
+            return passed;
+        }
+
+        private void readObject(java.io.ObjectInputStream in)
+                throws java.io.IOException, ClassNotFoundException {
+            int int1 = in.readInt();
+            Vector object1 = (Vector) in.readObject();
+            passed = int1 == 0xA9 && object1.equals(v1);
+        }
+
+        @SuppressWarnings("deprecation")
+        private void writeObject(java.io.ObjectOutputStream out)
+                throws java.io.IOException, ClassNotFoundException {
+            ObjectOutputStream.PutField fields = out.putFields();
+            fields.put("object1", v1);
+            fields.put("int1", 0xA9);
+            // Use fields.write() instead of out.writeFields();
+            fields.write(out);
+        }
+    }
+
+    public SerializationStressTest3(String name) {
+        super(name);
+    }
+
+    public void test_18_81_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        try {
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            DataOutputStream dos = new DataOutputStream(out);
+            new ObjectOutputStream(dos); // just to make sure we get a header
+            dos.writeByte(ObjectStreamConstants.TC_BLOCKDATALONG);
+            int length = 333; // Bigger than 1 byte
+            dos.writeInt(length);
+            for (int i = 0; i < length; i++) {
+                dos.writeByte(0); // actual value does not matter
+            }
+            dos.flush();
+            int lengthRead = 0;
+            try {
+                ObjectInputStream ois = new ObjectInputStream(
+                        new ByteArrayInputStream(out.toByteArray()));
+                Object obj = ois.readObject();
+            } catch (OptionalDataException e) {
+                lengthRead = e.length;
+            }
+            assertTrue("Did not throw exception with optional data size ",
+                    length == lengthRead);
+        } catch (ClassNotFoundException e) {
+            fail("Unable to read BLOCKDATA : " + e.getMessage());
+        } catch (IOException e) {
+            fail("IOException testing BLOCKDATALONG : " + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error " + err + " when testing BLOCKDATALONG");
+            throw err;
+        }
+    }
+
+    public void test_18_82_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            DefaultConstructor test = new DefaultConstructor();
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_83_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            DefaultConstructorSub test = new DefaultConstructorSub();
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_84_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            PrivateConstructor test = new PrivateConstructor();
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_85_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            PrivateConstructorSub test = new PrivateConstructorSub();
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_86_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            ProtectedConstructor test = new ProtectedConstructor();
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_87_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            ProtectedConstructorSub test = new ProtectedConstructorSub();
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_88_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            PublicConstructor test = new PublicConstructor();
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_89_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            PublicConstructorSub test = new PublicConstructorSub();
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_90_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = TABLE;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, TABLE.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_91_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            Object col = Collections.synchronizedMap(TABLE);
+            objToSave = col;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_92_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            Object col = Collections.unmodifiableMap(TABLE);
+            objToSave = col;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_93_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = MAP;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, MAP.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_94_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            Object col = Collections.synchronizedMap(MAP);
+            objToSave = col;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_95_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            Object col = Collections.unmodifiableMap(MAP);
+            objToSave = col;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_96_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = ALIST;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, ALIST.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_97_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = LIST;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, LIST.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_98_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            Object col = Collections.synchronizedList(LIST);
+            objToSave = col;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_99_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            Object col = Collections.unmodifiableList(LIST);
+            objToSave = col;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_100_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = SET;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, SET.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_101_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            Object col = Collections.synchronizedSet(SET);
+            objToSave = col;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_102_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            Object col = Collections.unmodifiableSet(SET);
+            objToSave = col;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_103_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = TREE;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, TREE.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_104_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            Object col = Collections.synchronizedSortedMap(TREE);
+            objToSave = col;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_105_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            Object col = Collections.unmodifiableSortedMap(TREE);
+            objToSave = col;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_106_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = SORTSET;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, SET.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_107_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            Object col = Collections.synchronizedSortedSet(SORTSET);
+            objToSave = col;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_108_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            Object col = Collections.unmodifiableSortedSet(SORTSET);
+            objToSave = col;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, col.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_109_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = CALENDAR;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, CALENDAR.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_110_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            TimeZone test = TimeZone.getTimeZone("EST");
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_111_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            TimeZone test = TimeZone.getTimeZone("EST");
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_112_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            TimeZone test = TimeZone.getTimeZone("GMT");
+            objToSave = test;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, test.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_113_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = DATEFORM;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, DATEFORM.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_114_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = CHOICE;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, CHOICE.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_115_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = NUMBERFORM;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, NUMBERFORM
+                    .equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_116_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = MESSAGE;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, MESSAGE.toPattern().equals(
+                    ((java.text.MessageFormat) objLoaded).toPattern()));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_119_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = Locale.CHINESE;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, Locale.CHINESE
+                    .equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_120_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = LINKEDLIST;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, LINKEDLIST
+                    .equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_121_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = java.text.AttributedCharacterIterator.Attribute.INPUT_METHOD_SEGMENT;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(
+                    MSG_TEST_FAILED + objToSave,
+                    java.text.AttributedCharacterIterator.Attribute.INPUT_METHOD_SEGMENT == objLoaded);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_122_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = java.text.AttributedCharacterIterator.Attribute.LANGUAGE;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(
+                    MSG_TEST_FAILED + objToSave,
+                    java.text.AttributedCharacterIterator.Attribute.LANGUAGE == objLoaded);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_123_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = java.text.AttributedCharacterIterator.Attribute.READING;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(
+                    MSG_TEST_FAILED + objToSave,
+                    java.text.AttributedCharacterIterator.Attribute.READING == objLoaded);
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_124_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = new Object[] { Integer.class, new Integer(1) };
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Classes with the same name are unique, so test for ==
+            assertTrue(MSG_TEST_FAILED + objToSave,
+                    ((Object[]) objLoaded)[0] == ((Object[]) objToSave)[0]
+                            && ((Object[]) objLoaded)[1]
+                            .equals(((Object[]) objToSave)[1]));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_125_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = new BigInteger[] { BigInteger.ZERO, BigInteger.ONE,
+                    BigInteger.valueOf(-1), BigInteger.valueOf(255),
+                    BigInteger.valueOf(-255),
+                    new BigInteger("75881644843307850793466070"),
+                    new BigInteger("-636104487142732527326202462") };
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(
+                    (BigInteger[]) objLoaded, (BigInteger[]) objToSave));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_126_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = new WriteFieldsUsingPutFieldWrite();
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            assertTrue(MSG_TEST_FAILED + objToSave,
+                    ((WriteFieldsUsingPutFieldWrite) objLoaded).passed());
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_127_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            BitSet bs = new BitSet(64);
+            bs.set(1);
+            bs.set(10);
+            bs.set(100);
+            bs.set(1000);
+            objToSave = bs;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            assertTrue(MSG_TEST_FAILED + objToSave, bs.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_18_128_writeObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            PropertyPermission test = new PropertyPermission("java.*",
+                    "read,write");
+            PermissionCollection p = test.newPermissionCollection();
+            p.add(new PropertyPermission("java.*", "read"));
+            p.add(new PropertyPermission("java.*", "write"));
+            // System.out.println("Does implies work? " + p.implies(test));
+
+            objToSave = p;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            assertTrue(MSG_TEST_FAILED + objToSave,
+                    ((PermissionCollection) objLoaded).implies(test));
+
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/SerializationStressTest4.java b/luni/src/test/java/tests/api/java/io/SerializationStressTest4.java
new file mode 100644
index 0000000..a26c5ee
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/SerializationStressTest4.java
@@ -0,0 +1,1999 @@
+/*
+ *  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.io;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.cert.Certificate;
+import java.text.DateFormat;
+import java.text.MessageFormat;
+import java.text.NumberFormat;
+import java.util.*;
+
+
+import tests.support.Support_Configuration;
+import tests.support.Support_Proxy_I1;
+
+@SuppressWarnings({ "serial", "unused" })
+public class SerializationStressTest4 extends SerializationStressTest {
+    // -----------------------------------------------------------------------------------
+    private static class GuardImplementation implements java.security.Guard,
+            java.io.Serializable {
+        public GuardImplementation() {
+        }
+
+        public void checkGuard(Object o) {
+        }
+    }
+
+    public SerializationStressTest4(String name) {
+        super(name);
+    }
+
+    public void test_writeObject_EventObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.util.EventObject)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = new java.util.EventObject("Source");
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            boolean equals;
+            equals = true;
+            // The the only data in EventObject that
+            // differentiates between instantiations is transient
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_writeObject_Collections_EmptySet() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.util.Collections.EmptySet)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = java.util.Collections.EMPTY_SET;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            boolean equals;
+            equals = objToSave.equals(objLoaded);
+            if (equals)
+                equals = ((Set) objLoaded).size() == 0;
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Collections_EmptyMap() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.util.Collections.EmptySet)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = java.util.Collections.EMPTY_MAP;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            boolean equals;
+            equals = objToSave.equals(objLoaded);
+            if (equals)
+                equals = ((Map) objLoaded).size() == 0;
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Character() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Character)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = new java.lang.Character('c');
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Collections_UnmodifiableCollection() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.util.Collections.UnmodifiableCollection)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = Collections.unmodifiableCollection(SET);
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            boolean equals;
+            equals = ((java.util.Collection) objToSave).size() == ((java.util.Collection) objLoaded)
+                    .size();
+            if (equals) {
+                java.util.Iterator iter1 = ((java.util.Collection) objToSave)
+                        .iterator(), iter2 = ((java.util.Collection) objLoaded)
+                        .iterator();
+                while (iter1.hasNext())
+                    equals = equals && iter1.next().equals(iter2.next());
+            }
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Format() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.text.Format)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = null;
+            objToSave = new java.text.Format() {
+                String save = "default";
+
+                public StringBuffer format(Object p1, StringBuffer p2,
+                        java.text.FieldPosition p3) {
+                    return new StringBuffer();
+                }
+
+                public Object parseObject(String p1, java.text.ParsePosition p2) {
+                    if (p1 != null)
+                        save = p1;
+                    return save;
+                }
+
+                public boolean equals(Object obj) {
+                    if (!(obj instanceof java.text.Format))
+                        return false;
+                    return save.equals(((java.text.Format) obj).parseObject(
+                            null, null));
+                }
+            };
+
+            ((java.text.Format) objToSave).parseObject("Test", null);
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_writeObject_BigDecimal() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.math.BigDecimal)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = new java.math.BigDecimal("1.2345");
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_SecureRandomSpi() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.security.SecureRandomSpi)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = null;
+            objToSave = new java.security.SecureRandomSpi() {
+                protected byte[] engineGenerateSeed(int p1) {
+                    return new byte[0];
+                }
+
+                protected void engineNextBytes(byte[] p1) {
+                }
+
+                protected void engineSetSeed(byte[] p1) {
+                }
+
+                public boolean equals(Object obj) {
+                    return true;
+                }
+            };
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_writeObject_Short() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Short)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = new java.lang.Short((short) 107);
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Byte() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Byte)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = new java.lang.Byte((byte) 107);
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    @SuppressWarnings("unchecked")
+    public void test_writeObject_String_CaseInsensitiveComparator() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.String.CaseInsensitiveComparator)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = java.lang.String.CASE_INSENSITIVE_ORDER;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            boolean equals;
+            equals = ((Comparator) objToSave).compare("apple", "Banana") == ((Comparator) objLoaded)
+                    .compare("apple", "Banana");
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Calendar() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.util.Calendar)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = new java.util.Calendar(TimeZone.getTimeZone("EST"),
+                    Locale.CANADA) {
+                public void add(int p1, int p2) {
+                }
+
+                protected void computeFields() {
+                }
+
+                protected void computeTime() {
+                }
+
+                public int getGreatestMinimum(int p1) {
+                    return 0;
+                }
+
+                public int getLeastMaximum(int p1) {
+                    return 0;
+                }
+
+                public int getMaximum(int p1) {
+                    return 0;
+                }
+
+                public int getMinimum(int p1) {
+                    return 0;
+                }
+
+                public void roll(int p1, boolean p2) {
+                }
+            };
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + "Calendar", objToSave
+                    .equals(objLoaded));
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_StringBuffer() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.StringBuffer)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = new java.lang.StringBuffer("This is a test.");
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            boolean equals;
+            equals = ((java.lang.StringBuffer) objToSave).toString().equals(
+                    ((java.lang.StringBuffer) objLoaded).toString());
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_File() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.io.File)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = new File("afile.txt");
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_BitSet() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.util.BitSet)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = new java.util.BitSet();
+            ((java.util.BitSet) objToSave).set(3);
+            ((java.util.BitSet) objToSave).set(5);
+            ((java.util.BitSet) objToSave).set(61, 89);
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_DateFormat() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.text.DateFormat)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = null;
+            objToSave = new java.text.DateFormat() {
+                // Thu Feb 01 01:01:01 EST 2001
+                java.util.Date save = new java.util.Date(981007261000L);
+
+                public StringBuffer format(Date p1, StringBuffer p2,
+                        java.text.FieldPosition p3) {
+                    if (p1 != null)
+                        save = p1;
+                    return new StringBuffer(Long.toString(save.getTime()));
+                }
+
+                public Date parse(String p1, java.text.ParsePosition p2) {
+                    return save;
+                }
+
+                public String toString() {
+                    return save.toString();
+                }
+
+                public boolean equals(Object obj) {
+                    if (!(obj instanceof java.text.DateFormat))
+                        return false;
+                    return save.equals(((java.text.DateFormat) obj).parse(null,
+                            null));
+                }
+            };
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Collections_CopiesList() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.util.Collections.CopiesList)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = java.util.Collections.nCopies(2, new Integer(2));
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            boolean equals;
+            equals = ((List) objToSave).get(0)
+                    .equals(((List) objLoaded).get(0));
+            if (equals)
+                equals = ((List) objToSave).get(1).equals(
+                        ((List) objLoaded).get(1));
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Properties() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.util.Properties)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = new java.util.Properties();
+            ((java.util.Properties) objToSave).put("key1", "value1");
+            ((java.util.Properties) objToSave).put("key2", "value2");
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            boolean equals;
+            Enumeration enum1 = ((java.util.Properties) objToSave).elements(), enum2 = ((java.util.Properties) objLoaded)
+                    .elements();
+
+            equals = true;
+            while (enum1.hasMoreElements() && equals) {
+                if (enum2.hasMoreElements())
+                    equals = enum1.nextElement().equals(enum2.nextElement());
+                else
+                    equals = false;
+            }
+
+            if (equals)
+                equals = !enum2.hasMoreElements();
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Collections_UnmodifiableMap_UnmodifiableEntrySet() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.util.Collections.UnmodifiableMap.UnmodifiableEntrySet)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = java.util.Collections.unmodifiableMap(MAP).entrySet();
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            boolean equals;
+            equals = ((java.util.Collection) objToSave).size() == ((java.util.Collection) objLoaded)
+                    .size();
+            if (equals) {
+                java.util.Iterator iter1 = ((java.util.Collection) objToSave)
+                        .iterator(), iter2 = ((java.util.Collection) objLoaded)
+                        .iterator();
+                while (iter1.hasNext())
+                    equals = equals && iter1.next().equals(iter2.next());
+            }
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_NumberFormat() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.text.NumberFormat)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = null;
+            objToSave = new java.text.NumberFormat() {
+                long save = 107;
+
+                public StringBuffer format(double p1, StringBuffer p2,
+                        java.text.FieldPosition p3) {
+                    return new StringBuffer();
+                }
+
+                public StringBuffer format(long p1, StringBuffer p2,
+                        java.text.FieldPosition p3) {
+                    if (p1 != 0)
+                        save = p1;
+                    return new StringBuffer(Long.toString(save));
+                }
+
+                public Number parse(String p1, java.text.ParsePosition p2) {
+                    return new Long(save);
+                }
+
+                public boolean equals(Object obj) {
+                    if (!(obj instanceof java.text.NumberFormat))
+                        return false;
+                    return save == ((Long) ((java.text.NumberFormat) obj)
+                            .parse(null, null)).longValue();
+                }
+            };
+
+            ((java.text.NumberFormat) objToSave).format(63L, null, null);
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_TimeZone() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.util.TimeZone)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = null;
+            objToSave = new java.util.TimeZone() {
+                int save = 0;
+
+                public int getOffset(int p1, int p2, int p3, int p4, int p5,
+                        int p6) {
+                    return 0;
+                }
+
+                public int getRawOffset() {
+                    return save;
+                }
+
+                public boolean inDaylightTime(java.util.Date p1) {
+                    return false;
+                }
+
+                public void setRawOffset(int p1) {
+                    save = p1;
+                }
+
+                public boolean useDaylightTime() {
+                    return false;
+                }
+
+                public boolean equals(Object obj) {
+                    if (obj instanceof TimeZone)
+                        return save == ((TimeZone) obj).getRawOffset();
+                    return false;
+                }
+            };
+
+            ((java.util.TimeZone) objToSave).setRawOffset(48);
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Double() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Double)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = new java.lang.Double(1.23);
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Number() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Number)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = null;
+            objToSave = new Number() {
+                int numCalls = 0;
+
+                public double doubleValue() {
+                    return ++numCalls;
+                }
+
+                public float floatValue() {
+                    return ++numCalls;
+                }
+
+                public int intValue() {
+                    return numCalls;
+                }
+
+                public long longValue() {
+                    return ++numCalls;
+                }
+
+                public boolean equals(Object obj) {
+                    if (!(obj instanceof java.lang.Number))
+                        return false;
+                    return intValue() == ((Number) obj).intValue();
+                }
+            };
+            ((java.lang.Number) objToSave).doubleValue();
+            ((java.lang.Number) objToSave).floatValue();
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Collections_ReverseComparator() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.util.Collections.ReverseComparator)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = java.util.Collections.reverseOrder();
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            boolean equals;
+            equals = ((Comparator) objToSave).compare("Hello", "Jello") == ((Comparator) objLoaded)
+                    .compare("Hello", "Jello");
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+        } catch (IOException e) {
+            fail("IOException serializing " + objToSave + " : "
+                    + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type : "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_DateFormatSymbols() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.text.DateFormatSymbols)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = new java.text.DateFormatSymbols(Locale.CHINESE);
+            ((java.text.DateFormatSymbols) objToSave)
+                    .setZoneStrings(new String[][] { { "a", "b", "c", "d" },
+                            { "e", "f", "g", "h" } });
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Collections_EmptyList() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.util.Collections.EmptyList)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = java.util.Collections.EMPTY_LIST;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            boolean equals;
+            equals = objToSave.equals(objLoaded);
+            if (equals)
+                equals = ((List) objLoaded).size() == 0;
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Boolean() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Boolean)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = new java.lang.Boolean(true);
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Collections_SingletonSet() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.util.Collections.SingletonSet)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = java.util.Collections.singleton(new Byte((byte) 107));
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            boolean equals;
+            java.util.Iterator iter = ((Set) objLoaded).iterator();
+            equals = iter.hasNext();
+            if (equals)
+                equals = iter.next().equals(new Byte((byte) 107));
+            if (equals)
+                equals = !iter.hasNext();
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Collections_SingletonList() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.util.Collections.SingletonSet)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = java.util.Collections
+                    .singletonList(new Byte((byte) 107));
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            boolean equals;
+            java.util.Iterator iter = ((List) objLoaded).iterator();
+            equals = objLoaded.equals(objToSave) && iter.hasNext()
+                    && iter.next().equals(new Byte((byte) 107))
+                    && !iter.hasNext();
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Collections_SingletonMap() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.util.Collections.SingletonSet)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = java.util.Collections.singletonMap("key", new Byte(
+                    (byte) 107));
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            boolean equals;
+            java.util.Iterator iter = ((Map) objLoaded).entrySet().iterator();
+            equals = objLoaded.equals(objToSave) && iter.hasNext();
+            Map.Entry entry = (Map.Entry) iter.next();
+            equals = equals && entry.getKey().equals("key")
+                    && entry.getValue().equals(new Byte((byte) 107))
+                    && !iter.hasNext();
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_SecureRandom() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.security.SecureRandom)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = new java.security.SecureRandom();
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            boolean equals;
+            equals = true; // assume fine because of the nature of the class,
+            // it is difficult to determine if they are the same
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_InetAddress() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.net.InetAddress)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = java.net.InetAddress.getByName("127.0.0.1");
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Inet6Address() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.net.Inet6Address)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = java.net.Inet6Address.getByName("fe80::20d:60ff:fe24:7410");
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Date() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.util.Date)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            // Thu Feb 01 01:01:01 EST 2001
+            objToSave = new java.util.Date(981007261000L);
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Float() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Float)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = new java.lang.Float(1.23f);
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Stack() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.util.Stack)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = new java.util.Stack();
+            ((Stack) objToSave).push("String 1");
+            ((Stack) objToSave).push("String 2");
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            boolean equals;
+            equals = true;
+            while (!((java.util.Stack) objToSave).empty() && equals) {
+                if (!((java.util.Stack) objLoaded).empty())
+                    equals = ((java.util.Stack) objToSave).pop().equals(
+                            ((java.util.Stack) objLoaded).pop());
+                else
+                    equals = false;
+            }
+
+            if (equals)
+                equals = ((java.util.Stack) objLoaded).empty();
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_DecimalFormatSymbols() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.text.DecimalFormatSymbols)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = new java.text.DecimalFormatSymbols(Locale.CHINESE);
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_AttributedCharacterIterator_Attribute() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.text.AttributedCharacterIterator.Attribute)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = java.text.AttributedCharacterIterator.Attribute.LANGUAGE;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_writeObject_Long() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Long)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = new java.lang.Long(107L);
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave.equals(objLoaded));
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Collections_SynchronizedCollection() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.util.Collections.SynchronizedCollection)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = java.util.Collections.synchronizedCollection(SET);
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            boolean equals;
+            equals = ((java.util.Collection) objToSave).size() == ((java.util.Collection) objLoaded)
+                    .size();
+            if (equals) {
+                java.util.Iterator iter1 = ((java.util.Collection) objToSave)
+                        .iterator(), iter2 = ((java.util.Collection) objLoaded)
+                        .iterator();
+                while (iter1.hasNext())
+                    equals = equals && iter1.next().equals(iter2.next());
+            }
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Random() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.util.Random)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = new java.util.Random(107L);
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            boolean equals;
+            equals = ((java.util.Random) objToSave).nextInt() == ((java.util.Random) objLoaded)
+                    .nextInt();
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_GuardedObject() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.security.GuardedObject)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = new java.security.GuardedObject("Test Object",
+                    new GuardImplementation());
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            boolean equals;
+            equals = ((java.security.GuardedObject) objToSave).getObject()
+                    .equals(
+                            ((java.security.GuardedObject) objLoaded)
+                                    .getObject());
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    // TODO : Reintroduce when we have a working security implementation
+    // public void test_writeObject_KeyPair() {
+    // // Test for method void
+    // // java.io.ObjectOutputStream.writeObject(java.security.GuardedObject)
+    //
+    // Object objToSave = null;
+    // Object objLoaded = null;
+    //
+    // try {
+    // objToSave = new java.security.KeyPair(null, null);
+    // if (DEBUG)
+    // System.out.println("Obj = " + objToSave);
+    // objLoaded = dumpAndReload(objToSave);
+    //
+    // // Has to have worked
+    // boolean equals;
+    // equals = true;
+    // assertTrue(MSG_TEST_FAILED + objToSave, equals);
+    // } catch (IOException e) {
+    // fail("IOException serializing " + objToSave + " : "
+    // + e.getMessage());
+    // } catch (ClassNotFoundException e) {
+    // fail("ClassNotFoundException reading Object type : " + e.getMessage());
+    // } catch (Error err) {
+    // System.out.println("Error when obj = " + objToSave);
+    // // err.printStackTrace();
+    // throw err;
+    // }
+    // }
+
+    static class MyInvocationHandler implements InvocationHandler, Serializable {
+        public Object invoke(Object proxy, Method method, Object[] args)
+                throws Throwable {
+            if (method.getName().equals("equals"))
+                return new Boolean(proxy == args[0]);
+            if (method.getName().equals("array"))
+                return new int[] { (int) ((long[]) args[0])[1], -1 };
+            if (method.getName().equals("string")) {
+                if ("error".equals(args[0]))
+                    throw new ArrayStoreException();
+                if ("any".equals(args[0]))
+                    throw new IllegalAccessException();
+            }
+            return null;
+        }
+    }
+
+    public void test_writeObject_Proxy() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.security.GuardedObject)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = Proxy.getProxyClass(Support_Proxy_I1.class
+                    .getClassLoader(), new Class[] { Support_Proxy_I1.class });
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            assertTrue(MSG_TEST_FAILED + "not a proxy class", Proxy
+                    .isProxyClass((Class) objLoaded));
+            Class[] interfaces = ((Class) objLoaded).getInterfaces();
+            assertTrue(MSG_TEST_FAILED + "wrong interfaces length",
+                    interfaces.length == 1);
+            assertTrue(MSG_TEST_FAILED + "wrong interface",
+                    interfaces[0] == Support_Proxy_I1.class);
+
+            InvocationHandler handler = new MyInvocationHandler();
+            objToSave = Proxy.newProxyInstance(Support_Proxy_I1.class
+                    .getClassLoader(), new Class[] { Support_Proxy_I1.class },
+                    handler);
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            boolean equals = Proxy.getInvocationHandler(objLoaded).getClass() == MyInvocationHandler.class;
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_writeObject_URI() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.net.URI)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            try {
+                objToSave = 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"),
+                        // multiple arg constructors
+                        new URI("http", "user%60%20info", "host", 80,
+                                "/a%20path", "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"),
+                        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
+                };
+            } catch (URISyntaxException e) {
+                fail("Unexpected Exception:" + e);
+            }
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, Arrays.equals(
+                    (URI[]) objToSave, (URI[]) objLoaded));
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_writeObject_URISyntaxException() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.net.URISyntaxException)
+
+        URISyntaxException objToSave = null;
+        URISyntaxException objLoaded = null;
+
+        try {
+            objToSave = new URISyntaxException("str", "problem", 4);
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = (URISyntaxException) dumpAndReload(objToSave);
+
+            boolean equals = objToSave.getMessage().equals(
+                    objLoaded.getMessage())
+                    && objToSave.getInput().equals(objLoaded.getInput())
+                    && objToSave.getIndex() == objLoaded.getIndex()
+                    && objToSave.getReason().equals(objLoaded.getReason());
+
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+
+    }
+
+    public void test_writeObject_Currency() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.util.Currency)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = java.util.Currency.getInstance("AMD");
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            // we need same instance for the same currency code
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave == objToSave);
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_writeObject_DateFormat_Field() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.text.DateFormat.Field)
+
+        DateFormat.Field[] objToSave = null;
+        DateFormat.Field[] objLoaded = null;
+
+        try {
+            objToSave = new DateFormat.Field[] { DateFormat.Field.AM_PM,
+                    DateFormat.Field.DAY_OF_MONTH, DateFormat.Field.ERA,
+                    DateFormat.Field.HOUR0, DateFormat.Field.HOUR1,
+                    DateFormat.Field.HOUR_OF_DAY0,
+                    DateFormat.Field.HOUR_OF_DAY1, DateFormat.Field.TIME_ZONE,
+                    DateFormat.Field.YEAR,
+                    DateFormat.Field.DAY_OF_WEEK_IN_MONTH };
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+
+            objLoaded = (DateFormat.Field[]) dumpAndReload(objToSave);
+
+            // Has to have worked
+            // we need same instances for the same field names
+            for (int i = 0; i < objToSave.length; i++) {
+                assertTrue(MSG_TEST_FAILED + objToSave[i],
+                        objToSave[i] == objLoaded[i]);
+            }
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_writeObject_NumberFormat_Field() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.text.NumberFormat.Field)
+
+        NumberFormat.Field[] objToSave = null;
+        NumberFormat.Field[] objLoaded = null;
+
+        try {
+            objToSave = new NumberFormat.Field[] { NumberFormat.Field.CURRENCY,
+                    NumberFormat.Field.DECIMAL_SEPARATOR,
+                    NumberFormat.Field.EXPONENT,
+                    NumberFormat.Field.EXPONENT_SIGN,
+                    NumberFormat.Field.EXPONENT_SYMBOL,
+                    NumberFormat.Field.FRACTION,
+                    NumberFormat.Field.GROUPING_SEPARATOR,
+                    NumberFormat.Field.INTEGER, NumberFormat.Field.PERCENT,
+                    NumberFormat.Field.PERMILLE, NumberFormat.Field.SIGN };
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+
+            objLoaded = (NumberFormat.Field[]) dumpAndReload(objToSave);
+
+            // Has to have worked
+            // we need same instances for the same field names
+            for (int i = 0; i < objToSave.length; i++) {
+                assertTrue(MSG_TEST_FAILED + objToSave[i],
+                        objToSave[i] == objLoaded[i]);
+            }
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_writeObject_MessageFormat_Field() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.text.MessageFormat.Field)
+
+        Object objToSave = null;
+        Object objLoaded = null;
+
+        try {
+            objToSave = MessageFormat.Field.ARGUMENT;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+
+            objLoaded = dumpAndReload(objToSave);
+
+            // Has to have worked
+            // we need same instance for the same field name
+            assertTrue(MSG_TEST_FAILED + objToSave, objToSave == objLoaded);
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_writeObject_LinkedHashMap() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = LINKEDMAP;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, LINKEDMAP.equals(objLoaded));
+
+            Map mapLoaded = (Map) objLoaded;
+            Iterator loadedIterator = mapLoaded.keySet().iterator();
+            Iterator iterator = LINKEDMAP.keySet().iterator();
+            while (loadedIterator.hasNext()) {
+                assertTrue("invalid iterator order", loadedIterator.next()
+                        .equals(iterator.next()));
+            }
+            assertTrue("invalid iterator size", !iterator.hasNext());
+
+            loadedIterator = mapLoaded.entrySet().iterator();
+            iterator = LINKEDMAP.entrySet().iterator();
+            while (loadedIterator.hasNext()) {
+                assertTrue("invalid entry set iterator order", loadedIterator
+                        .next().equals(iterator.next()));
+            }
+            assertTrue("invalid entry set iterator size", !iterator.hasNext());
+
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_writeObject_LinkedHashSet() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        Object objToSave = null;
+        Object objLoaded;
+
+        try {
+            objToSave = LINKEDSET;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = dumpAndReload(objToSave);
+            // Has to have worked
+            assertTrue(MSG_TEST_FAILED + objToSave, LINKEDSET.equals(objLoaded));
+
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+
+    public void test_writeObject_IdentityHashMap() {
+        // Test for method void
+        // java.io.ObjectOutputStream.writeObject(java.lang.Object)
+
+        IdentityHashMap objToSave = null;
+        IdentityHashMap objLoaded;
+
+        try {
+            objToSave = IDENTITYMAP;
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            objLoaded = (IdentityHashMap) dumpAndReload(objToSave);
+            // Has to have worked
+
+            // a serialized identity hash map will not be equal to its original
+            // because it is an "identity" mapping,
+            // so we simply check for the usual meaning of equality
+
+            assertEquals(
+                    "Loaded IdentityHashMap is not of the same size as the saved one.",
+                    objToSave.size(), objLoaded.size());
+            HashMap duplicateSaved = new HashMap();
+            duplicateSaved.putAll(objToSave);
+            HashMap duplicateLoaded = new HashMap();
+            duplicateLoaded.putAll(objLoaded);
+            assertTrue(MSG_TEST_FAILED + duplicateSaved, duplicateSaved
+                    .equals(duplicateLoaded));
+        } catch (IOException e) {
+            fail("Exception serializing " + objToSave + " : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail("ClassNotFoundException reading Object type: "
+                    + e.getMessage());
+        } catch (Error err) {
+            System.out.println("Error when obj = " + objToSave);
+            // err.printStackTrace();
+            throw err;
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/SerializationStressTest5.java b/luni/src/test/java/tests/api/java/io/SerializationStressTest5.java
new file mode 100644
index 0000000..34aaca9
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/SerializationStressTest5.java
@@ -0,0 +1,383 @@
+/*
+ *  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.io;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Vector;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+@SuppressWarnings({ "serial", "unused" })
+public class SerializationStressTest5 extends SerializationStressTest {
+
+    transient Throwable current;
+
+    // Use this for retrieving a list of any Throwable Classes that did not get
+    // tested.
+    transient Vector<Class> missedV = new Vector<Class>();
+
+    transient Class[][] params = new Class[][] { { String.class },
+            { Throwable.class }, { Exception.class },
+            { String.class, Exception.class }, { String.class, int.class },
+            { String.class, String.class, String.class },
+            { String.class, Error.class },
+            { int.class, boolean.class, boolean.class, int.class, int.class },
+            { } };
+
+    transient Object[][] args = new Object[][] {
+            { "message" },
+            { new Throwable() },
+            { new Exception("exception") },
+            { "message", new Exception("exception") },
+            { "message", new Integer(5) },
+            { "message", "message", "message" },
+            { "message", new Error("error") },
+            { new Integer(5), new Boolean(false), new Boolean(false),
+                    new Integer(5), new Integer(5) }, { } };
+
+    public SerializationStressTest5(String name) {
+        super(name);
+    }
+
+    public void test_writeObject_Throwables() {
+        try {
+            oos.close();
+        } catch (IOException e) {
+        }
+
+        File javaDir = findJavaDir();
+
+        Vector<File> classFilesVector = new Vector<File>();
+        if (javaDir != null)
+            findClassFiles(javaDir, classFilesVector);
+        else
+            findClassFilesFromZip(classFilesVector);
+
+        if (classFilesVector.size() == 0) {
+            fail("No Class Files Found.");
+        }
+
+        File[] classFilesArray = new File[classFilesVector.size()];
+        classFilesVector.copyInto(classFilesArray);
+
+        Class[] throwableClasses = findThrowableClasses(classFilesArray);
+        findParam(throwableClasses);
+
+        // Use this to print out the list of Throwable classes that weren't
+        // tested.
+        /*
+           * System.out.println(); Class[] temp = new Class[missedV.size()];
+           * missedV.copyInto(temp); for (int i = 0; i < temp.length; i++)
+           * System.out.println(i+1 + ": " + temp[i].getName());
+           */
+    }
+
+    private File[] makeClassPathArray() {
+        String classPath;
+        if (System.getProperty("java.vendor").startsWith("IBM"))
+            classPath = System.getProperty("org.apache.harmony.boot.class.path");
+        else
+            classPath = System.getProperty("sun.boot.class.path");
+        int instanceOfSep = -1;
+        int nextInstance = classPath.indexOf(File.pathSeparatorChar,
+                instanceOfSep + 1);
+        Vector<File> elms = new Vector<File>();
+        while (nextInstance != -1) {
+            elms.add(new File(classPath.substring(instanceOfSep + 1,
+                    nextInstance)));
+            instanceOfSep = nextInstance;
+            nextInstance = classPath.indexOf(File.pathSeparatorChar,
+                    instanceOfSep + 1);
+        }
+        elms.add(new File(classPath.substring(instanceOfSep + 1)));
+        File[] result = new File[elms.size()];
+        elms.copyInto(result);
+        return result;
+    }
+
+    private File findJavaDir() {
+        File[] files = makeClassPathArray();
+        for (int i = 0; i < files.length; i++) {
+            if (files[i].isDirectory()) {
+                String[] tempFileNames = files[i].list();
+                for (int j = 0; j < tempFileNames.length; j++) {
+                    File tempfile = new File(files[i], tempFileNames[j]);
+                    if (tempfile.isDirectory()
+                            && tempFileNames[j].equals("java")) {
+                        String[] subdirNames = tempfile.list();
+                        for (int k = 0; k < subdirNames.length; k++) {
+                            File subdir = new File(tempfile, subdirNames[k]);
+                            if (subdir.isDirectory()
+                                    && subdirNames[k].equals("lang")) {
+                                return tempfile;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    private void findClassFiles(File dir, Vector<File> v) {
+        String[] classFileNames = dir.list();
+        for (int i = 0; i < classFileNames.length; i++) {
+            File file = new File(dir, classFileNames[i]);
+            if (file.isDirectory())
+                findClassFiles(file, v);
+            else if (classFileNames[i].endsWith(".class"))
+                v.add(file);
+        }
+    }
+
+    private Class[] findThrowableClasses(File[] files) {
+        Class<Throwable> thrClass = Throwable.class;
+        Vector<Class> resultVector = new Vector<Class>();
+        String slash = System.getProperty("file.separator");
+        String begTarget = slash + "java" + slash;
+        String endTarget = ".class";
+        for (int i = 0; i < files.length; i++) {
+            String fileName = files[i].getPath();
+            int instOfBegTarget = fileName.indexOf(begTarget);
+            int instOfEndTarget = fileName.indexOf(endTarget);
+            fileName = fileName.substring(instOfBegTarget + 1, instOfEndTarget);
+            fileName = fileName.replace(slash.charAt(0), '.');
+            try {
+                Class theClass = Class.forName(fileName, false, ClassLoader
+                        .getSystemClassLoader());
+                if (thrClass.isAssignableFrom(theClass)) {
+                    // java.lang.VirtualMachineError is abstract.
+                    // java.io.ObjectStreamException is abstract
+                    // java.beans.PropertyVetoException needs a
+                    // java.beans.PropertyChangeEvent as a parameter
+                    if (!fileName.equals("java.lang.VirtualMachineError")
+                            && !fileName
+                            .equals("java.io.ObjectStreamException")
+                            && !fileName
+                            .equals("java.beans.PropertyVetoException"))
+                        resultVector.add(theClass);
+                }
+            } catch (ClassNotFoundException e) {
+                fail("ClassNotFoundException : " + fileName);
+            }
+        }
+        Class[] result = new Class[resultVector.size()];
+        resultVector.copyInto(result);
+        return result;
+    }
+
+    private void initClass(Class thrC, int num) {
+        Constructor[] cons = thrC.getConstructors();
+        for (int i = 0; i < cons.length; i++) {
+            try {
+                Throwable obj = (Throwable) cons[i].newInstance(args[num]);
+                t_Class(obj, num);
+                break;
+            } catch (IllegalArgumentException e) {
+                // This error should be caught until the correct args is hit.
+            } catch (IllegalAccessException e) {
+                fail(
+                        "IllegalAccessException while creating instance of: "
+                                + thrC.getName());
+            } catch (InstantiationException e) {
+                fail(
+                        "InstantiationException while creating instance of: "
+                                + thrC.getName());
+            } catch (InvocationTargetException e) {
+                fail(
+                        "InvocationTargetException while creating instance of: "
+                                + thrC.getName());
+            }
+            if (i == cons.length - 1) {
+                fail(
+                        "Failed to create newInstance of: " + thrC.getName());
+            }
+        }
+    }
+
+    public String getDumpName() {
+        if (current == null) {
+            dumpCount++;
+            return getName();
+        }
+        return getName() + "_" + current.getClass().getName();
+    }
+
+    private void t_Class(Throwable objToSave, int argsNum) {
+        current = objToSave;
+        Object objLoaded = null;
+        try {
+            if (DEBUG)
+                System.out.println("Obj = " + objToSave);
+            try {
+                objLoaded = dumpAndReload(objToSave);
+            } catch (FileNotFoundException e) {
+                // Must be using xload, ignore missing Throwables
+                System.out.println("Ignoring: "
+                        + objToSave.getClass().getName());
+                return;
+            }
+
+            // Has to have worked
+            boolean equals;
+            equals = objToSave.getClass().equals(objLoaded.getClass());
+            assertTrue(MSG_TEST_FAILED + objToSave, equals);
+            if (argsNum == 0 || (argsNum >= 3 && argsNum <= 7)) {
+                equals = ((Throwable) objToSave).getMessage().equals(
+                        ((Throwable) objLoaded).getMessage());
+                assertTrue("Message Test: " + MSG_TEST_FAILED + objToSave,
+                        equals);
+            } else {
+                // System.out.println(((Throwable)objToSave).getMessage());
+                equals = ((Throwable) objToSave).getMessage() == null;
+                assertTrue("Null Test 1: (args=" + argsNum + ") "
+                        + MSG_TEST_FAILED + objToSave, equals);
+                equals = ((Throwable) objLoaded).getMessage() == null;
+                assertTrue("Null Test 2: (args=" + argsNum + ") "
+                        + MSG_TEST_FAILED + objToSave, equals);
+            }
+        } catch (IOException e) {
+            fail("Unexpected IOException in checkIt() : " + e.getMessage());
+        } catch (ClassNotFoundException e) {
+            fail(e.toString() + " - testing " + objToSave.getClass().getName());
+        }
+    }
+
+    private void findParam(Class[] thrC) {
+        for (int i = 0; i < thrC.length; i++) {
+            Constructor con = null;
+            for (int j = 0; j < params.length; j++) {
+                try {
+                    con = thrC[i].getConstructor(params[j]);
+                } catch (NoSuchMethodException e) {
+                    // This Error will be caught until the right param is found.
+                }
+
+                if (con != null) {
+                    // If the param was found, initialize the Class
+                    initClass(thrC[i], j);
+                    break;
+                }
+                // If the param not found then add to missed Vector.
+                if (j == params.length - 1)
+                    missedV.add(thrC[i]);
+            }
+        }
+    }
+
+    private void findClassFilesFromZip(Vector<File> v) {
+        String slash = System.getProperty("file.separator");
+        String javaHome = System.getProperty("java.home");
+        if (!javaHome.endsWith(slash))
+            javaHome += slash;
+
+        String[] wanted = { "java" + slash + "io", "java" + slash + "lang",
+                "java" + slash + "math", "java" + slash + "net",
+                "java" + slash + "security", "java" + slash + "text",
+                "java" + slash + "util", "java" + slash + "beans",
+                "java" + slash + "rmi",
+                // One or more class files in awt make the VM hang after being
+                // loaded.
+                // "java" + slash + "awt",
+                "java" + slash + "sql",
+                // These are (possibly) all of the throwable classes in awt
+                /*
+             * "java\\awt\\AWTError", "java\\awt\\AWTException",
+             * "java\\awt\\color\\CMMException",
+             * "java\\awt\\color\\ProfileDataException",
+             * "java\\awt\\datatransfer\\MimeTypeParseException",
+             * "java\\awt\\datatransfer\\UnsupportedFlavorException",
+             * "java\\awt\\dnd\\InvalidDnDOperationException",
+             * "java\\awt\\FontFormatException",
+             * "java\\awt\\geom\\IllegalPathStateException",
+             * "java\\awt\\geom\\NoninvertibleTransformException",
+             * "java\\awt\\IllegalComponentStateException",
+             * "java\\awt\\image\\ImagingOpException",
+             * "java\\awt\\image\\RasterFormatException",
+             * "java\\awt\\print\\PrinterAbortException",
+             * "java\\awt\\print\\PrinterException",
+             * "java\\awt\\print\\PrinterIOException"
+             */
+        };
+
+        File[] files = makeClassPathArray();
+        FileInputStream fis = null;
+        ZipInputStream zis = null;
+        ZipEntry ze = null;
+        for (int i = 0; i < files.length; i++) {
+            String fileName = files[i].getPath();
+            if (files[i].exists() && files[i].isFile()
+                    && fileName.endsWith(".jar") || fileName.endsWith(".zip")) {
+                try {
+                    fis = new FileInputStream(files[i].getPath());
+                } catch (FileNotFoundException e) {
+                    fail("FileNotFoundException trying to open "
+                            + files[i].getPath());
+                }
+                zis = new ZipInputStream(fis);
+                while (true) {
+                    try {
+                        ze = zis.getNextEntry();
+                    } catch (IOException e) {
+                        fail("IOException while getting next zip entry: "
+                                + e);
+                    }
+                    if (ze == null)
+                        break;
+                    String zeName = ze.getName();
+                    if (zeName.endsWith(".class")) {
+                        zeName = zeName.replace('/', slash.charAt(0));
+                        for (int j = 0; j < wanted.length; j++) {
+                            if (zeName.startsWith(wanted[j])) {
+                                // When finding class files from directories the
+                                // program saves them as files.
+                                // To stay consistent we will turn the ZipEntry
+                                // classes into instances of files.
+                                File tempF = new File(javaHome + zeName);
+                                // Making sure that the same class is not added
+                                // twice.
+                                boolean duplicate = false;
+                                for (int k = 0; k < v.size(); k++) {
+                                    if (v.get(k).equals(tempF))
+                                        duplicate = true;
+                                }
+                                if (!duplicate)
+                                    v.add(tempF);
+                                break;
+                            }
+                        }
+                    }
+                }
+                ;
+                try {
+                    zis.close();
+                    fis.close();
+                } catch (IOException e) {
+                    fail(
+                            "IOException while trying to close InputStreams: "
+                                    + e);
+                }
+            }
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/StreamCorruptedExceptionTest.java b/luni/src/test/java/tests/api/java/io/StreamCorruptedExceptionTest.java
new file mode 100644
index 0000000..20fce7f
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/StreamCorruptedExceptionTest.java
@@ -0,0 +1,78 @@
+/*
+ *  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.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.ObjectInputStream;
+import java.io.StreamCorruptedException;
+
+public class StreamCorruptedExceptionTest extends junit.framework.TestCase {
+
+    /**
+     * java.io.StreamCorruptedException#StreamCorruptedException()
+     */
+    public void test_Constructor() throws Exception {
+        // Test for method java.io.StreamCorruptedException()
+
+        try {
+            ObjectInputStream ois = new ObjectInputStream(
+                    new ByteArrayInputStream(
+                            "kLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLl"
+                                    .getBytes()));
+            ois.readObject();
+        } catch (StreamCorruptedException e) {
+            // Correct
+            return;
+        }
+
+        fail("Failed to throw StreamCorruptedException for non serialized stream");
+    }
+
+    /**
+     * java.io.StreamCorruptedException#StreamCorruptedException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() throws Exception {
+        // Test for method java.io.StreamCorruptedException(java.lang.String)
+        try {
+            ObjectInputStream ois = new ObjectInputStream(
+                    new ByteArrayInputStream(
+                            "kLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLl"
+                                    .getBytes()));
+            ois.readObject();
+        } catch (StreamCorruptedException e) {
+            // Correct
+            return;
+        }
+
+        fail("Failed to throw StreamCorruptedException for non serialized stream");
+    }
+
+    /**
+     * 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() {
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/StreamTokenizerTest.java b/luni/src/test/java/tests/api/java/io/StreamTokenizerTest.java
new file mode 100644
index 0000000..472fd5a
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/StreamTokenizerTest.java
@@ -0,0 +1,448 @@
+/*
+ *  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.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.CharArrayReader;
+import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.Reader;
+import java.io.StreamTokenizer;
+import java.io.StringBufferInputStream;
+
+import tests.support.Support_StringReader;
+
+public class StreamTokenizerTest extends junit.framework.TestCase {
+    Support_StringReader r;
+
+    StreamTokenizer st;
+
+    String testString;
+
+    /**
+     * java.io.StreamTokenizer#StreamTokenizer(java.io.InputStream)
+     */
+    @SuppressWarnings("deprecation")
+    public void test_ConstructorLjava_io_InputStream() throws IOException {
+        st = new StreamTokenizer(new StringBufferInputStream(
+                "/comments\n d 8 'h'"));
+
+        assertEquals("the next token returned should be the letter d",
+                StreamTokenizer.TT_WORD, st.nextToken());
+        assertEquals("the next token returned should be the letter d",
+                "d", st.sval);
+
+        assertEquals("the next token returned should be the digit 8",
+                StreamTokenizer.TT_NUMBER, st.nextToken());
+        assertEquals("the next token returned should be the digit 8",
+                8.0, st.nval);
+
+        assertEquals("the next token returned should be the quote character",
+                39, st.nextToken());
+        assertEquals("the next token returned should be the quote character",
+                "h", st.sval);
+    }
+
+    /**
+     * java.io.StreamTokenizer#StreamTokenizer(java.io.Reader)
+     */
+    public void test_ConstructorLjava_io_Reader() throws IOException {
+        setTest("/testing\n d 8 'h' ");
+        assertEquals("the next token returned should be the letter d skipping the comments",
+                StreamTokenizer.TT_WORD, st.nextToken());
+        assertEquals("the next token returned should be the letter d",
+                "d", st.sval);
+
+        assertEquals("the next token returned should be the digit 8",
+                StreamTokenizer.TT_NUMBER, st.nextToken());
+        assertEquals("the next token returned should be the digit 8",
+                8.0, st.nval);
+
+        assertEquals("the next token returned should be the quote character",
+                39, st.nextToken());
+        assertEquals("the next token returned should be the quote character",
+                "h", st.sval);
+    }
+
+    /**
+     * java.io.StreamTokenizer#commentChar(int)
+     */
+    public void test_commentCharI() throws IOException {
+        setTest("*comment \n / 8 'h' ");
+        st.ordinaryChar('/');
+        st.commentChar('*');
+        assertEquals("nextToken() did not return the character / skiping the comments starting with *",
+                47, st.nextToken());
+        assertTrue("the next token returned should be the digit 8", st
+                .nextToken() == StreamTokenizer.TT_NUMBER
+                && st.nval == 8.0);
+        assertTrue("the next token returned should be the quote character",
+                st.nextToken() == 39 && st.sval.equals("h"));
+    }
+
+    /**
+     * java.io.StreamTokenizer#eolIsSignificant(boolean)
+     */
+    public void test_eolIsSignificantZ() throws IOException {
+        setTest("d 8\n");
+        // by default end of line characters are not significant
+        assertTrue("nextToken did not return d",
+                st.nextToken() == StreamTokenizer.TT_WORD
+                        && st.sval.equals("d"));
+        assertTrue("nextToken did not return 8",
+                st.nextToken() == StreamTokenizer.TT_NUMBER
+                        && st.nval == 8.0);
+        assertTrue("nextToken should be the end of file",
+                st.nextToken() == StreamTokenizer.TT_EOF);
+        setTest("d\n");
+        st.eolIsSignificant(true);
+        // end of line characters are significant
+        assertTrue("nextToken did not return d",
+                st.nextToken() == StreamTokenizer.TT_WORD
+                        && st.sval.equals("d"));
+        assertTrue("nextToken is the end of line",
+                st.nextToken() == StreamTokenizer.TT_EOL);
+    }
+
+    /**
+     * java.io.StreamTokenizer#lineno()
+     */
+    public void test_lineno() throws IOException {
+        setTest("d\n 8\n");
+        assertEquals("the lineno should be 1", 1, st.lineno());
+        st.nextToken();
+        st.nextToken();
+        assertEquals("the lineno should be 2", 2, st.lineno());
+        st.nextToken();
+        assertEquals("the next line no should be 3", 3, st.lineno());
+    }
+
+    /**
+     * java.io.StreamTokenizer#lowerCaseMode(boolean)
+     */
+    public void test_lowerCaseModeZ() throws Exception {
+        // SM.
+        setTest("HELLOWORLD");
+        st.lowerCaseMode(true);
+
+        st.nextToken();
+        assertEquals("sval not converted to lowercase.", "helloworld", st.sval
+        );
+    }
+
+    /**
+     * java.io.StreamTokenizer#nextToken()
+     */
+    @SuppressWarnings("deprecation")
+    public void test_nextToken() throws IOException {
+        // SM.
+        setTest("\r\n/* fje fje 43.4 f \r\n f g */  456.459 \r\n"
+                + "Hello  / 	\r\n \r\n \n \r \257 Hi \'Hello World\'");
+        st.ordinaryChar('/');
+        st.slashStarComments(true);
+        st.nextToken();
+        assertTrue("Wrong Token type1: " + (char) st.ttype,
+                st.ttype == StreamTokenizer.TT_NUMBER);
+        st.nextToken();
+        assertTrue("Wrong Token type2: " + st.ttype,
+                st.ttype == StreamTokenizer.TT_WORD);
+        st.nextToken();
+        assertTrue("Wrong Token type3: " + st.ttype, st.ttype == '/');
+        st.nextToken();
+        assertTrue("Wrong Token type4: " + st.ttype,
+                st.ttype == StreamTokenizer.TT_WORD);
+        st.nextToken();
+        assertTrue("Wrong Token type5: " + st.ttype,
+                st.ttype == StreamTokenizer.TT_WORD);
+        st.nextToken();
+        assertTrue("Wrong Token type6: " + st.ttype, st.ttype == '\'');
+        assertTrue("Wrong Token type7: " + st.ttype, st.sval
+                .equals("Hello World"));
+        st.nextToken();
+        assertTrue("Wrong Token type8: " + st.ttype, st.ttype == -1);
+
+        final PipedInputStream pin = new PipedInputStream();
+        PipedOutputStream pout = new PipedOutputStream(pin);
+        pout.write("hello\n\r\r".getBytes("UTF-8"));
+        StreamTokenizer s = new StreamTokenizer(pin);
+        s.eolIsSignificant(true);
+        assertTrue("Wrong token 1,1",
+                s.nextToken() == StreamTokenizer.TT_WORD
+                        && s.sval.equals("hello"));
+        assertTrue("Wrong token 1,2", s.nextToken() == '\n');
+        assertTrue("Wrong token 1,3", s.nextToken() == '\n');
+        assertTrue("Wrong token 1,4", s.nextToken() == '\n');
+        pout.close();
+        assertTrue("Wrong token 1,5",
+                s.nextToken() == StreamTokenizer.TT_EOF);
+        StreamTokenizer tokenizer = new StreamTokenizer(
+                new Support_StringReader("\n \r\n#"));
+        tokenizer.ordinaryChar('\n'); // make \n ordinary
+        tokenizer.eolIsSignificant(true);
+        assertTrue("Wrong token 2,1", tokenizer.nextToken() == '\n');
+        assertTrue("Wrong token 2,2", tokenizer.nextToken() == '\n');
+        assertEquals("Wrong token 2,3", '#', tokenizer.nextToken());
+    }
+
+    /**
+     * java.io.StreamTokenizer#ordinaryChar(int)
+     */
+    public void test_ordinaryCharI() throws IOException {
+        // SM.
+        setTest("Ffjein 893");
+        st.ordinaryChar('F');
+        st.nextToken();
+        assertTrue("OrdinaryChar failed." + (char) st.ttype,
+                st.ttype == 'F');
+    }
+
+    /**
+     * java.io.StreamTokenizer#ordinaryChars(int, int)
+     */
+    public void test_ordinaryCharsII() throws IOException {
+        // SM.
+        setTest("azbc iof z 893");
+        st.ordinaryChars('a', 'z');
+        assertEquals("OrdinaryChars failed.", 'a', st.nextToken());
+        assertEquals("OrdinaryChars failed.", 'z', st.nextToken());
+    }
+
+    /**
+     * java.io.StreamTokenizer#parseNumbers()
+     */
+    public void test_parseNumbers() throws IOException {
+        // SM
+        setTest("9.9 678");
+        assertTrue("Base behavior failed.",
+                st.nextToken() == StreamTokenizer.TT_NUMBER);
+        st.ordinaryChars('0', '9');
+        assertEquals("setOrdinary failed.", '6', st.nextToken());
+        st.parseNumbers();
+        assertTrue("parseNumbers failed.",
+                st.nextToken() == StreamTokenizer.TT_NUMBER);
+    }
+
+    /**
+     * java.io.StreamTokenizer#pushBack()
+     */
+    public void test_pushBack() throws IOException {
+        // SM.
+        setTest("Hello 897");
+        st.nextToken();
+        st.pushBack();
+        assertTrue("PushBack failed.",
+                st.nextToken() == StreamTokenizer.TT_WORD);
+    }
+
+    /**
+     * java.io.StreamTokenizer#quoteChar(int)
+     */
+    public void test_quoteCharI() throws IOException {
+        // SM
+        setTest("<Hello World<    HelloWorldH");
+        st.quoteChar('<');
+        assertEquals("QuoteChar failed.", '<', st.nextToken());
+        assertEquals("QuoteChar failed.", "Hello World", st.sval);
+        st.quoteChar('H');
+        st.nextToken();
+        assertEquals("QuoteChar failed for word.", "elloWorld", st.sval
+        );
+    }
+
+    /**
+     * java.io.StreamTokenizer#resetSyntax()
+     */
+    public void test_resetSyntax() throws IOException {
+        // SM
+        setTest("H 9\' ello World");
+        st.resetSyntax();
+        assertTrue("resetSyntax failed1." + (char) st.ttype,
+                st.nextToken() == 'H');
+        assertTrue("resetSyntax failed1." + (char) st.ttype,
+                st.nextToken() == ' ');
+        assertTrue("resetSyntax failed2." + (char) st.ttype,
+                st.nextToken() == '9');
+        assertTrue("resetSyntax failed3." + (char) st.ttype,
+                st.nextToken() == '\'');
+    }
+
+    /**
+     * java.io.StreamTokenizer#slashSlashComments(boolean)
+     */
+    public void test_slashSlashCommentsZ() throws IOException {
+        // SM.
+        setTest("// foo \r\n /fiji \r\n -456");
+        st.ordinaryChar('/');
+        st.slashSlashComments(true);
+        assertEquals("Test failed.", '/', st.nextToken());
+        assertTrue("Test failed.",
+                st.nextToken() == StreamTokenizer.TT_WORD);
+    }
+
+    /**
+     * java.io.StreamTokenizer#slashSlashComments(boolean)
+     */
+    public void test_slashSlashComments_withSSOpen() throws IOException {
+        Reader reader = new CharArrayReader("t // t t t".toCharArray());
+
+        StreamTokenizer st = new StreamTokenizer(reader);
+        st.slashSlashComments(true);
+
+        assertEquals(StreamTokenizer.TT_WORD, st.nextToken());
+        assertEquals(StreamTokenizer.TT_EOF, st.nextToken());
+    }
+
+    /**
+     * java.io.StreamTokenizer#slashSlashComments(boolean)
+     */
+    public void test_slashSlashComments_withSSOpen_NoComment() throws IOException {
+        Reader reader = new CharArrayReader("// t".toCharArray());
+
+        StreamTokenizer st = new StreamTokenizer(reader);
+        st.slashSlashComments(true);
+        st.ordinaryChar('/');
+
+        assertEquals(StreamTokenizer.TT_EOF, st.nextToken());
+    }
+
+    /**
+     * java.io.StreamTokenizer#slashSlashComments(boolean)
+     */
+    public void test_slashSlashComments_withSSClosed() throws IOException {
+        Reader reader = new CharArrayReader("// t".toCharArray());
+
+        StreamTokenizer st = new StreamTokenizer(reader);
+        st.slashSlashComments(false);
+        st.ordinaryChar('/');
+
+        assertEquals('/', st.nextToken());
+        assertEquals('/', st.nextToken());
+        assertEquals(StreamTokenizer.TT_WORD, st.nextToken());
+    }
+
+    /**
+     * java.io.StreamTokenizer#slashStarComments(boolean)
+     */
+    public void test_slashStarCommentsZ() throws IOException {
+        setTest("/* foo \r\n /fiji \r\n*/ -456");
+        st.ordinaryChar('/');
+        st.slashStarComments(true);
+        assertTrue("Test failed.",
+                st.nextToken() == StreamTokenizer.TT_NUMBER);
+    }
+
+    /**
+     * java.io.StreamTokenizer#slashStarComments(boolean)
+     */
+    public void test_slashStarComments_withSTOpen() throws IOException {
+        Reader reader = new CharArrayReader("t /* t */ t".toCharArray());
+
+        StreamTokenizer st = new StreamTokenizer(reader);
+        st.slashStarComments(true);
+
+        assertEquals(StreamTokenizer.TT_WORD, st.nextToken());
+        assertEquals(StreamTokenizer.TT_WORD, st.nextToken());
+        assertEquals(StreamTokenizer.TT_EOF, st.nextToken());
+    }
+
+    /**
+     * java.io.StreamTokenizer#slashStarComments(boolean)
+     */
+    public void test_slashStarComments_withSTClosed() throws IOException {
+        Reader reader = new CharArrayReader("t /* t */ t".toCharArray());
+
+        StreamTokenizer st = new StreamTokenizer(reader);
+        st.slashStarComments(false);
+
+        assertEquals(StreamTokenizer.TT_WORD, st.nextToken());
+        assertEquals(StreamTokenizer.TT_EOF, st.nextToken());
+    }
+
+    /**
+     * java.io.StreamTokenizer#toString()
+     */
+    public void test_toString() throws IOException {
+        setTest("ABC Hello World");
+        st.nextToken();
+        assertTrue("toString failed." + st.toString(),
+                st.toString().equals(
+                        "Token[ABC], line 1"));
+
+        // Regression test for HARMONY-4070
+        byte[] data = new byte[] { (byte) '-' };
+        StreamTokenizer tokenizer = new StreamTokenizer(
+                new ByteArrayInputStream(data));
+        tokenizer.nextToken();
+        String result = tokenizer.toString();
+        assertEquals("Token['-'], line 1", result);
+    }
+
+    /**
+     * java.io.StreamTokenizer#whitespaceChars(int, int)
+     */
+    public void test_whitespaceCharsII() throws IOException {
+        setTest("azbc iof z 893");
+        st.whitespaceChars('a', 'z');
+        assertTrue("OrdinaryChar failed.",
+                st.nextToken() == StreamTokenizer.TT_NUMBER);
+    }
+
+    /**
+     * java.io.StreamTokenizer#wordChars(int, int)
+     */
+    public void test_wordCharsII() throws IOException {
+        setTest("A893 -9B87");
+        st.wordChars('0', '9');
+        assertTrue("WordChar failed1.",
+                st.nextToken() == StreamTokenizer.TT_WORD);
+        assertEquals("WordChar failed2.", "A893", st.sval);
+        assertTrue("WordChar failed3.",
+                st.nextToken() == StreamTokenizer.TT_NUMBER);
+        st.nextToken();
+        assertEquals("WordChar failed4.", "B87", st.sval);
+
+        setTest("    Hello World");
+        st.wordChars(' ', ' ');
+        st.nextToken();
+        assertEquals("WordChars failed for whitespace.", "Hello World", st.sval
+        );
+
+        setTest("    Hello World\r\n  \'Hello World\' Hello\' World");
+        st.wordChars(' ', ' ');
+        st.wordChars('\'', '\'');
+        st.nextToken();
+        assertTrue("WordChars failed for whitespace: " + st.sval, st.sval
+                .equals("Hello World"));
+        st.nextToken();
+        assertTrue("WordChars failed for quote1: " + st.sval, st.sval
+                .equals("\'Hello World\' Hello\' World"));
+    }
+
+    private void setTest(String s) {
+        testString = s;
+        r = new Support_StringReader(testString);
+        st = new StreamTokenizer(r);
+    }
+
+    protected void setUp() {
+    }
+
+    protected void tearDown() {
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/StringBufferInputStreamTest.java b/luni/src/test/java/tests/api/java/io/StringBufferInputStreamTest.java
new file mode 100644
index 0000000..9adce09
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/StringBufferInputStreamTest.java
@@ -0,0 +1,99 @@
+/*
+ *  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.io;
+
+import java.io.StringBufferInputStream;
+import java.io.UnsupportedEncodingException;
+
+@SuppressWarnings("deprecation")
+public class StringBufferInputStreamTest extends junit.framework.TestCase {
+
+    StringBufferInputStream sbis;
+
+    /**
+     * java.io.StringBufferInputStream#StringBufferInputStream(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        // Test for method java.io.StringBufferInputStream(java.lang.String)
+    }
+
+    /**
+     * java.io.StringBufferInputStream#available()
+     */
+    public void test_available() {
+        // Test for method int java.io.StringBufferInputStream.available()
+        assertEquals("Returned incorrect number of available bytes", 11, sbis
+                .available());
+    }
+
+    /**
+     * java.io.StringBufferInputStream#read()
+     */
+    public void test_read() throws UnsupportedEncodingException {
+        // Test for method int java.io.StringBufferInputStream.read()
+        byte[] buf = new byte[5];
+        sbis.skip(6);
+        sbis.read(buf, 0, 5);
+        assertEquals("Returned incorrect chars", "World", new String(buf, "UTF-8"));
+    }
+
+    /**
+     * java.io.StringBufferInputStream#read(byte[], int, int)
+     */
+    public void test_read$BII() {
+        // Test for method int java.io.StringBufferInputStream.read(byte [],
+        // int, int)
+        assertEquals("Read returned incorrect char", 'H', sbis.read());
+    }
+
+    /**
+     * java.io.StringBufferInputStream#reset()
+     */
+    public void test_reset() {
+        // Test for method void java.io.StringBufferInputStream.reset()
+        long s = sbis.skip(6);
+        assertEquals("Unable to skip correct umber of chars", 6, s);
+        sbis.reset();
+        assertEquals("Failed to reset", 'H', sbis.read());
+    }
+
+    /**
+     * java.io.StringBufferInputStream#skip(long)
+     */
+    public void test_skipJ() {
+        // Test for method long java.io.StringBufferInputStream.skip(long)
+        long s = sbis.skip(6);
+        assertEquals("Unable to skip correct umber of chars", 6, s);
+        assertEquals("Skip positioned at incorrect char", 'W', sbis.read());
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() {
+        sbis = new StringBufferInputStream("Hello World");
+    }
+
+    /**
+     * 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/tests/api/java/io/StringReaderTest.java b/luni/src/test/java/tests/api/java/io/StringReaderTest.java
new file mode 100644
index 0000000..2e2f4cf
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/StringReaderTest.java
@@ -0,0 +1,172 @@
+/*
+ *  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.io;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+public class StringReaderTest extends junit.framework.TestCase {
+
+    String testString = "This is a test string";
+
+    StringReader sr;
+
+    /**
+     * java.io.StringReader#StringReader(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        // Test for method java.io.StringReader(java.lang.String)
+        assertTrue("Used in tests", true);
+    }
+
+    /**
+     * java.io.StringReader#close()
+     */
+    public void test_close() throws Exception {
+        // Test for method void java.io.StringReader.close()
+        try {
+            sr = new StringReader(testString);
+            sr.close();
+            char[] buf = new char[10];
+            sr.read(buf, 0, 2);
+            fail("Close failed");
+        } catch (java.io.IOException e) {
+            return;
+        }
+    }
+
+    /**
+     * java.io.StringReader#mark(int)
+     */
+    public void test_markI() throws Exception {
+        // Test for method void java.io.StringReader.mark(int)
+        sr = new StringReader(testString);
+        sr.skip(5);
+        sr.mark(0);
+        sr.skip(5);
+        sr.reset();
+        char[] buf = new char[10];
+        sr.read(buf, 0, 2);
+        assertTrue("Failed to return to mark", new String(buf, 0, 2)
+                .equals(testString.substring(5, 7)));
+    }
+
+    /**
+     * java.io.StringReader#markSupported()
+     */
+    public void test_markSupported() {
+        // Test for method boolean java.io.StringReader.markSupported()
+
+        sr = new StringReader(testString);
+        assertTrue("markSupported returned false", sr.markSupported());
+    }
+
+    /**
+     * java.io.StringReader#read()
+     */
+    public void test_read() throws Exception {
+        // Test for method int java.io.StringReader.read()
+        sr = new StringReader(testString);
+        int r = sr.read();
+        assertEquals("Failed to read char", 'T', r);
+        sr = new StringReader(new String(new char[] { '\u8765' }));
+        assertTrue("Wrong double byte char", sr.read() == '\u8765');
+    }
+
+    /**
+     * java.io.StringReader#read(char[], int, int)
+     */
+    public void test_read$CII() throws Exception {
+        // Test for method int java.io.StringReader.read(char [], int, int)
+        sr = new StringReader(testString);
+        char[] buf = new char[testString.length()];
+        int r = sr.read(buf, 0, testString.length());
+        assertTrue("Failed to read chars", r == testString.length());
+        assertTrue("Read chars incorrectly", new String(buf, 0, r)
+                .equals(testString));
+    }
+
+    /**
+     * java.io.StringReader#ready()
+     */
+    public void test_ready() throws Exception {
+        // Test for method boolean java.io.StringReader.ready()
+        sr = new StringReader(testString);
+        assertTrue("Steam not ready", sr.ready());
+        sr.close();
+        int r = 0;
+        try {
+            sr.ready();
+        } catch (IOException e) {
+            r = 1;
+        }
+        assertEquals("Expected IOException not thrown in read()", 1, r);
+    }
+
+    /**
+     * java.io.StringReader#reset()
+     */
+    public void test_reset() throws Exception {
+        // Test for method void java.io.StringReader.reset()
+        sr = new StringReader(testString);
+        sr.skip(5);
+        sr.mark(0);
+        sr.skip(5);
+        sr.reset();
+        char[] buf = new char[10];
+        sr.read(buf, 0, 2);
+        assertTrue("Failed to reset properly", new String(buf, 0, 2)
+                .equals(testString.substring(5, 7)));
+    }
+
+    /**
+     * java.io.StringReader#skip(long)
+     */
+    public void test_skipJ() throws Exception {
+        // Test for method long java.io.StringReader.skip(long)
+        sr = new StringReader(testString);
+        sr.skip(5);
+        char[] buf = new char[10];
+        sr.read(buf, 0, 2);
+        assertTrue("Failed to skip properly", new String(buf, 0, 2)
+                .equals(testString.substring(5, 7)));
+    }
+
+    // Regression test for HARMONY-5077
+    static boolean finish = false;
+
+    public void test_synchronization() {
+        String anything = "Hello world";
+        final StringReader sr = new StringReader(anything);
+        Thread other = new Thread(new Runnable() {
+            public void run() {
+                sr.close();
+                finish = true;
+            }
+
+            ;
+        });
+
+        synchronized (anything) {
+            other.start();
+            while (!finish) {
+                Thread.yield();
+            }
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/StringWriterTest.java b/luni/src/test/java/tests/api/java/io/StringWriterTest.java
new file mode 100644
index 0000000..dcb9a2521
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/StringWriterTest.java
@@ -0,0 +1,211 @@
+/*
+ *  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.io;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+public class StringWriterTest extends junit.framework.TestCase {
+
+    StringWriter sw;
+
+    /**
+     * java.io.StringWriter#StringWriter()
+     */
+    public void test_Constructor() {
+        // Test for method java.io.StringWriter()
+        assertTrue("Used in tests", true);
+    }
+
+    /**
+     * java.io.StringWriter#close()
+     */
+    public void test_close() {
+        // Test for method void java.io.StringWriter.close()
+        try {
+            sw.close();
+        } catch (IOException e) {
+            fail("IOException closing StringWriter : " + e.getMessage());
+        }
+    }
+
+    /**
+     * java.io.StringWriter#flush()
+     */
+    public void test_flush() {
+        // Test for method void java.io.StringWriter.flush()
+        sw.flush();
+        sw.write('c');
+        assertEquals("Failed to flush char", "c", sw.toString());
+    }
+
+    /**
+     * java.io.StringWriter#getBuffer()
+     */
+    public void test_getBuffer() {
+        // Test for method java.lang.StringBuffer
+        // java.io.StringWriter.getBuffer()
+
+        sw.write("This is a test string");
+        StringBuffer sb = sw.getBuffer();
+        assertEquals("Incorrect buffer returned",
+                "This is a test string", sb.toString());
+    }
+
+    /**
+     * java.io.StringWriter#toString()
+     */
+    public void test_toString() {
+        // Test for method java.lang.String java.io.StringWriter.toString()
+        sw.write("This is a test string");
+        assertEquals("Incorrect string returned",
+                "This is a test string", sw.toString());
+    }
+
+    /**
+     * java.io.StringWriter#write(char[], int, int)
+     */
+    public void test_write$CII() {
+        // Test for method void java.io.StringWriter.write(char [], int, int)
+        char[] c = new char[1000];
+        "This is a test string".getChars(0, 21, c, 0);
+        sw.write(c, 0, 21);
+        assertEquals("Chars not written properly",
+                "This is a test string", sw.toString());
+    }
+
+    /**
+     * java.io.StringWriter#write(char[], int, int)
+     * Regression for HARMONY-387
+     */
+    public void test_write$CII_2() {
+        StringWriter obj = null;
+        try {
+            obj = new StringWriter();
+            obj.write(new char[0], (int) 0, (int) -1);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+    }
+
+    /**
+     * java.io.StringWriter#write(char[], int, int)
+     */
+    public void test_write$CII_3() {
+        StringWriter obj = null;
+        try {
+            obj = new StringWriter();
+            obj.write(new char[0], (int) -1, (int) 0);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+    }
+
+    /**
+     * java.io.StringWriter#write(char[], int, int)
+     */
+    public void test_write$CII_4() {
+        StringWriter obj = null;
+        try {
+            obj = new StringWriter();
+            obj.write(new char[0], (int) -1, (int) -1);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+    }
+
+    /**
+     * java.io.StringWriter#write(int)
+     */
+    public void test_writeI() {
+        // Test for method void java.io.StringWriter.write(int)
+        sw.write('c');
+        assertEquals("Char not written properly", "c", sw.toString());
+    }
+
+    /**
+     * java.io.StringWriter#write(java.lang.String)
+     */
+    public void test_writeLjava_lang_String() {
+        // Test for method void java.io.StringWriter.write(java.lang.String)
+        sw.write("This is a test string");
+        assertEquals("String not written properly",
+                "This is a test string", sw.toString());
+    }
+
+    /**
+     * java.io.StringWriter#write(java.lang.String, int, int)
+     */
+    public void test_writeLjava_lang_StringII() {
+        // Test for method void java.io.StringWriter.write(java.lang.String,
+        // int, int)
+        sw.write("This is a test string", 2, 2);
+        assertEquals("String not written properly", "is", sw.toString());
+    }
+
+    /**
+     * java.io.StringWriter#append(char)
+     */
+    public void test_appendChar() throws IOException {
+        char testChar = ' ';
+        StringWriter stringWriter = new StringWriter(20);
+        stringWriter.append(testChar);
+        assertEquals(String.valueOf(testChar), stringWriter.toString());
+        stringWriter.close();
+    }
+
+    /**
+     * java.io.PrintWriter#append(CharSequence)
+     */
+    public void test_appendCharSequence() throws IOException {
+
+        String testString = "My Test String";
+        StringWriter stringWriter = new StringWriter(20);
+        stringWriter.append(testString);
+        assertEquals(String.valueOf(testString), stringWriter.toString());
+        stringWriter.close();
+    }
+
+    /**
+     * java.io.PrintWriter#append(CharSequence, int, int)
+     */
+    public void test_appendCharSequenceIntInt() throws IOException {
+        String testString = "My Test String";
+        StringWriter stringWriter = new StringWriter(20);
+        stringWriter.append(testString, 1, 3);
+        assertEquals(testString.substring(1, 3), stringWriter.toString());
+        stringWriter.close();
+
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() {
+
+        sw = new StringWriter();
+    }
+
+    /**
+     * 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/tests/api/java/io/SyncFailedExceptionTest.java b/luni/src/test/java/tests/api/java/io/SyncFailedExceptionTest.java
new file mode 100644
index 0000000..481d3d3
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/SyncFailedExceptionTest.java
@@ -0,0 +1,60 @@
+/*
+ *  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.io;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.SyncFailedException;
+
+public class SyncFailedExceptionTest extends junit.framework.TestCase {
+
+    /**
+     * java.io.SyncFailedException#SyncFailedException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() throws Exception {
+        // Test for method java.io.SyncFailedException(java.lang.String)
+        File f = null;
+        try {
+            f = new File(System.getProperty("user.dir"), "synfail.tst");
+            FileOutputStream fos = new FileOutputStream(f.getPath());
+            FileDescriptor fd = fos.getFD();
+            fos.close();
+            fd.sync();
+        } catch (SyncFailedException e) {
+            f.delete();
+            return;
+        }
+
+        fail("Failed to generate expected Exception");
+    }
+
+    /**
+     * 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() {
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/UTFDataFormatExceptionTest.java b/luni/src/test/java/tests/api/java/io/UTFDataFormatExceptionTest.java
new file mode 100644
index 0000000..ecaa5bc
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/UTFDataFormatExceptionTest.java
@@ -0,0 +1,83 @@
+/*
+ *  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.io;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.UTFDataFormatException;
+
+public class UTFDataFormatExceptionTest extends junit.framework.TestCase {
+
+    /**
+     * java.io.UTFDataFormatException#UTFDataFormatException()
+     */
+    public void test_Constructor() {
+        // Test for method java.io.UTFDataFormatException()
+        try {
+            int stringBufferSize = 70000;
+            int loopCount = 66;
+            StringBuffer sb = new StringBuffer(stringBufferSize);
+            for (int i = 0; i < (loopCount); i++)
+                sb
+                        .append("qwertyuiopasdfghjklzxcvbnmlkjhgfdsaqwertyuioplkjhgqwertyuiopasdfghjklzxcvbnmlkjhgfdsaqwertyuioplkjhg");
+            DataOutputStream dos = new DataOutputStream(
+                    new ByteArrayOutputStream());
+            dos.writeUTF(sb.toString());
+        } catch (UTFDataFormatException e) {
+            return;
+        } catch (Exception e) {
+            fail("Exception during Constructor test : " + e.getMessage());
+        }
+    }
+
+    /**
+     * java.io.UTFDataFormatException#UTFDataFormatException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        // Test for method java.io.UTFDataFormatException(java.lang.String)
+        try {
+            int stringBufferSize = 70000;
+            int loopCount = 66;
+            StringBuffer sb = new StringBuffer(stringBufferSize);
+            for (int i = 0; i < (loopCount); i++)
+                sb
+                        .append("qwertyuiopasdfghjklzxcvbnmlkjhgfdsaqwertyuioplkjhgqwertyuiopasdfghjklzxcvbnmlkjhgfdsaqwertyuioplkjhg");
+            DataOutputStream dos = new DataOutputStream(
+                    new ByteArrayOutputStream());
+            dos.writeUTF(sb.toString());
+        } catch (UTFDataFormatException e) {
+            return;
+        } catch (Exception e) {
+            fail("Exception during Constructor test : " + e.getMessage());
+        }
+    }
+
+    /**
+     * 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() {
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/UnsupportedEncodingExceptionTest.java b/luni/src/test/java/tests/api/java/io/UnsupportedEncodingExceptionTest.java
new file mode 100644
index 0000000..44c2fd55
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/UnsupportedEncodingExceptionTest.java
@@ -0,0 +1,68 @@
+/*
+ *  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.io;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+
+public class UnsupportedEncodingExceptionTest extends junit.framework.TestCase {
+
+    /**
+     * java.io.UnsupportedEncodingException#UnsupportedEncodingException()
+     */
+    public void test_Constructor() {
+        // Test for method java.io.UnsupportedEncodingException()
+        try {
+            new OutputStreamWriter(new ByteArrayOutputStream(), "BogusEncoding");
+        } catch (UnsupportedEncodingException e) {
+            return;
+        }
+
+        fail("Failed to generate expected exception");
+    }
+
+    /**
+     * java.io.UnsupportedEncodingException#UnsupportedEncodingException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        // Test for method
+        // java.io.UnsupportedEncodingException(java.lang.String)
+        try {
+            new OutputStreamWriter(new ByteArrayOutputStream(), "BogusEncoding");
+        } catch (UnsupportedEncodingException e) {
+            return;
+        }
+
+        fail("Failed to generate expected exception");
+    }
+
+    /**
+     * 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() {
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/WriteAbortedExceptionTest.java b/luni/src/test/java/tests/api/java/io/WriteAbortedExceptionTest.java
new file mode 100644
index 0000000..1d270f6
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/WriteAbortedExceptionTest.java
@@ -0,0 +1,73 @@
+/*
+ *  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.io;
+
+import java.io.WriteAbortedException;
+
+public class WriteAbortedExceptionTest extends junit.framework.TestCase {
+
+    /**
+     * java.io.WriteAbortedException#WriteAbortedException(java.lang.String,
+     *java.lang.Exception)
+     */
+    public void test_ConstructorLjava_lang_StringLjava_lang_Exception() {
+        // Test for method java.io.WriteAbortedException(java.lang.String,
+        // java.lang.Exception)
+        try {
+            if (true)
+                throw new WriteAbortedException("HelloWorld",
+                        new WriteAbortedException("ByeWorld", null));
+        } catch (WriteAbortedException e) {
+            return;
+        }
+        fail("Failed to generate expected Exception");
+    }
+
+    /**
+     * java.io.WriteAbortedException#getMessage()
+     */
+    public void test_getMessage() {
+        // Test for method java.lang.String
+        // java.io.WriteAbortedException.getMessage()
+        try {
+            if (true)
+                throw new WriteAbortedException("HelloWorld",
+                        new WriteAbortedException("ByeWorld", null));
+        } catch (WriteAbortedException e) {
+            assertTrue("WriteAbortedException::getMessage() failed"
+                    + e.getMessage(), e.getMessage().equals(
+                    "HelloWorld; java.io.WriteAbortedException: ByeWorld"));
+            return;
+        }
+        fail("Failed to generate expected Exception");
+    }
+
+    /**
+     * 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() {
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/io/WriterTest.java b/luni/src/test/java/tests/api/java/io/WriterTest.java
new file mode 100644
index 0000000..b161030
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/WriterTest.java
@@ -0,0 +1,147 @@
+/* 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.io;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import junit.framework.TestCase;
+
+public class WriterTest extends TestCase {
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+
+    }
+
+    /**
+     * 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();
+
+    }
+
+
+    /**
+     * 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;
+
+        MockLockWriter(Object lock) {
+            super(lock);
+            myLock = lock;
+        }
+
+        @Override
+        public synchronized void close() throws IOException {
+            // do nothing
+        }
+
+        @Override
+        public synchronized void flush() throws IOException {
+            // do nothing
+        }
+
+        @Override
+        public void write(char[] arg0, int arg1, int arg2) throws IOException {
+            assertTrue(Thread.holdsLock(myLock));
+        }
+    }
+
+
+    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/tests/api/java/io/WriterTesterTest.java b/luni/src/test/java/tests/api/java/io/WriterTesterTest.java
new file mode 100644
index 0000000..e087fac
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/io/WriterTesterTest.java
@@ -0,0 +1,212 @@
+/*
+ *  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.io;
+
+import junit.framework.TestSuite;
+import org.apache.harmony.testframework.CharSinkTester;
+import org.apache.harmony.testframework.CharWrapperTester;
+import tests.support.Streams;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.CharArrayWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.FilterWriter;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PipedReader;
+import java.io.PipedWriter;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+/**
+ * Tests basic {@link Writer} behaviors for the luni implementations of the type.
+ */
+public class WriterTesterTest {
+
+    public static junit.framework.Test suite() {
+        TestSuite suite = new TestSuite();
+
+        // sink tests
+        suite.addTest(new FileWriterCharSinkTester(true).createTests());
+        suite.addTest(new FileWriterCharSinkTester(false).createTests());
+        suite.addTest(new CharArrayWriterCharSinkTester().setThrowsExceptions(false).createTests());
+        suite.addTest(new StringWriterCharSinkTester().setThrowsExceptions(false).createTests());
+        suite.addTest(new PipedWriterCharSinkTester().createTests());
+
+        // wrapper tests
+        suite.addTest(new BufferedWriterCharSinkTester(1).createTests());
+        suite.addTest(new BufferedWriterCharSinkTester(5).createTests());
+        suite.addTest(new BufferedWriterCharSinkTester(1024).createTests());
+        suite.addTest(new FilterWriterCharSinkTester().createTests());
+        suite.addTest(new PrintWriterCharSinkTester().setThrowsExceptions(false).createTests());
+        suite.addTest(new OutputStreamWriterCharSinkTester().createTests());
+
+        return suite;
+    }
+
+    private static class FileWriterCharSinkTester extends CharSinkTester {
+        private final boolean append;
+        private File file;
+
+        public FileWriterCharSinkTester(boolean append) {
+            this.append = append;
+        }
+
+        @Override
+        public Writer create() throws Exception {
+            file = File.createTempFile("FileOutputStreamSinkTester", "tmp");
+            file.deleteOnExit();
+            return new FileWriter(file, append);
+        }
+
+        @Override
+        public char[] getChars() throws Exception {
+            return Streams.streamToString(new FileReader(file)).toCharArray();
+        }
+    }
+
+    private static class CharArrayWriterCharSinkTester extends CharSinkTester {
+        private CharArrayWriter writer;
+
+        @Override
+        public Writer create() throws Exception {
+            writer = new CharArrayWriter();
+            return writer;
+        }
+
+        @Override
+        public char[] getChars() throws Exception {
+            return writer.toCharArray();
+        }
+    }
+
+    private static class PipedWriterCharSinkTester extends CharSinkTester {
+
+        private ExecutorService executor;
+        private Future<char[]> future;
+
+        public Writer create() throws IOException {
+            final PipedReader in = new PipedReader();
+            PipedWriter out = new PipedWriter(in);
+
+            executor = Executors.newSingleThreadExecutor();
+            future = executor.submit(new Callable<char[]>() {
+                final CharArrayWriter chars = new CharArrayWriter();
+
+                public char[] call() throws Exception {
+                    char[] buffer = new char[256];
+                    int count;
+                    while ((count = in.read(buffer)) != -1) {
+                        chars.write(buffer, 0, count);
+                    }
+                    return chars.toCharArray();
+                }
+            });
+
+            return out;
+        }
+
+        @Override
+        public char[] getChars() throws Exception {
+            executor.shutdown();
+            return future.get();
+        }
+    }
+
+    private static class StringWriterCharSinkTester extends CharSinkTester {
+        private StringWriter writer;
+
+        @Override
+        public Writer create() throws Exception {
+            writer = new StringWriter();
+            return writer;
+        }
+
+        @Override
+        public char[] getChars() throws Exception {
+            return writer.toString().toCharArray();
+        }
+    }
+
+    private static class BufferedWriterCharSinkTester extends CharWrapperTester {
+        private final int bufferSize;
+
+        private BufferedWriterCharSinkTester(int bufferSize) {
+            this.bufferSize = bufferSize;
+        }
+
+        @Override
+        public Writer create(Writer delegate) throws Exception {
+            return new BufferedWriter(delegate, bufferSize);
+        }
+
+        @Override
+        public char[] decode(char[] delegateChars) throws Exception {
+            return delegateChars;
+        }
+    }
+
+    private static class FilterWriterCharSinkTester extends CharWrapperTester {
+        @Override
+        public Writer create(Writer delegate) throws Exception {
+            return new FilterWriter(delegate) {
+            };
+        }
+
+        @Override
+        public char[] decode(char[] delegateChars) throws Exception {
+            return delegateChars;
+        }
+    }
+
+    private static class PrintWriterCharSinkTester extends CharWrapperTester {
+        @Override
+        public Writer create(Writer delegate) throws Exception {
+            return new PrintWriter(delegate) {
+            };
+        }
+
+        @Override
+        public char[] decode(char[] delegateChars) throws Exception {
+            return delegateChars;
+        }
+    }
+
+    private static class OutputStreamWriterCharSinkTester extends CharSinkTester {
+        private ByteArrayOutputStream out;
+
+        @Override
+        public Writer create() throws Exception {
+            out = new ByteArrayOutputStream();
+            return new OutputStreamWriter(out, "UTF-8");
+        }
+
+        @Override
+        public char[] getChars() throws Exception {
+            return new String(out.toByteArray(), "UTF-8").toCharArray();
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/AbstractMethodErrorTest.java b/luni/src/test/java/tests/api/java/lang/AbstractMethodErrorTest.java
new file mode 100644
index 0000000..c30e68f
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/AbstractMethodErrorTest.java
@@ -0,0 +1,62 @@
+/*
+ *  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.lang;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class AbstractMethodErrorTest extends junit.framework.TestCase {
+
+    /**
+     * {@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());
+    }
+
+    /**
+     * {@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());
+    }
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+        SerializationTest.verifySelf(new AbstractMethodError());
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+        SerializationTest.verifyGolden(this, new AbstractMethodError());
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/lang/ArithmeticExceptionTest.java b/luni/src/test/java/tests/api/java/lang/ArithmeticExceptionTest.java
new file mode 100644
index 0000000..6ecf6ac
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/ArithmeticExceptionTest.java
@@ -0,0 +1,41 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class ArithmeticExceptionTest extends TestCase {
+
+    /**
+     * java.lang.ArithmeticException#ArithmeticException()
+     */
+    public void test_Constructor() {
+        ArithmeticException e = new ArithmeticException();
+        assertNull(e.getMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.ArithmeticException#ArithmeticException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        ArithmeticException e = new ArithmeticException("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/ArrayIndexOutOfBoundsExceptionTest.java b/luni/src/test/java/tests/api/java/lang/ArrayIndexOutOfBoundsExceptionTest.java
new file mode 100644
index 0000000..90ba03e
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/ArrayIndexOutOfBoundsExceptionTest.java
@@ -0,0 +1,52 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class ArrayIndexOutOfBoundsExceptionTest extends TestCase {
+
+    /**
+     * java.lang.ArrayIndexOutOfBoundsException#ArrayIndexOutOfBoundsException(int)
+     */
+    public void test_ConstructorI() {
+        ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException(-1);
+        assertNotNull(e.getMessage());
+        assertTrue("Unable to find index value in 'message' property.", e.getMessage().indexOf(
+                "-1", 0) >= 0);
+
+    }
+
+    /**
+     * java.lang.ArrayIndexOutOfBoundsException#ArrayIndexOutOfBoundsException()
+     */
+    public void test_Constructor() {
+        ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
+        assertNull(e.getMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.ArrayIndexOutOfBoundsException#ArrayIndexOutOfBoundsException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/ArrayStoreExceptionTest.java b/luni/src/test/java/tests/api/java/lang/ArrayStoreExceptionTest.java
new file mode 100644
index 0000000..fc323d4
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/ArrayStoreExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class ArrayStoreExceptionTest extends TestCase {
+
+    /**
+     * java.lang.ArrayStoreException#ArrayStoreException()
+     */
+    public void test_Constructor() {
+        ArrayStoreException e = new ArrayStoreException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.ArrayStoreException#ArrayStoreException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        ArrayStoreException e = new ArrayStoreException("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/AssertionErrorTest.java b/luni/src/test/java/tests/api/java/lang/AssertionErrorTest.java
new file mode 100644
index 0000000..c0c968c
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/AssertionErrorTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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.lang;
+
+import junit.framework.TestCase;
+
+public class AssertionErrorTest extends TestCase {
+
+    public void test_Constructor() {
+        AssertionError e = new AssertionError();
+        assertNull(e.getMessage());
+        assertNull(e.getCause());
+    }
+
+    public void test_ConstructorObject() {
+        Object obj = "toString";
+        AssertionError e = new AssertionError(obj);
+        assertEquals("toString", e.getMessage());
+        assertNull(e.getCause());
+
+        NullPointerException npe = new NullPointerException("null value");
+        e = new AssertionError(npe);
+        assertEquals(npe.toString(), e.getMessage());
+        assertSame(npe, e.getCause());
+    }
+
+    public void test_ConstructorBoolean() {
+        AssertionError e = new AssertionError(true);
+        assertEquals("true", e.getMessage());
+        assertNull(e.getCause());
+    }
+
+    public void test_ConstructorChar() {
+        AssertionError e = new AssertionError('a');
+        assertEquals("a", e.getMessage());
+        assertNull(e.getCause());
+    }
+
+    public void test_ConstructorInt() {
+        AssertionError e = new AssertionError(1);
+        assertEquals("1", e.getMessage());
+        assertNull(e.getCause());
+    }
+
+    public void test_ConstructorLong() {
+        AssertionError e = new AssertionError(1L);
+        assertEquals("1", e.getMessage());
+        assertNull(e.getCause());
+    }
+
+    public void test_ConstructorFloat() {
+        AssertionError e = new AssertionError(1.0F);
+        assertEquals("1.0", e.getMessage());
+        assertNull(e.getCause());
+    }
+
+    public void test_ConstructorDouble() {
+        AssertionError e = new AssertionError(1.0D);
+        assertEquals("1.0", e.getMessage());
+        assertNull(e.getCause());
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/lang/BooleanTest.java b/luni/src/test/java/tests/api/java/lang/BooleanTest.java
new file mode 100644
index 0000000..6bc6e83
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/BooleanTest.java
@@ -0,0 +1,157 @@
+/* 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.lang;
+
+import junit.framework.TestCase;
+
+public class BooleanTest extends TestCase {
+
+    /**
+     * java.lang.Boolean#hashCode()
+     */
+    public void test_hashCode() {
+        assertEquals(1231, Boolean.TRUE.hashCode());
+        assertEquals(1237, Boolean.FALSE.hashCode());
+    }
+
+    /**
+     * java.lang.Boolean#Boolean(String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        assertEquals(Boolean.TRUE, new Boolean("TRUE"));
+        assertEquals(Boolean.TRUE, new Boolean("true"));
+        assertEquals(Boolean.TRUE, new Boolean("True"));
+
+        assertEquals(Boolean.FALSE, new Boolean("yes"));
+        assertEquals(Boolean.FALSE, new Boolean("false"));
+    }
+
+    /**
+     * java.lang.Boolean#Boolean(boolean)
+     */
+    public void test_ConstructorZ() {
+        assertEquals(Boolean.TRUE, new Boolean(true));
+        assertEquals(Boolean.FALSE, new Boolean(false));
+    }
+
+    /**
+     * java.lang.Boolean#booleanValue()
+     */
+    public void test_booleanValue() {
+        assertTrue(Boolean.TRUE.booleanValue());
+        assertFalse(Boolean.FALSE.booleanValue());
+    }
+
+    /**
+     * java.lang.Boolean#equals(Object)
+     */
+    public void test_equalsLjava_lang_Object() {
+        assertTrue(Boolean.TRUE.equals(Boolean.TRUE));
+        assertTrue(Boolean.TRUE.equals(new Boolean(true)));
+        assertFalse(Boolean.TRUE.equals("true"));
+        assertFalse(Boolean.TRUE.equals(null));
+        assertFalse(Boolean.FALSE.equals(Boolean.TRUE));
+        assertTrue(Boolean.FALSE.equals(Boolean.FALSE));
+        assertTrue(Boolean.FALSE.equals(new Boolean(false)));
+    }
+
+    /**
+     * java.lang.Boolean#getBoolean(String)
+     */
+    public void test_getBooleanLjava_lang_String() {
+        System.setProperty(getClass().getName(), "true");
+        assertTrue(Boolean.getBoolean(getClass().getName()));
+
+        System.setProperty(getClass().getName(), "TRUE");
+        assertTrue(Boolean.getBoolean(getClass().getName()));
+
+        System.setProperty(getClass().getName(), "false");
+        assertFalse(Boolean.getBoolean(getClass().getName()));
+    }
+
+    /**
+     * java.lang.Boolean#toString()
+     */
+    public void test_toString() {
+        assertEquals("true", Boolean.TRUE.toString());
+        assertEquals("false", Boolean.FALSE.toString());
+    }
+
+    /**
+     * java.lang.Boolean#toString(boolean)
+     */
+    public void test_toStringZ() {
+        assertEquals("true", Boolean.toString(true));
+        assertEquals("false", Boolean.toString(false));
+    }
+
+    /**
+     * java.lang.Boolean#valueOf(String)
+     */
+    public void test_valueOfLjava_lang_String() {
+        assertEquals(Boolean.TRUE, Boolean.valueOf("true"));
+        assertEquals(Boolean.FALSE, Boolean.valueOf("false"));
+
+        assertEquals(Boolean.TRUE, Boolean.valueOf("TRUE"));
+        assertEquals(Boolean.FALSE, Boolean.valueOf("false"));
+
+        assertEquals(Boolean.FALSE, Boolean.valueOf(null));
+        assertEquals(Boolean.FALSE, Boolean.valueOf(""));
+        assertEquals(Boolean.FALSE, Boolean.valueOf("invalid"));
+
+        assertTrue("Failed to parse true to true", Boolean.valueOf("true").booleanValue());
+        assertTrue("Failed to parse mixed case true to true", Boolean.valueOf("TrUe")
+                .booleanValue());
+        assertTrue("parsed non-true to true", !Boolean.valueOf("ddddd").booleanValue());
+    }
+
+    /**
+     * java.lang.Boolean#valueOf(boolean)
+     */
+    public void test_valueOfZ() {
+        assertEquals(Boolean.TRUE, Boolean.valueOf(true));
+        assertEquals(Boolean.FALSE, Boolean.valueOf(false));
+    }
+
+    /**
+     * java.lang.Boolean#parseBoolean(String)
+     */
+    public void test_parseBooleanLjava_lang_String() {
+        assertTrue(Boolean.parseBoolean("true"));
+        assertTrue(Boolean.parseBoolean("TRUE"));
+        assertFalse(Boolean.parseBoolean("false"));
+        assertFalse(Boolean.parseBoolean(null));
+        assertFalse(Boolean.parseBoolean(""));
+        assertFalse(Boolean.parseBoolean("invalid"));
+    }
+
+    /**
+     * java.lang.Boolean#compareTo(Boolean)
+     */
+    public void test_compareToLjava_lang_Boolean() {
+        assertTrue(Boolean.TRUE.compareTo(Boolean.TRUE) == 0);
+        assertTrue(Boolean.FALSE.compareTo(Boolean.FALSE) == 0);
+        assertTrue(Boolean.TRUE.compareTo(Boolean.FALSE) > 0);
+        assertTrue(Boolean.FALSE.compareTo(Boolean.TRUE) < 0);
+
+        try {
+            Boolean.TRUE.compareTo(null);
+            fail("No NPE");
+        } catch (NullPointerException e) {
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/ByteTest.java b/luni/src/test/java/tests/api/java/lang/ByteTest.java
new file mode 100644
index 0000000..ed1bee7
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/ByteTest.java
@@ -0,0 +1,672 @@
+/* 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.lang;
+
+import junit.framework.TestCase;
+
+public class ByteTest extends TestCase {
+
+    /**
+     * java.lang.Byte#valueOf(byte)
+     */
+    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));
+        assertEquals(new Byte((byte) 0), Byte.valueOf((byte) 0));
+
+        byte b = Byte.MIN_VALUE + 1;
+        while (b < Byte.MAX_VALUE) {
+            assertEquals(new Byte(b), Byte.valueOf(b));
+            assertSame(Byte.valueOf(b), Byte.valueOf(b));
+            b++;
+        }
+    }
+
+    /**
+     * java.lang.Byte#hashCode()
+     */
+    public void test_hashCode() {
+        assertEquals(1, new Byte((byte) 1).hashCode());
+        assertEquals(2, new Byte((byte) 2).hashCode());
+        assertEquals(0, new Byte((byte) 0).hashCode());
+        assertEquals(-1, new Byte((byte) -1).hashCode());
+    }
+
+    /**
+     * java.lang.Byte#Byte(String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        assertEquals(new Byte((byte) 0), new Byte("0"));
+        assertEquals(new Byte((byte) 1), new Byte("1"));
+        assertEquals(new Byte((byte) -1), new Byte("-1"));
+
+        try {
+            new Byte("0x1");
+            fail("Expected NumberFormatException with hex string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            new Byte("9.2");
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            new Byte("");
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            new Byte(null);
+            fail("Expected NumberFormatException with null string.");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Byte#Byte(byte)
+     */
+    public void test_ConstructorB() {
+        assertEquals(1, new Byte((byte) 1).byteValue());
+        assertEquals(2, new Byte((byte) 2).byteValue());
+        assertEquals(0, new Byte((byte) 0).byteValue());
+        assertEquals(-1, new Byte((byte) -1).byteValue());
+    }
+
+    /**
+     * java.lang.Byte#byteValue()
+     */
+    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());
+        assertEquals(-1, new Byte((byte) -1).byteValue());
+    }
+
+    /**
+     * java.lang.Byte#equals(Object)
+     */
+    public void test_equalsLjava_lang_Object() {
+        assertEquals(new Byte((byte) 0), Byte.valueOf((byte) 0));
+        assertEquals(new Byte((byte) 1), Byte.valueOf((byte) 1));
+        assertEquals(new Byte((byte) -1), Byte.valueOf((byte) -1));
+
+        Byte fixture = new Byte((byte) 25);
+        assertEquals(fixture, fixture);
+        assertFalse(fixture.equals(null));
+        assertFalse(fixture.equals("Not a Byte"));
+    }
+
+    /**
+     * java.lang.Byte#toString()
+     */
+    public void test_toString() {
+        assertEquals("-1", new Byte((byte) -1).toString());
+        assertEquals("0", new Byte((byte) 0).toString());
+        assertEquals("1", new Byte((byte) 1).toString());
+        assertEquals("-1", new Byte((byte) 0xFF).toString());
+    }
+
+    /**
+     * java.lang.Byte#toString(byte)
+     */
+    public void test_toStringB() {
+        assertEquals("-1", Byte.toString((byte) -1));
+        assertEquals("0", Byte.toString((byte) 0));
+        assertEquals("1", Byte.toString((byte) 1));
+        assertEquals("-1", Byte.toString((byte) 0xFF));
+    }
+
+    /**
+     * java.lang.Byte#valueOf(String)
+     */
+    public void test_valueOfLjava_lang_String() {
+        assertEquals(new Byte((byte) 0), Byte.valueOf("0"));
+        assertEquals(new Byte((byte) 1), Byte.valueOf("1"));
+        assertEquals(new Byte((byte) -1), Byte.valueOf("-1"));
+
+        try {
+            Byte.valueOf("0x1");
+            fail("Expected NumberFormatException with hex string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Byte.valueOf("9.2");
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Byte.valueOf("");
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Byte.valueOf(null);
+            fail("Expected NumberFormatException with null string.");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Byte#valueOf(String, int)
+     */
+    public void test_valueOfLjava_lang_StringI() {
+        assertEquals(new Byte((byte) 0), Byte.valueOf("0", 10));
+        assertEquals(new Byte((byte) 1), Byte.valueOf("1", 10));
+        assertEquals(new Byte((byte) -1), Byte.valueOf("-1", 10));
+
+        //must be consistent with Character.digit()
+        assertEquals(Character.digit('1', 2), Byte.valueOf("1", 2).byteValue());
+        assertEquals(Character.digit('F', 16), Byte.valueOf("F", 16).byteValue());
+
+        try {
+            Byte.valueOf("0x1", 10);
+            fail("Expected NumberFormatException with hex string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Byte.valueOf("9.2", 10);
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Byte.valueOf("", 10);
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Byte.valueOf(null, 10);
+            fail("Expected NumberFormatException with null string.");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Byte#parseByte(String)
+     */
+    public void test_parseByteLjava_lang_String() {
+        assertEquals(0, Byte.parseByte("0"));
+        assertEquals(1, Byte.parseByte("1"));
+        assertEquals(-1, Byte.parseByte("-1"));
+
+        try {
+            Byte.parseByte("0x1");
+            fail("Expected NumberFormatException with hex string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Byte.parseByte("9.2");
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Byte.parseByte("");
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Byte.parseByte(null);
+            fail("Expected NumberFormatException with null string.");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Byte#parseByte(String, int)
+     */
+    public void test_parseByteLjava_lang_StringI() {
+        assertEquals(0, Byte.parseByte("0", 10));
+        assertEquals(1, Byte.parseByte("1", 10));
+        assertEquals(-1, Byte.parseByte("-1", 10));
+
+        //must be consistent with Character.digit()
+        assertEquals(Character.digit('1', 2), Byte.parseByte("1", 2));
+        assertEquals(Character.digit('F', 16), Byte.parseByte("F", 16));
+
+        try {
+            Byte.parseByte("0x1", 10);
+            fail("Expected NumberFormatException with hex string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Byte.parseByte("9.2", 10);
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Byte.parseByte("", 10);
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Byte.parseByte(null, 10);
+            fail("Expected NumberFormatException with null string.");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Byte#decode(String)
+     */
+    public void test_decodeLjava_lang_String() {
+        assertEquals(new Byte((byte) 0), Byte.decode("0"));
+        assertEquals(new Byte((byte) 1), Byte.decode("1"));
+        assertEquals(new Byte((byte) -1), Byte.decode("-1"));
+        assertEquals(new Byte((byte) 0xF), Byte.decode("0xF"));
+        assertEquals(new Byte((byte) 0xF), Byte.decode("#F"));
+        assertEquals(new Byte((byte) 0xF), Byte.decode("0XF"));
+        assertEquals(new Byte((byte) 07), Byte.decode("07"));
+
+        try {
+            Byte.decode("9.2");
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Byte.decode("");
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Byte.decode(null);
+            //undocumented NPE, but seems consistent across JREs
+            fail("Expected NullPointerException with null string.");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    /**
+     * java.lang.Byte#doubleValue()
+     */
+    public void test_doubleValue() {
+        assertEquals(-1D, new Byte((byte) -1).doubleValue(), 0D);
+        assertEquals(0D, new Byte((byte) 0).doubleValue(), 0D);
+        assertEquals(1D, new Byte((byte) 1).doubleValue(), 0D);
+    }
+
+    /**
+     * java.lang.Byte#floatValue()
+     */
+    public void test_floatValue() {
+        assertEquals(-1F, new Byte((byte) -1).floatValue(), 0F);
+        assertEquals(0F, new Byte((byte) 0).floatValue(), 0F);
+        assertEquals(1F, new Byte((byte) 1).floatValue(), 0F);
+    }
+
+    /**
+     * java.lang.Byte#intValue()
+     */
+    public void test_intValue() {
+        assertEquals(-1, new Byte((byte) -1).intValue());
+        assertEquals(0, new Byte((byte) 0).intValue());
+        assertEquals(1, new Byte((byte) 1).intValue());
+    }
+
+    /**
+     * java.lang.Byte#longValue()
+     */
+    public void test_longValue() {
+        assertEquals(-1L, new Byte((byte) -1).longValue());
+        assertEquals(0L, new Byte((byte) 0).longValue());
+        assertEquals(1L, new Byte((byte) 1).longValue());
+    }
+
+    /**
+     * java.lang.Byte#shortValue()
+     */
+    public void test_shortValue() {
+        assertEquals(-1, new Byte((byte) -1).shortValue());
+        assertEquals(0, new Byte((byte) 0).shortValue());
+        assertEquals(1, new Byte((byte) 1).shortValue());
+    }
+
+    /**
+     * java.lang.Byte#compareTo(Byte)
+     */
+    public void test_compareToLjava_lang_Byte() {
+        final Byte min = new Byte(Byte.MIN_VALUE);
+        final Byte zero = new Byte((byte) 0);
+        final Byte max = new Byte(Byte.MAX_VALUE);
+
+        assertTrue(max.compareTo(max) == 0);
+        assertTrue(min.compareTo(min) == 0);
+        assertTrue(zero.compareTo(zero) == 0);
+
+        assertTrue(max.compareTo(zero) > 0);
+        assertTrue(max.compareTo(min) > 0);
+
+        assertTrue(zero.compareTo(max) < 0);
+        assertTrue(zero.compareTo(min) > 0);
+
+        assertTrue(min.compareTo(zero) < 0);
+        assertTrue(min.compareTo(max) < 0);
+
+        try {
+            min.compareTo(null);
+            fail("No NPE");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    /**
+     * java.lang.Byte#Byte(byte)
+     */
+    public void test_ConstructorB2() {
+        // Test for method java.lang.Byte(byte)
+
+        Byte b = new Byte((byte) 127);
+        assertTrue("Byte creation failed", b.byteValue() == (byte) 127);
+    }
+
+    /**
+     * java.lang.Byte#Byte(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String2() {
+        // Test for method java.lang.Byte(java.lang.String)
+
+        Byte b = new Byte("127");
+        Byte nb = new Byte("-128");
+        assertTrue("Incorrect Byte Object created", b.byteValue() == (byte) 127
+                && (nb.byteValue() == (byte) -128));
+
+    }
+
+    /**
+     * java.lang.Byte#byteValue()
+     */
+    public void test_byteValue() {
+        // Test for method byte java.lang.Byte.byteValue()
+        assertTrue("Returned incorrect byte value",
+                new Byte((byte) 127).byteValue() == (byte) (127));
+    }
+
+    /**
+     * java.lang.Byte#compareTo(java.lang.Byte)
+     */
+    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);
+        assertTrue("Comparison failed", new Byte((byte) 1).compareTo(new Byte((byte) -2)) > 0);
+        assertEquals("Comparison failed", 0, new Byte((byte) 1).compareTo(new Byte((byte) 1)));
+    }
+
+    /**
+     * java.lang.Byte#decode(java.lang.String)
+     */
+    public void test_decodeLjava_lang_String2() {
+        // Test for method java.lang.Byte
+        // java.lang.Byte.decode(java.lang.String)
+        assertTrue("String decoded incorrectly, wanted: 1 got: " + Byte.decode("1").toString(),
+                Byte.decode("1").equals(new Byte((byte) 1)));
+        assertTrue("String decoded incorrectly, wanted: -1 got: "
+                + Byte.decode("-1").toString(), Byte.decode("-1").equals(new Byte((byte) -1)));
+        assertTrue("String decoded incorrectly, wanted: 127 got: "
+                + Byte.decode("127").toString(), Byte.decode("127")
+                .equals(new Byte((byte) 127)));
+        assertTrue("String decoded incorrectly, wanted: -128 got: "
+                + Byte.decode("-128").toString(), Byte.decode("-128").equals(
+                new Byte((byte) -128)));
+        assertTrue("String decoded incorrectly, wanted: 127 got: "
+                + Byte.decode("0x7f").toString(), Byte.decode("0x7f").equals(
+                new Byte((byte) 127)));
+        assertTrue("String decoded incorrectly, wanted: -128 got: "
+                + Byte.decode("-0x80").toString(), Byte.decode("-0x80").equals(
+                new Byte((byte) -128)));
+
+        boolean exception = false;
+        try {
+            Byte.decode("128");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for MAX_VALUE + 1", exception);
+
+        exception = false;
+        try {
+            Byte.decode("-129");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for MIN_VALUE - 1", exception);
+
+        exception = false;
+        try {
+            Byte.decode("0x80");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for hex MAX_VALUE + 1", exception);
+
+        exception = false;
+        try {
+            Byte.decode("-0x81");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for hex MIN_VALUE - 1", exception);
+    }
+
+    /**
+     * java.lang.Byte#doubleValue()
+     */
+    public void test_doubleValue2() {
+        assertEquals(127D, new Byte((byte) 127).doubleValue(), 0.0);
+    }
+
+    /**
+     * java.lang.Byte#equals(java.lang.Object)
+     */
+    public void test_equalsLjava_lang_Object2() {
+        // Test for method boolean java.lang.Byte.equals(java.lang.Object)
+        Byte b1 = new Byte((byte) 90);
+        Byte b2 = new Byte((byte) 90);
+        Byte b3 = new Byte((byte) -90);
+        assertTrue("Equality test failed", b1.equals(b2));
+        assertTrue("Equality test failed", !b1.equals(b3));
+    }
+
+    /**
+     * java.lang.Byte#floatValue()
+     */
+    public void test_floatValue2() {
+        assertEquals(127F, new Byte((byte) 127).floatValue(), 0.0);
+    }
+
+    /**
+     * java.lang.Byte#hashCode()
+     */
+    public void test_hashCode2() {
+        // Test for method int java.lang.Byte.hashCode()
+        assertEquals("Incorrect hash returned", 127, new Byte((byte) 127).hashCode());
+    }
+
+    /**
+     * java.lang.Byte#intValue()
+     */
+    public void test_intValue2() {
+        // Test for method int java.lang.Byte.intValue()
+        assertEquals("Returned incorrect int value", 127, new Byte((byte) 127).intValue());
+    }
+
+    /**
+     * java.lang.Byte#longValue()
+     */
+    public void test_longValue2() {
+        // Test for method long java.lang.Byte.longValue()
+        assertEquals("Returned incorrect long value", 127L, new Byte((byte) 127).longValue());
+    }
+
+    /**
+     * java.lang.Byte#parseByte(java.lang.String)
+     */
+    public void test_parseByteLjava_lang_String2() {
+        assertEquals((byte) 127, Byte.parseByte("127"));
+        assertEquals((byte) -128, Byte.parseByte("-128"));
+        assertEquals((byte) 0, Byte.parseByte("0"));
+        assertEquals((byte) 0x80, Byte.parseByte("-128"));
+        assertEquals((byte) 0x7F, Byte.parseByte("127"));
+
+        try {
+            Byte.parseByte("-1000");
+            fail("No NumberFormatException");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Byte.parseByte("128");
+            fail("No NumberFormatException");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Byte.parseByte("-129");
+            fail("No NumberFormatException");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Byte#parseByte(java.lang.String, int)
+     */
+    public void test_parseByteLjava_lang_StringI2() {
+        // Test for method byte java.lang.Byte.parseByte(java.lang.String, int)
+        byte b = Byte.parseByte("127", 10);
+        byte bn = Byte.parseByte("-128", 10);
+        assertTrue("Invalid parse of dec byte", b == (byte) 127 && (bn == (byte) -128));
+        assertEquals("Failed to parse hex value", 10, Byte.parseByte("A", 16));
+        assertEquals("Returned incorrect value for 0 hex", 0, Byte.parseByte("0", 16));
+        assertTrue("Returned incorrect value for most negative value hex", Byte.parseByte(
+                "-80", 16) == (byte) 0x80);
+        assertTrue("Returned incorrect value for most positive value hex", Byte.parseByte("7f",
+                16) == 0x7f);
+        assertEquals("Returned incorrect value for 0 decimal", 0, Byte.parseByte("0", 10));
+        assertTrue("Returned incorrect value for most negative value decimal", Byte.parseByte(
+                "-128", 10) == (byte) 0x80);
+        assertTrue("Returned incorrect value for most positive value decimal", Byte.parseByte(
+                "127", 10) == 0x7f);
+
+        try {
+            Byte.parseByte("-1000", 10);
+            fail("Failed to throw exception");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Byte.parseByte("128", 10);
+            fail("Failed to throw exception for MAX_VALUE + 1");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Byte.parseByte("-129", 10);
+            fail("Failed to throw exception for MIN_VALUE - 1");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Byte.parseByte("80", 16);
+            fail("Failed to throw exception for hex MAX_VALUE + 1");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Byte.parseByte("-81", 16);
+            fail("Failed to throw exception for hex MIN_VALUE + 1");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Byte#shortValue()
+     */
+    public void test_shortValue2() {
+        assertEquals((short) 127, new Byte((byte) 127).shortValue());
+    }
+
+    /**
+     * java.lang.Byte#toString()
+     */
+    public void test_toString2() {
+        assertEquals("Returned incorrect String", "127", new Byte((byte) 127).toString());
+        assertEquals("Returned incorrect String", "-127", new Byte((byte) -127).toString());
+        assertEquals("Returned incorrect String", "-128", new Byte((byte) -128).toString());
+    }
+
+    /**
+     * java.lang.Byte#toString(byte)
+     */
+    public void test_toStringB2() {
+        assertEquals("Returned incorrect String", "127", Byte.toString((byte) 127));
+        assertEquals("Returned incorrect String", "-127", Byte.toString((byte) -127));
+        assertEquals("Returned incorrect String", "-128", Byte.toString((byte) -128));
+    }
+
+    /**
+     * java.lang.Byte#valueOf(java.lang.String)
+     */
+    public void test_valueOfLjava_lang_String2() {
+        assertEquals("Returned incorrect byte", 0, Byte.valueOf("0").byteValue());
+        assertEquals("Returned incorrect byte", 127, Byte.valueOf("127").byteValue());
+        assertEquals("Returned incorrect byte", -127, Byte.valueOf("-127").byteValue());
+        assertEquals("Returned incorrect byte", -128, Byte.valueOf("-128").byteValue());
+
+        try {
+            Byte.valueOf("128");
+            fail("Failed to throw exception when passes value > byte");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Byte#valueOf(java.lang.String, int)
+     */
+    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());
+        assertEquals("Returned incorrect byte", -127, Byte.valueOf("-127", 10).byteValue());
+        assertEquals("Returned incorrect byte", -128, Byte.valueOf("-128", 10).byteValue());
+        assertEquals("Returned incorrect byte", 127, Byte.valueOf("7f", 16).byteValue());
+        assertEquals("Returned incorrect byte", -127, Byte.valueOf("-7f", 16).byteValue());
+        assertEquals("Returned incorrect byte", -128, Byte.valueOf("-80", 16).byteValue());
+
+        try {
+            Byte.valueOf("128", 10);
+            fail("Failed to throw exception when passes value > byte");
+        } catch (NumberFormatException e) {
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/CharacterImplTest.java b/luni/src/test/java/tests/api/java/lang/CharacterImplTest.java
new file mode 100644
index 0000000..2963d41
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/CharacterImplTest.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 tests.api.java.lang;
+
+import junit.framework.TestCase;
+
+public class CharacterImplTest extends TestCase {
+
+    public void test_valueOfC() {
+        // test the cache range
+        for (char c = '\u0000'; c < 128; c++) {
+            Character e = new Character(c);
+            Character a = Character.valueOf(c);
+            assertEquals(e, a);
+
+            // WARN: this assertion may not be valid on other JREs
+            assertSame(Character.valueOf(c), Character.valueOf(c));
+        }
+        // test the rest of the chars
+        for (int c = 128; c <= Character.MAX_VALUE; c++) {
+            assertEquals(new Character((char) c), Character.valueOf((char) c));
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/CharacterTest.java b/luni/src/test/java/tests/api/java/lang/CharacterTest.java
new file mode 100644
index 0000000..776ebf07
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/CharacterTest.java
@@ -0,0 +1,1733 @@
+/* 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.lang;
+
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+public class CharacterTest extends TestCase {
+
+    public void test_isValidCodePointI() {
+        assertFalse(Character.isValidCodePoint(-1));
+        assertTrue(Character.isValidCodePoint(0));
+        assertTrue(Character.isValidCodePoint(1));
+        assertFalse(Character.isValidCodePoint(Integer.MAX_VALUE));
+
+        for (int c = '\u0000'; c <= 0x10FFFF; c++) {
+            assertTrue(Character.isValidCodePoint(c));
+        }
+
+        assertFalse(Character.isValidCodePoint(0x10FFFF + 1));
+    }
+
+    public void test_isSupplementaryCodePointI() {
+        assertFalse(Character.isSupplementaryCodePoint(-1));
+
+        for (int c = '\u0000'; c <= '\uFFFF'; c++) {
+            assertFalse(Character.isSupplementaryCodePoint(c));
+        }
+
+        for (int c = 0xFFFF + 1; c <= 0x10FFFF; c++) {
+            assertTrue(Character.isSupplementaryCodePoint(c));
+        }
+
+        assertFalse(Character.isSupplementaryCodePoint(0x10FFFF + 1));
+    }
+
+    public void test_isHighSurrogateC() {
+        // (\uD800-\uDBFF)
+        assertFalse(Character.isHighSurrogate((char) ('\uD800' - 1)));
+        for (int c = '\uD800'; c <= '\uDBFF'; c++) {
+            assertTrue(Character.isHighSurrogate((char) c));
+        }
+        assertFalse(Character.isHighSurrogate((char) ('\uDBFF' + 1)));
+        assertFalse(Character.isHighSurrogate('\uFFFF'));
+    }
+
+    public void test_isLowSurrogateC() {
+        // (\uDC00-\uDFFF)
+        assertFalse(Character.isLowSurrogate((char) ('\uDC00' - 1)));
+        for (int c = '\uDC00'; c <= '\uDFFF'; c++) {
+            assertTrue(Character.isLowSurrogate((char) c));
+        }
+        assertFalse(Character.isLowSurrogate((char) ('\uDFFF' + 1)));
+    }
+
+    public void test_isSurrogatePairCC() {
+        assertFalse(Character.isSurrogatePair('\u0000', '\u0000'));
+        assertFalse(Character.isSurrogatePair('\u0000', '\uDC00'));
+
+        assertTrue(Character.isSurrogatePair('\uD800', '\uDC00'));
+        assertTrue(Character.isSurrogatePair('\uD800', '\uDFFF'));
+        assertTrue(Character.isSurrogatePair('\uDBFF', '\uDFFF'));
+
+        assertFalse(Character.isSurrogatePair('\uDBFF', '\uF000'));
+    }
+
+    public void test_charCountI() {
+
+        for (int c = '\u0000'; c <= '\uFFFF'; c++) {
+            assertEquals(1, Character.charCount(c));
+        }
+
+        for (int c = 0xFFFF + 1; c <= 0x10FFFF; c++) {
+            assertEquals(2, Character.charCount(c));
+        }
+
+        // invalid code points work in this method
+        assertEquals(2, Character.charCount(Integer.MAX_VALUE));
+    }
+
+    public void test_toCodePointCC() {
+        int result = Character.toCodePoint('\uD800', '\uDC00');
+        assertEquals(0x00010000, result);
+
+        result = Character.toCodePoint('\uD800', '\uDC01');
+        assertEquals(0x00010001, result);
+
+        result = Character.toCodePoint('\uD801', '\uDC01');
+        assertEquals(0x00010401, result);
+
+        result = Character.toCodePoint('\uDBFF', '\uDFFF');
+        assertEquals(0x00010FFFF, result);
+    }
+
+    @SuppressWarnings("cast")
+    public void test_codePointAtLjava_lang_CharSequenceI() {
+
+        assertEquals('a', Character.codePointAt((CharSequence) "abc", 0));
+        assertEquals('b', Character.codePointAt((CharSequence) "abc", 1));
+        assertEquals('c', Character.codePointAt((CharSequence) "abc", 2));
+        assertEquals(0x10000, Character.codePointAt(
+                (CharSequence) "\uD800\uDC00", 0));
+        assertEquals('\uDC00', Character.codePointAt(
+                (CharSequence) "\uD800\uDC00", 1));
+
+        try {
+            Character.codePointAt((CharSequence) null, 0);
+            fail("No NPE.");
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            Character.codePointAt((CharSequence) "abc", -1);
+            fail("No IOOBE, negative index.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.codePointAt((CharSequence) "abc", 4);
+            fail("No IOOBE, index too large.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    public void test_codePointAt$CI() {
+
+        assertEquals('a', Character.codePointAt("abc".toCharArray(), 0));
+        assertEquals('b', Character.codePointAt("abc".toCharArray(), 1));
+        assertEquals('c', Character.codePointAt("abc".toCharArray(), 2));
+        assertEquals(0x10000, Character.codePointAt("\uD800\uDC00"
+                .toCharArray(), 0));
+        assertEquals('\uDC00', Character.codePointAt("\uD800\uDC00"
+                .toCharArray(), 1));
+
+        try {
+            Character.codePointAt((char[]) null, 0);
+            fail("No NPE.");
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            Character.codePointAt("abc".toCharArray(), -1);
+            fail("No IOOBE, negative index.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.codePointAt("abc".toCharArray(), 4);
+            fail("No IOOBE, index too large.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    public void test_codePointAt$CII() {
+
+        assertEquals('a', Character.codePointAt("abc".toCharArray(), 0, 3));
+        assertEquals('b', Character.codePointAt("abc".toCharArray(), 1, 3));
+        assertEquals('c', Character.codePointAt("abc".toCharArray(), 2, 3));
+        assertEquals(0x10000, Character.codePointAt("\uD800\uDC00"
+                .toCharArray(), 0, 2));
+        assertEquals('\uDC00', Character.codePointAt("\uD800\uDC00"
+                .toCharArray(), 1, 2));
+        assertEquals('\uD800', Character.codePointAt("\uD800\uDC00"
+                .toCharArray(), 0, 1));
+
+        try {
+            Character.codePointAt((char[]) null, 0, 1);
+            fail("No NPE.");
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            Character.codePointAt("abc".toCharArray(), -1, 3);
+            fail("No IOOBE, negative index.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.codePointAt("abc".toCharArray(), 4, 3);
+            fail("No IOOBE, index too large.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.codePointAt("abc".toCharArray(), 2, 1);
+            fail("No IOOBE, index larger than limit.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.codePointAt("abc".toCharArray(), 2, -1);
+            fail("No IOOBE, limit is negative.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("cast")
+    public void test_codePointBeforeLjava_lang_CharSequenceI() {
+
+        assertEquals('a', Character.codePointBefore((CharSequence) "abc", 1));
+        assertEquals('b', Character.codePointBefore((CharSequence) "abc", 2));
+        assertEquals('c', Character.codePointBefore((CharSequence) "abc", 3));
+        assertEquals(0x10000, Character.codePointBefore(
+                (CharSequence) "\uD800\uDC00", 2));
+        assertEquals('\uD800', Character.codePointBefore(
+                (CharSequence) "\uD800\uDC00", 1));
+
+        try {
+            Character.codePointBefore((CharSequence) null, 0);
+            fail("No NPE.");
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            Character.codePointBefore((CharSequence) "abc", 0);
+            fail("No IOOBE, index below one.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.codePointBefore((CharSequence) "abc", 4);
+            fail("No IOOBE, index too large.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    public void test_codePointBefore$CI() {
+
+        assertEquals('a', Character.codePointBefore("abc".toCharArray(), 1));
+        assertEquals('b', Character.codePointBefore("abc".toCharArray(), 2));
+        assertEquals('c', Character.codePointBefore("abc".toCharArray(), 3));
+        assertEquals(0x10000, Character.codePointBefore("\uD800\uDC00"
+                .toCharArray(), 2));
+        assertEquals('\uD800', Character.codePointBefore("\uD800\uDC00"
+                .toCharArray(), 1));
+
+        try {
+            Character.codePointBefore((char[]) null, 0);
+            fail("No NPE.");
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            Character.codePointBefore("abc".toCharArray(), -1);
+            fail("No IOOBE, negative index.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.codePointBefore("abc".toCharArray(), 4);
+            fail("No IOOBE, index too large.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    public void test_codePointBefore$CII() {
+
+        assertEquals('a', Character.codePointBefore("abc".toCharArray(), 1, 0));
+        assertEquals('b', Character.codePointBefore("abc".toCharArray(), 2, 0));
+        assertEquals('c', Character.codePointBefore("abc".toCharArray(), 3, 0));
+        assertEquals(0x10000, Character.codePointBefore("\uD800\uDC00"
+                .toCharArray(), 2, 0));
+        assertEquals('\uDC00', Character.codePointBefore("\uD800\uDC00"
+                .toCharArray(), 2, 1));
+        assertEquals('\uD800', Character.codePointBefore("\uD800\uDC00"
+                .toCharArray(), 1, 0));
+
+        try {
+            Character.codePointBefore((char[]) null, 1, 0);
+            fail("No NPE.");
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            Character.codePointBefore("abc".toCharArray(), 0, 1);
+            fail("No IOOBE, index less than start.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.codePointBefore("abc".toCharArray(), 4, 0);
+            fail("No IOOBE, index larger than length.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.codePointBefore("abc".toCharArray(), 2, -1);
+            fail("No IOOBE, start is negative.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.codePointBefore("abc".toCharArray(), 2, 4);
+            fail("No IOOBE, start larger than length.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    public void test_toCharsI$CI() {
+        char[] dst = new char[2];
+        int result = Character.toChars(0x10000, dst, 0);
+        assertEquals(2, result);
+        assertTrue(Arrays.equals(new char[] { '\uD800', '\uDC00' }, dst));
+
+        result = Character.toChars(0x10001, dst, 0);
+        assertEquals(2, result);
+        assertTrue(Arrays.equals(new char[] { '\uD800', '\uDC01' }, dst));
+
+        result = Character.toChars(0x10401, dst, 0);
+        assertEquals(2, result);
+        assertTrue(Arrays.equals(new char[] { '\uD801', '\uDC01' }, dst));
+
+        result = Character.toChars(0x10FFFF, dst, 0);
+        assertEquals(2, result);
+        assertTrue(Arrays.equals(new char[] { '\uDBFF', '\uDFFF' }, dst));
+
+        try {
+            Character.toChars(Integer.MAX_VALUE, new char[2], 0);
+            fail("No IAE, invalid code point.");
+        } catch (IllegalArgumentException e) {
+        }
+
+        try {
+            Character.toChars('a', null, 0);
+            fail("No NPE, null char[].");
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            Character.toChars('a', new char[1], -1);
+            fail("No IOOBE, negative index.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.toChars('a', new char[1], 1);
+            fail("No IOOBE, index equal to length.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    public void test_toCharsI() {
+        assertTrue(Arrays.equals(new char[] { '\uD800', '\uDC00' }, Character
+                .toChars(0x10000)));
+        assertTrue(Arrays.equals(new char[] { '\uD800', '\uDC01' }, Character
+                .toChars(0x10001)));
+        assertTrue(Arrays.equals(new char[] { '\uD801', '\uDC01' }, Character
+                .toChars(0x10401)));
+        assertTrue(Arrays.equals(new char[] { '\uDBFF', '\uDFFF' }, Character
+                .toChars(0x10FFFF)));
+
+        try {
+            Character.toChars(Integer.MAX_VALUE);
+            fail("No IAE, invalid code point.");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public void test_codePointCountLjava_lang_CharSequenceII() {
+        assertEquals(1, Character.codePointCount("\uD800\uDC00", 0, 2));
+        assertEquals(1, Character.codePointCount("\uD800\uDC01", 0, 2));
+        assertEquals(1, Character.codePointCount("\uD801\uDC01", 0, 2));
+        assertEquals(1, Character.codePointCount("\uDBFF\uDFFF", 0, 2));
+
+        assertEquals(3, Character.codePointCount("a\uD800\uDC00b", 0, 4));
+        assertEquals(4, Character.codePointCount("a\uD800\uDC00b\uD800", 0, 5));
+
+        try {
+            Character.codePointCount((CharSequence) null, 0, 1);
+            fail("No NPE, null char sequence.");
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            Character.codePointCount("abc", -1, 1);
+            fail("No IOOBE, negative start.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.codePointCount("abc", 0, 4);
+            fail("No IOOBE, end greater than length.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.codePointCount("abc", 2, 1);
+            fail("No IOOBE, end greater than start.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    public void test_offsetByCodePointsLjava_lang_CharSequenceII() {
+        int result = Character.offsetByCodePoints("a\uD800\uDC00b", 0, 2);
+        assertEquals(3, result);
+
+        result = Character.offsetByCodePoints("abcd", 3, -1);
+        assertEquals(2, result);
+
+        result = Character.offsetByCodePoints("a\uD800\uDC00b", 0, 3);
+        assertEquals(4, result);
+
+        result = Character.offsetByCodePoints("a\uD800\uDC00b", 3, -1);
+        assertEquals(1, result);
+
+        result = Character.offsetByCodePoints("a\uD800\uDC00b", 3, 0);
+        assertEquals(3, result);
+
+        result = Character.offsetByCodePoints("\uD800\uDC00bc", 3, 0);
+        assertEquals(3, result);
+
+        result = Character.offsetByCodePoints("a\uDC00bc", 3, -1);
+        assertEquals(2, result);
+
+        result = Character.offsetByCodePoints("a\uD800bc", 3, -1);
+        assertEquals(2, result);
+
+        try {
+            Character.offsetByCodePoints((CharSequence) null, 0, 1);
+            fail();
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            Character.offsetByCodePoints("abc", -1, 1);
+            fail();
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.offsetByCodePoints("abc", 4, 1);
+            fail();
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.offsetByCodePoints("abc", 1, 3);
+            fail();
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.offsetByCodePoints("abc", 1, -2);
+            fail();
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    public void test_offsetByCodePoints$CIIII() {
+        int result = Character.offsetByCodePoints("a\uD800\uDC00b"
+                .toCharArray(), 0, 4, 0, 2);
+        assertEquals(3, result);
+
+        result = Character.offsetByCodePoints("a\uD800\uDC00b".toCharArray(),
+                0, 4, 0, 3);
+        assertEquals(4, result);
+
+        result = Character.offsetByCodePoints("a\uD800\uDC00b\uD800c"
+                .toCharArray(), 0, 5, 0, 3);
+        assertEquals(4, result);
+
+        result = Character
+                .offsetByCodePoints("abcd".toCharArray(), 0, 4, 3, -1);
+        assertEquals(2, result);
+
+        result = Character
+                .offsetByCodePoints("abcd".toCharArray(), 1, 2, 3, -2);
+        assertEquals(1, result);
+
+        result = Character.offsetByCodePoints("a\uD800\uDC00b".toCharArray(),
+                0, 4, 3, -1);
+        assertEquals(1, result);
+
+        result = Character.offsetByCodePoints("a\uD800\uDC00b".toCharArray(),
+                0, 2, 2, -1);
+        assertEquals(1, result);
+
+        result = Character.offsetByCodePoints("a\uD800\uDC00b".toCharArray(),
+                0, 4, 3, 0);
+        assertEquals(3, result);
+
+        result = Character.offsetByCodePoints("\uD800\uDC00bc".toCharArray(),
+                0, 4, 3, 0);
+        assertEquals(3, result);
+
+        result = Character.offsetByCodePoints("a\uDC00bc".toCharArray(), 0, 4,
+                3, -1);
+        assertEquals(2, result);
+
+        result = Character.offsetByCodePoints("a\uD800bc".toCharArray(), 0, 4,
+                3, -1);
+        assertEquals(2, result);
+
+        try {
+            Character.offsetByCodePoints(null, 0, 4, 1, 1);
+            fail();
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            Character.offsetByCodePoints("abcd".toCharArray(), -1, 4, 1, 1);
+            fail();
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.offsetByCodePoints("abcd".toCharArray(), 0, -1, 1, 1);
+            fail();
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.offsetByCodePoints("abcd".toCharArray(), 2, 4, 1, 1);
+            fail();
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.offsetByCodePoints("abcd".toCharArray(), 1, 3, 0, 1);
+            fail();
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.offsetByCodePoints("abcd".toCharArray(), 1, 1, 3, 1);
+            fail();
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.offsetByCodePoints("abc".toCharArray(), 0, 3, 1, 3);
+            fail();
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.offsetByCodePoints("abc".toCharArray(), 0, 2, 1, 2);
+            fail();
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Character.offsetByCodePoints("abc".toCharArray(), 1, 3, 1, -2);
+            fail();
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    /**
+     * java.lang.Character#compareTo(Character)
+     */
+    public void test_compareToLjava_lang_Byte() {
+        final Character min = new Character(Character.MIN_VALUE);
+        final Character mid = new Character((char) (Character.MAX_VALUE / 2));
+        final Character max = new Character(Character.MAX_VALUE);
+
+        assertTrue(max.compareTo(max) == 0);
+        assertTrue(min.compareTo(min) == 0);
+        assertTrue(mid.compareTo(mid) == 0);
+
+        assertTrue(max.compareTo(mid) > 0);
+        assertTrue(max.compareTo(min) > 0);
+
+        assertTrue(mid.compareTo(max) < 0);
+        assertTrue(mid.compareTo(min) > 0);
+
+        assertTrue(min.compareTo(mid) < 0);
+        assertTrue(min.compareTo(max) < 0);
+
+        try {
+            min.compareTo(null);
+            fail("No NPE");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    public void test_codePointAt_Invalid() {
+
+        try {
+            Character.codePointAt(null, 6, 4);
+            fail("Expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            Character.codePointAt(null, 4, 6);
+            fail("Expected NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            Character.codePointAt(null, 0, 0);
+            fail("Expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.lang.Character#Character(char)
+     */
+    public void test_ConstructorC() {
+        assertEquals("Constructor failed", 'T', new Character('T').charValue());
+    }
+
+    /**
+     * java.lang.Character#charValue()
+     */
+    public void test_charValue() {
+        assertEquals("Incorrect char value returned", 'T', new Character('T')
+                .charValue());
+    }
+
+    /**
+     * java.lang.Character#compareTo(java.lang.Character)
+     */
+    public void test_compareToLjava_lang_Character() {
+        Character c = new Character('c');
+        Character x = new Character('c');
+        Character y = new Character('b');
+        Character z = new Character('d');
+
+        assertEquals("Returned false for same Character", 0, c.compareTo(c));
+        assertEquals("Returned false for identical Character",
+                0, c.compareTo(x));
+        assertTrue("Returned other than less than for lesser char", c
+                .compareTo(y) > 0);
+        assertTrue("Returned other than greater than for greater char", c
+                .compareTo(z) < 0);
+    }
+
+    /**
+     * java.lang.Character#digit(char, int)
+     */
+    public void test_digitCI() {
+        assertEquals("Returned incorrect digit", 1, Character.digit('1', 10));
+        assertEquals("Returned incorrect digit", 15, Character.digit('F', 16));
+    }
+
+    /**
+     * java.lang.Character#digit(int, int)
+     */
+    public void test_digit_II() {
+        assertEquals(1, Character.digit((int) '1', 10));
+        assertEquals(15, Character.digit((int) 'F', 16));
+
+        assertEquals(-1, Character.digit(0x0000, 37));
+        assertEquals(-1, Character.digit(0x0045, 10));
+
+        assertEquals(10, Character.digit(0x0041, 20));
+        assertEquals(10, Character.digit(0x0061, 20));
+
+        assertEquals(-1, Character.digit(0x110000, 20));
+    }
+
+    /**
+     * java.lang.Character#equals(java.lang.Object)
+     */
+    public void test_equalsLjava_lang_Object() {
+        // Test for method boolean java.lang.Character.equals(java.lang.Object)
+        assertTrue("Equality test failed", new Character('A')
+                .equals(new Character('A')));
+        assertTrue("Equality test failed", !(new Character('A')
+                .equals(new Character('a'))));
+    }
+
+    /**
+     * java.lang.Character#forDigit(int, int)
+     */
+    public void test_forDigitII() {
+        char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+                'a', 'b', 'c', 'd', 'e', 'f' };
+        for (int i = 0; i < hexChars.length; i++) {
+            assertTrue("Returned incorrect char for " + Integer.toString(i),
+                    Character.forDigit(i, hexChars.length) == hexChars[i]);
+        }
+
+        char decimalChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
+                '9' };
+        for (int i = 0; i < decimalChars.length; i++) {
+            assertTrue(
+                    "Returned incorrect char for " + Integer.toString(i),
+                    Character.forDigit(i, decimalChars.length) == decimalChars[i]);
+        }
+
+    }
+
+    /**
+     * java.lang.Character#getNumericValue(char)
+     */
+    public void test_getNumericValueC() {
+        assertEquals("Returned incorrect numeric value 1", 1, Character
+                .getNumericValue('1'));
+        assertEquals("Returned incorrect numeric value 2", 15, Character
+                .getNumericValue('F'));
+        assertEquals("Returned incorrect numeric value 3", -1, Character
+                .getNumericValue('\u221e'));
+        assertEquals("Returned incorrect numeric value 4", -2, Character
+                .getNumericValue('\u00be'));
+        assertEquals("Returned incorrect numeric value 5", 10000, Character
+                .getNumericValue('\u2182'));
+        assertEquals("Returned incorrect numeric value 6", 2, Character
+                .getNumericValue('\uff12'));
+    }
+
+    /**
+     * java.lang.Character#getNumericValue(int)
+     */
+    public void test_getNumericValue_I() {
+        assertEquals(1, Character.getNumericValue((int) '1'));
+        assertEquals(15, Character.getNumericValue((int) 'F'));
+        assertEquals(-1, Character.getNumericValue((int) '\u221e'));
+        assertEquals(-2, Character.getNumericValue((int) '\u00be'));
+        assertEquals(10000, Character.getNumericValue((int) '\u2182'));
+        assertEquals(2, Character.getNumericValue((int) '\uff12'));
+        assertEquals(-1, Character.getNumericValue(0xFFFF));
+
+        assertEquals(-1, Character.getNumericValue(0xFFFF));
+        assertEquals(0, Character.getNumericValue(0x1D7CE));
+        assertEquals(0, Character.getNumericValue(0x1D7D8));
+        assertEquals(-1, Character.getNumericValue(0x2F800));
+        assertEquals(-1, Character.getNumericValue(0x10FFFD));
+        assertEquals(-1, Character.getNumericValue(0x110000));
+
+        assertEquals(50, Character.getNumericValue(0x216C));
+
+        assertEquals(10, Character.getNumericValue(0x0041));
+        assertEquals(35, Character.getNumericValue(0x005A));
+        assertEquals(10, Character.getNumericValue(0x0061));
+        assertEquals(35, Character.getNumericValue(0x007A));
+        assertEquals(10, Character.getNumericValue(0xFF21));
+
+        //FIXME depends on ICU4J
+        //assertEquals(35, Character.getNumericValue(0xFF3A));
+
+        assertEquals(10, Character.getNumericValue(0xFF41));
+        assertEquals(35, Character.getNumericValue(0xFF5A));
+    }
+
+    /**
+     * java.lang.Character#getType(char)
+     */
+    public void test_getTypeC() {
+        assertTrue("Returned incorrect type for: \n",
+                Character.getType('\n') == Character.CONTROL);
+        assertTrue("Returned incorrect type for: 1",
+                Character.getType('1') == Character.DECIMAL_DIGIT_NUMBER);
+        assertTrue("Returned incorrect type for: ' '",
+                Character.getType(' ') == Character.SPACE_SEPARATOR);
+        assertTrue("Returned incorrect type for: a",
+                Character.getType('a') == Character.LOWERCASE_LETTER);
+        assertTrue("Returned incorrect type for: A",
+                Character.getType('A') == Character.UPPERCASE_LETTER);
+        assertTrue("Returned incorrect type for: <",
+                Character.getType('<') == Character.MATH_SYMBOL);
+        assertTrue("Returned incorrect type for: ;",
+                Character.getType(';') == Character.OTHER_PUNCTUATION);
+        assertTrue("Returned incorrect type for: _",
+                Character.getType('_') == Character.CONNECTOR_PUNCTUATION);
+        assertTrue("Returned incorrect type for: $",
+                Character.getType('$') == Character.CURRENCY_SYMBOL);
+        assertTrue("Returned incorrect type for: \u2029", Character
+                .getType('\u2029') == Character.PARAGRAPH_SEPARATOR);
+
+        assertEquals("Wrong constant for FORMAT", 16, Character.FORMAT);
+        assertEquals("Wrong constant for PRIVATE_USE",
+                18, Character.PRIVATE_USE);
+    }
+
+    /**
+     * java.lang.Character#getType(int)
+     */
+    public void test_getType_I() {
+        assertTrue(Character.getType((int) '\n') == Character.CONTROL);
+        assertTrue(Character.getType((int) '1') == Character.DECIMAL_DIGIT_NUMBER);
+        assertTrue(Character.getType((int) ' ') == Character.SPACE_SEPARATOR);
+        assertTrue(Character.getType((int) 'a') == Character.LOWERCASE_LETTER);
+        assertTrue(Character.getType((int) 'A') == Character.UPPERCASE_LETTER);
+        assertTrue(Character.getType((int) '<') == Character.MATH_SYMBOL);
+        assertTrue(Character.getType((int) ';') == Character.OTHER_PUNCTUATION);
+        assertTrue(Character.getType((int) '_') == Character.CONNECTOR_PUNCTUATION);
+        assertTrue(Character.getType((int) '$') == Character.CURRENCY_SYMBOL);
+        assertTrue(Character.getType((int) '\u2029') == Character.PARAGRAPH_SEPARATOR);
+
+        assertTrue(Character.getType(0x9FFF) == Character.UNASSIGNED);
+        assertTrue(Character.getType(0x30000) == Character.UNASSIGNED);
+        assertTrue(Character.getType(0x110000) == Character.UNASSIGNED);
+
+        assertTrue(Character.getType(0x0041) == Character.UPPERCASE_LETTER);
+        assertTrue(Character.getType(0x10400) == Character.UPPERCASE_LETTER);
+
+        assertTrue(Character.getType(0x0061) == Character.LOWERCASE_LETTER);
+        assertTrue(Character.getType(0x10428) == Character.LOWERCASE_LETTER);
+
+        assertTrue(Character.getType(0x01C5) == Character.TITLECASE_LETTER);
+        assertTrue(Character.getType(0x1FFC) == Character.TITLECASE_LETTER);
+
+        assertTrue(Character.getType(0x02B0) == Character.MODIFIER_LETTER);
+        assertTrue(Character.getType(0xFF9F) == Character.MODIFIER_LETTER);
+
+        assertTrue(Character.getType(0x01BB) == Character.OTHER_LETTER);
+        assertTrue(Character.getType(0x2F888) == Character.OTHER_LETTER);
+
+        assertTrue(Character.getType(0x0F82) == Character.NON_SPACING_MARK);
+        assertTrue(Character.getType(0x1D180) == Character.NON_SPACING_MARK);
+
+        assertTrue(Character.getType(0x0488) == Character.ENCLOSING_MARK);
+        assertTrue(Character.getType(0x20DE) == Character.ENCLOSING_MARK);
+
+        assertTrue(Character.getType(0x1938) == Character.COMBINING_SPACING_MARK);
+        assertTrue(Character.getType(0x1D165) == Character.COMBINING_SPACING_MARK);
+
+        assertTrue(Character.getType(0x194D) == Character.DECIMAL_DIGIT_NUMBER);
+        assertTrue(Character.getType(0x1D7CE) == Character.DECIMAL_DIGIT_NUMBER);
+
+        assertTrue(Character.getType(0x2160) == Character.LETTER_NUMBER);
+        assertTrue(Character.getType(0x1034A) == Character.LETTER_NUMBER);
+
+        assertTrue(Character.getType(0x00B2) == Character.OTHER_NUMBER);
+        assertTrue(Character.getType(0x10120) == Character.OTHER_NUMBER);
+
+        assertTrue(Character.getType(0x0020) == Character.SPACE_SEPARATOR);
+        assertTrue(Character.getType(0x3000) == Character.SPACE_SEPARATOR);
+
+        assertTrue(Character.getType(0x2028) == Character.LINE_SEPARATOR);
+
+        assertTrue(Character.getType(0x2029) == Character.PARAGRAPH_SEPARATOR);
+
+        assertTrue(Character.getType(0x0000) == Character.CONTROL);
+        assertTrue(Character.getType(0x009F) == Character.CONTROL);
+
+        assertTrue(Character.getType(0x00AD) == Character.FORMAT);
+        assertTrue(Character.getType(0xE007F) == Character.FORMAT);
+
+        assertTrue(Character.getType(0xE000) == Character.PRIVATE_USE);
+        assertTrue(Character.getType(0x10FFFD) == Character.PRIVATE_USE);
+
+        assertTrue(Character.getType(0xD800) == Character.SURROGATE);
+        assertTrue(Character.getType(0xDFFF) == Character.SURROGATE);
+
+        assertTrue(Character.getType(0xFE31) == Character.DASH_PUNCTUATION);
+        assertTrue(Character.getType(0xFF0D) == Character.DASH_PUNCTUATION);
+
+        assertTrue(Character.getType(0x0028) == Character.START_PUNCTUATION);
+        assertTrue(Character.getType(0xFF62) == Character.START_PUNCTUATION);
+
+        assertTrue(Character.getType(0x0029) == Character.END_PUNCTUATION);
+        assertTrue(Character.getType(0xFF63) == Character.END_PUNCTUATION);
+
+        assertTrue(Character.getType(0x005F) == Character.CONNECTOR_PUNCTUATION);
+        assertTrue(Character.getType(0xFF3F) == Character.CONNECTOR_PUNCTUATION);
+
+        assertTrue(Character.getType(0x2034) == Character.OTHER_PUNCTUATION);
+        assertTrue(Character.getType(0x1039F) == Character.OTHER_PUNCTUATION);
+
+        assertTrue(Character.getType(0x002B) == Character.MATH_SYMBOL);
+        assertTrue(Character.getType(0x1D6C1) == Character.MATH_SYMBOL);
+
+        assertTrue(Character.getType(0x0024) == Character.CURRENCY_SYMBOL);
+        assertTrue(Character.getType(0xFFE6) == Character.CURRENCY_SYMBOL);
+
+        assertTrue(Character.getType(0x005E) == Character.MODIFIER_SYMBOL);
+        assertTrue(Character.getType(0xFFE3) == Character.MODIFIER_SYMBOL);
+
+        assertTrue(Character.getType(0x00A6) == Character.OTHER_SYMBOL);
+        assertTrue(Character.getType(0x1D356) == Character.OTHER_SYMBOL);
+
+        assertTrue(Character.getType(0x00AB) == Character.INITIAL_QUOTE_PUNCTUATION);
+        assertTrue(Character.getType(0x2039) == Character.INITIAL_QUOTE_PUNCTUATION);
+
+        assertTrue(Character.getType(0x00BB) == Character.FINAL_QUOTE_PUNCTUATION);
+        assertTrue(Character.getType(0x203A) == Character.FINAL_QUOTE_PUNCTUATION);
+    }
+
+    /**
+     * java.lang.Character#hashCode()
+     */
+    public void test_hashCode() {
+        assertEquals("Incorrect hash returned",
+                89, new Character('Y').hashCode());
+    }
+
+    /**
+     * java.lang.Character#isDefined(char)
+     */
+    public void test_isDefinedC() {
+        assertTrue("Defined character returned false", Character.isDefined('v'));
+        assertTrue("Defined character returned false", Character
+                .isDefined('\u6039'));
+    }
+
+    /**
+     * java.lang.Character#isDefined(int)
+     */
+    public void test_isDefined_I() {
+        assertTrue(Character.isDefined((int) 'v'));
+        assertTrue(Character.isDefined((int) '\u6039'));
+        assertTrue(Character.isDefined(0x10300));
+
+        assertFalse(Character.isDefined(0x30000));
+        assertFalse(Character.isDefined(0x3FFFF));
+        assertFalse(Character.isDefined(0x110000));
+    }
+
+    /**
+     * java.lang.Character#isDigit(char)
+     */
+    public void test_isDigitC() {
+        assertTrue("Digit returned false", Character.isDigit('1'));
+        assertTrue("Non-Digit returned false", !Character.isDigit('A'));
+    }
+
+    /**
+     * java.lang.Character#isDigit(int)
+     */
+    public void test_isDigit_I() {
+        assertTrue(Character.isDigit((int) '1'));
+        assertFalse(Character.isDigit((int) 'A'));
+
+        assertTrue(Character.isDigit(0x0030));
+        assertTrue(Character.isDigit(0x0035));
+        assertTrue(Character.isDigit(0x0039));
+
+        assertTrue(Character.isDigit(0x0660));
+        assertTrue(Character.isDigit(0x0665));
+        assertTrue(Character.isDigit(0x0669));
+
+        assertTrue(Character.isDigit(0x06F0));
+        assertTrue(Character.isDigit(0x06F5));
+        assertTrue(Character.isDigit(0x06F9));
+
+        assertTrue(Character.isDigit(0x0966));
+        assertTrue(Character.isDigit(0x096A));
+        assertTrue(Character.isDigit(0x096F));
+
+        assertTrue(Character.isDigit(0xFF10));
+        assertTrue(Character.isDigit(0xFF15));
+        assertTrue(Character.isDigit(0xFF19));
+
+        assertTrue(Character.isDigit(0x1D7CE));
+        assertTrue(Character.isDigit(0x1D7D8));
+
+        assertFalse(Character.isDigit(0x2F800));
+        assertFalse(Character.isDigit(0x10FFFD));
+        assertFalse(Character.isDigit(0x110000));
+    }
+
+    /**
+     * java.lang.Character#isIdentifierIgnorable(char)
+     */
+    public void test_isIdentifierIgnorableC() {
+        assertTrue("Ignorable whitespace returned false", Character
+                .isIdentifierIgnorable('\u0007'));
+        assertTrue("Ignorable non - whitespace  control returned false",
+                Character.isIdentifierIgnorable('\u000f'));
+        assertTrue("Ignorable join control returned false", Character
+                .isIdentifierIgnorable('\u200e'));
+
+        // the spec is wrong, and our implementation is correct
+        assertTrue("Ignorable bidi control returned false", Character
+                .isIdentifierIgnorable('\u202b'));
+
+        assertTrue("Ignorable format control returned false", Character
+                .isIdentifierIgnorable('\u206c'));
+        assertTrue("Ignorable zero-width no-break returned false", Character
+                .isIdentifierIgnorable('\ufeff'));
+
+        assertTrue("Non-Ignorable returned true", !Character
+                .isIdentifierIgnorable('\u0065'));
+    }
+
+    /**
+     * java.lang.Character#isIdentifierIgnorable(int)
+     */
+    public void test_isIdentifierIgnorable_I() {
+        assertTrue(Character.isIdentifierIgnorable(0x0000));
+        assertTrue(Character.isIdentifierIgnorable(0x0004));
+        assertTrue(Character.isIdentifierIgnorable(0x0008));
+
+        assertTrue(Character.isIdentifierIgnorable(0x000E));
+        assertTrue(Character.isIdentifierIgnorable(0x0013));
+        assertTrue(Character.isIdentifierIgnorable(0x001B));
+
+        assertTrue(Character.isIdentifierIgnorable(0x007F));
+        assertTrue(Character.isIdentifierIgnorable(0x008F));
+        assertTrue(Character.isIdentifierIgnorable(0x009F));
+
+        assertTrue(Character.isIdentifierIgnorable(0x202b));
+        assertTrue(Character.isIdentifierIgnorable(0x206c));
+        assertTrue(Character.isIdentifierIgnorable(0xfeff));
+        assertFalse(Character.isIdentifierIgnorable(0x0065));
+
+        assertTrue(Character.isIdentifierIgnorable(0x1D173));
+
+        assertFalse(Character.isIdentifierIgnorable(0x10FFFD));
+        assertFalse(Character.isIdentifierIgnorable(0x110000));
+    }
+
+    /**
+     * java.lang.Character#isMirrored(char)
+     */
+    public void test_isMirrored_C() {
+        assertTrue(Character.isMirrored('\u0028'));
+        assertFalse(Character.isMirrored('\uFFFF'));
+    }
+
+    /**
+     * java.lang.Character#isMirrored(int)
+     */
+    public void test_isMirrored_I() {
+        assertTrue(Character.isMirrored(0x0028));
+        assertFalse(Character.isMirrored(0xFFFF));
+        assertFalse(Character.isMirrored(0x110000));
+    }
+
+    /**
+     * java.lang.Character#isISOControl(char)
+     */
+    public void test_isISOControlC() {
+        // Test for method boolean java.lang.Character.isISOControl(char)
+        for (int i = 0; i < 32; i++)
+            assertTrue("ISOConstrol char returned false", Character
+                    .isISOControl((char) i));
+
+        for (int i = 127; i < 160; i++)
+            assertTrue("ISOConstrol char returned false", Character
+                    .isISOControl((char) i));
+    }
+
+    /**
+     * java.lang.Character#isISOControl(int)
+     */
+    public void test_isISOControlI() {
+        // Test for method boolean java.lang.Character.isISOControl(char)
+        for (int i = 0; i < 32; i++)
+            assertTrue("ISOConstrol char returned false", Character
+                    .isISOControl(i));
+
+        for (int i = 127; i < 160; i++)
+            assertTrue("ISOConstrol char returned false", Character
+                    .isISOControl(i));
+
+        for (int i = 160; i < 260; i++)
+            assertFalse("Not ISOConstrol char returned true", Character
+                    .isISOControl(i));
+
+    }
+
+
+    /**
+     * java.lang.Character#isJavaIdentifierPart(char)
+     */
+    public void test_isJavaIdentifierPartC() {
+        assertTrue("letter returned false", Character.isJavaIdentifierPart('l'));
+        assertTrue("currency returned false", Character
+                .isJavaIdentifierPart('$'));
+        assertTrue("digit returned false", Character.isJavaIdentifierPart('9'));
+        assertTrue("connecting char returned false", Character
+                .isJavaIdentifierPart('_'));
+        assertTrue("ignorable control returned true", !Character
+                .isJavaIdentifierPart('\u200b'));
+        assertTrue("semi returned true", !Character.isJavaIdentifierPart(';'));
+    }
+
+    /**
+     * java.lang.Character#isJavaIdentifierPart(int)
+     */
+    public void test_isJavaIdentifierPart_I() {
+        assertTrue(Character.isJavaIdentifierPart((int) 'l'));
+        assertTrue(Character.isJavaIdentifierPart((int) '$'));
+        assertTrue(Character.isJavaIdentifierPart((int) '9'));
+        assertTrue(Character.isJavaIdentifierPart((int) '_'));
+        assertFalse(Character.isJavaIdentifierPart((int) ';'));
+
+        assertTrue(Character.isJavaIdentifierPart(0x0041));
+        assertTrue(Character.isJavaIdentifierPart(0x10400));
+        assertTrue(Character.isJavaIdentifierPart(0x0061));
+        assertTrue(Character.isJavaIdentifierPart(0x10428));
+        assertTrue(Character.isJavaIdentifierPart(0x01C5));
+        assertTrue(Character.isJavaIdentifierPart(0x1FFC));
+        assertTrue(Character.isJavaIdentifierPart(0x02B0));
+        assertTrue(Character.isJavaIdentifierPart(0xFF9F));
+        assertTrue(Character.isJavaIdentifierPart(0x01BB));
+        assertTrue(Character.isJavaIdentifierPart(0x2F888));
+
+        assertTrue(Character.isJavaIdentifierPart(0x0024));
+        assertTrue(Character.isJavaIdentifierPart(0xFFE6));
+
+        assertTrue(Character.isJavaIdentifierPart(0x005F));
+        assertTrue(Character.isJavaIdentifierPart(0xFF3F));
+
+        assertTrue(Character.isJavaIdentifierPart(0x194D));
+        assertTrue(Character.isJavaIdentifierPart(0x1D7CE));
+        assertTrue(Character.isJavaIdentifierPart(0x2160));
+        assertTrue(Character.isJavaIdentifierPart(0x1034A));
+
+        assertTrue(Character.isJavaIdentifierPart(0x0F82));
+        assertTrue(Character.isJavaIdentifierPart(0x1D180));
+
+        assertTrue(Character.isJavaIdentifierPart(0x0000));
+        assertTrue(Character.isJavaIdentifierPart(0x0008));
+        assertTrue(Character.isJavaIdentifierPart(0x000E));
+        assertTrue(Character.isJavaIdentifierPart(0x001B));
+        assertTrue(Character.isJavaIdentifierPart(0x007F));
+        assertTrue(Character.isJavaIdentifierPart(0x009F));
+        assertTrue(Character.isJavaIdentifierPart(0x00AD));
+        assertTrue(Character.isJavaIdentifierPart(0xE007F));
+
+        //RI fails because 0x200B changes category in Unicode 4.1
+        assertTrue(Character.isJavaIdentifierPart(0x200B));
+    }
+
+    /**
+     * java.lang.Character#isJavaIdentifierStart(char)
+     */
+    public void test_isJavaIdentifierStartC() {
+        assertTrue("letter returned false", Character
+                .isJavaIdentifierStart('l'));
+        assertTrue("currency returned false", Character
+                .isJavaIdentifierStart('$'));
+        assertTrue("connecting char returned false", Character
+                .isJavaIdentifierStart('_'));
+        assertTrue("digit returned true", !Character.isJavaIdentifierStart('9'));
+        assertTrue("ignorable control returned true", !Character
+                .isJavaIdentifierStart('\u200b'));
+        assertTrue("semi returned true", !Character.isJavaIdentifierStart(';'));
+    }
+
+    /**
+     * java.lang.Character#isJavaIdentifierStart(int)
+     */
+    public void test_isJavaIdentifierStart_I() {
+        assertTrue(Character.isJavaIdentifierStart((int) 'l'));
+        assertTrue(Character.isJavaIdentifierStart((int) '$'));
+        assertTrue(Character.isJavaIdentifierStart((int) '_'));
+        assertFalse(Character.isJavaIdentifierStart((int) '9'));
+        assertFalse(Character.isJavaIdentifierStart((int) '\u200b'));
+        assertFalse(Character.isJavaIdentifierStart((int) ';'));
+
+        assertTrue(Character.isJavaIdentifierStart(0x0041));
+        assertTrue(Character.isJavaIdentifierStart(0x10400));
+        assertTrue(Character.isJavaIdentifierStart(0x0061));
+        assertTrue(Character.isJavaIdentifierStart(0x10428));
+        assertTrue(Character.isJavaIdentifierStart(0x01C5));
+        assertTrue(Character.isJavaIdentifierStart(0x1FFC));
+        assertTrue(Character.isJavaIdentifierStart(0x02B0));
+        assertTrue(Character.isJavaIdentifierStart(0xFF9F));
+        assertTrue(Character.isJavaIdentifierStart(0x01BB));
+        assertTrue(Character.isJavaIdentifierStart(0x2F888));
+
+        assertTrue(Character.isJavaIdentifierPart(0x0024));
+        assertTrue(Character.isJavaIdentifierPart(0xFFE6));
+
+        assertTrue(Character.isJavaIdentifierPart(0x005F));
+        assertTrue(Character.isJavaIdentifierPart(0xFF3F));
+
+        assertTrue(Character.isJavaIdentifierPart(0x2160));
+        assertTrue(Character.isJavaIdentifierPart(0x1034A));
+
+        assertFalse(Character.isJavaIdentifierPart(0x110000));
+    }
+
+    /**
+     * java.lang.Character#isJavaLetter(char)
+     */
+    @SuppressWarnings("deprecation")
+    public void test_isJavaLetterC() {
+        assertTrue("letter returned false", Character.isJavaLetter('l'));
+        assertTrue("currency returned false", Character.isJavaLetter('$'));
+        assertTrue("connecting char returned false", Character
+                .isJavaLetter('_'));
+
+        assertTrue("digit returned true", !Character.isJavaLetter('9'));
+        assertTrue("ignored control returned true", !Character
+                .isJavaLetter('\u200b'));
+        assertTrue("semi returned true", !Character.isJavaLetter(';'));
+    }
+
+    /**
+     * java.lang.Character#isJavaLetterOrDigit(char)
+     */
+    @SuppressWarnings("deprecation")
+    public void test_isJavaLetterOrDigitC() {
+        assertTrue("letter returned false", Character.isJavaLetterOrDigit('l'));
+        assertTrue("currency returned false", Character
+                .isJavaLetterOrDigit('$'));
+        assertTrue("digit returned false", Character.isJavaLetterOrDigit('9'));
+        assertTrue("connecting char returned false", Character
+                .isJavaLetterOrDigit('_'));
+        assertTrue("semi returned true", !Character.isJavaLetterOrDigit(';'));
+    }
+
+    /**
+     * java.lang.Character#isLetter(char)
+     */
+    public void test_isLetterC() {
+        assertTrue("Letter returned false", Character.isLetter('L'));
+        assertTrue("Non-Letter returned true", !Character.isLetter('9'));
+    }
+
+    /**
+     * java.lang.Character#isLetter(int)
+     */
+    public void test_isLetter_I() {
+        assertTrue(Character.isLetter((int) 'L'));
+        assertFalse(Character.isLetter((int) '9'));
+
+        assertTrue(Character.isLetter(0x1FA9));
+        assertTrue(Character.isLetter(0x1D400));
+        assertTrue(Character.isLetter(0x1D622));
+        assertTrue(Character.isLetter(0x10000));
+
+        assertFalse(Character.isLetter(0x1012C));
+        assertFalse(Character.isLetter(0x110000));
+    }
+
+    /**
+     * java.lang.Character#isLetterOrDigit(char)
+     */
+    public void test_isLetterOrDigitC() {
+        assertTrue("Digit returned false", Character.isLetterOrDigit('9'));
+        assertTrue("Letter returned false", Character.isLetterOrDigit('K'));
+        assertTrue("Control returned true", !Character.isLetterOrDigit('\n'));
+        assertTrue("Punctuation returned true", !Character.isLetterOrDigit('?'));
+    }
+
+    /**
+     * java.lang.Character#isLetterOrDigit(int)
+     */
+    public void test_isLetterOrDigit_I() {
+        assertTrue(Character.isLetterOrDigit((int) '9'));
+        assertTrue(Character.isLetterOrDigit((int) 'K'));
+        assertFalse(Character.isLetterOrDigit((int) '\n'));
+        assertFalse(Character.isLetterOrDigit((int) '?'));
+
+        assertTrue(Character.isLetterOrDigit(0x1FA9));
+        assertTrue(Character.isLetterOrDigit(0x1D400));
+        assertTrue(Character.isLetterOrDigit(0x1D622));
+        assertTrue(Character.isLetterOrDigit(0x10000));
+
+        assertTrue(Character.isLetterOrDigit(0x1D7CE));
+        assertTrue(Character.isLetterOrDigit(0x1D7D8));
+
+        assertFalse(Character.isLetterOrDigit(0x10FFFD));
+        assertFalse(Character.isLetterOrDigit(0x1012C));
+        assertFalse(Character.isLetterOrDigit(0x110000));
+    }
+
+    /**
+     * java.lang.Character#isLowerCase(char)
+     */
+    public void test_isLowerCaseC() {
+        assertTrue("lower returned false", Character.isLowerCase('a'));
+        assertTrue("upper returned true", !Character.isLowerCase('T'));
+    }
+
+    /**
+     * java.lang.Character#isLowerCase(int)
+     */
+    public void test_isLowerCase_I() {
+        assertTrue(Character.isLowerCase((int) 'a'));
+        assertFalse(Character.isLowerCase((int) 'T'));
+
+        assertTrue(Character.isLowerCase(0x10428));
+        assertTrue(Character.isLowerCase(0x1D4EA));
+
+        assertFalse(Character.isLowerCase(0x1D504));
+        assertFalse(Character.isLowerCase(0x30000));
+        assertFalse(Character.isLowerCase(0x110000));
+    }
+
+    /**
+     * java.lang.Character#isSpace(char)
+     */
+    @SuppressWarnings("deprecation")
+    public void test_isSpaceC() {
+        // Test for method boolean java.lang.Character.isSpace(char)
+        assertTrue("space returned false", Character.isSpace('\n'));
+        assertTrue("non-space returned true", !Character.isSpace('T'));
+    }
+
+    /**
+     * java.lang.Character#isSpaceChar(char)
+     */
+    public void test_isSpaceCharC() {
+        assertTrue("space returned false", Character.isSpaceChar('\u0020'));
+        assertTrue("non-space returned true", !Character.isSpaceChar('\n'));
+    }
+
+    /**
+     * java.lang.Character#isSpaceChar(int)
+     */
+    public void test_isSpaceChar_I() {
+        assertTrue(Character.isSpaceChar((int) '\u0020'));
+        assertFalse(Character.isSpaceChar((int) '\n'));
+
+        assertTrue(Character.isSpaceChar(0x2000));
+        assertTrue(Character.isSpaceChar(0x200A));
+
+        assertTrue(Character.isSpaceChar(0x2028));
+        assertTrue(Character.isSpaceChar(0x2029));
+
+        assertFalse(Character.isSpaceChar(0x110000));
+    }
+
+    /**
+     * java.lang.Character#isTitleCase(char)
+     */
+    public void test_isTitleCaseC() {
+        char[] tChars = { (char) 0x01c5, (char) 0x01c8, (char) 0x01cb,
+                (char) 0x01f2, (char) 0x1f88, (char) 0x1f89, (char) 0x1f8a,
+                (char) 0x1f8b, (char) 0x1f8c, (char) 0x1f8d, (char) 0x1f8e,
+                (char) 0x1f8f, (char) 0x1f98, (char) 0x1f99, (char) 0x1f9a,
+                (char) 0x1f9b, (char) 0x1f9c, (char) 0x1f9d, (char) 0x1f9e,
+                (char) 0x1f9f, (char) 0x1fa8, (char) 0x1fa9, (char) 0x1faa,
+                (char) 0x1fab, (char) 0x1fac, (char) 0x1fad, (char) 0x1fae,
+                (char) 0x1faf, (char) 0x1fbc, (char) 0x1fcc, (char) 0x1ffc };
+        byte tnum = 0;
+        for (char c = 0; c < 65535; c++) {
+            if (Character.isTitleCase(c)) {
+                tnum++;
+                int i;
+                for (i = 0; i < tChars.length; i++)
+                    if (tChars[i] == c)
+                        i = tChars.length + 1;
+                if (i < tChars.length) {
+                    fail("Non Title Case char returned true");
+                }
+            }
+        }
+        assertTrue("Failed to find all Title Case chars", tnum == tChars.length);
+    }
+
+    /**
+     * java.lang.Character#isTitleCase(int)
+     */
+    public void test_isTitleCase_I() {
+        //all the titlecase characters
+        int[] titleCaseCharacters = { 0x01c5, 0x01c8, 0x01cb, 0x01f2, 0x1f88,
+                0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f, 0x1f98,
+                0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f, 0x1fa8,
+                0x1fa9, 0x1faa, 0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf, 0x1fbc,
+                0x1fcc, 0x1ffc };
+
+        for (int i = 0; i < titleCaseCharacters.length; i++) {
+            assertTrue(Character.isTitleCase(titleCaseCharacters[i]));
+        }
+
+        assertFalse(Character.isTitleCase(0x110000));
+    }
+
+    /**
+     * java.lang.Character#isUnicodeIdentifierPart(char)
+     */
+    public void test_isUnicodeIdentifierPartC() {
+        assertTrue("'a' returned false", Character.isUnicodeIdentifierPart('a'));
+        assertTrue("'2' returned false", Character.isUnicodeIdentifierPart('2'));
+        assertTrue("'+' returned true", !Character.isUnicodeIdentifierPart('+'));
+    }
+
+    /**
+     * java.lang.Character#isUnicodeIdentifierPart(int)
+     */
+    public void test_isUnicodeIdentifierPart_I() {
+        assertTrue(Character.isUnicodeIdentifierPart((int) 'a'));
+        assertTrue(Character.isUnicodeIdentifierPart((int) '2'));
+        assertFalse(Character.isUnicodeIdentifierPart((int) '+'));
+
+        assertTrue(Character.isUnicodeIdentifierPart(0x1FA9));
+        assertTrue(Character.isUnicodeIdentifierPart(0x1D400));
+        assertTrue(Character.isUnicodeIdentifierPart(0x1D622));
+        assertTrue(Character.isUnicodeIdentifierPart(0x10000));
+
+        assertTrue(Character.isUnicodeIdentifierPart(0x0030));
+        assertTrue(Character.isUnicodeIdentifierPart(0x0035));
+        assertTrue(Character.isUnicodeIdentifierPart(0x0039));
+
+        assertTrue(Character.isUnicodeIdentifierPart(0x0660));
+        assertTrue(Character.isUnicodeIdentifierPart(0x0665));
+        assertTrue(Character.isUnicodeIdentifierPart(0x0669));
+
+        assertTrue(Character.isUnicodeIdentifierPart(0x06F0));
+        assertTrue(Character.isUnicodeIdentifierPart(0x06F5));
+        assertTrue(Character.isUnicodeIdentifierPart(0x06F9));
+
+        assertTrue(Character.isUnicodeIdentifierPart(0x0966));
+        assertTrue(Character.isUnicodeIdentifierPart(0x096A));
+        assertTrue(Character.isUnicodeIdentifierPart(0x096F));
+
+        assertTrue(Character.isUnicodeIdentifierPart(0xFF10));
+        assertTrue(Character.isUnicodeIdentifierPart(0xFF15));
+        assertTrue(Character.isUnicodeIdentifierPart(0xFF19));
+
+        assertTrue(Character.isUnicodeIdentifierPart(0x1D7CE));
+        assertTrue(Character.isUnicodeIdentifierPart(0x1D7D8));
+
+        assertTrue(Character.isUnicodeIdentifierPart(0x16EE));
+        assertTrue(Character.isUnicodeIdentifierPart(0xFE33));
+        assertTrue(Character.isUnicodeIdentifierPart(0xFF10));
+        assertTrue(Character.isUnicodeIdentifierPart(0x1D165));
+        assertTrue(Character.isUnicodeIdentifierPart(0x1D167));
+        assertTrue(Character.isUnicodeIdentifierPart(0x1D173));
+
+        assertFalse(Character.isUnicodeIdentifierPart(0x10FFFF));
+        assertFalse(Character.isUnicodeIdentifierPart(0x110000));
+    }
+
+    /**
+     * java.lang.Character#isUnicodeIdentifierStart(char)
+     */
+    public void test_isUnicodeIdentifierStartC() {
+        assertTrue("'a' returned false", Character
+                .isUnicodeIdentifierStart('a'));
+        assertTrue("'2' returned true", !Character
+                .isUnicodeIdentifierStart('2'));
+        assertTrue("'+' returned true", !Character
+                .isUnicodeIdentifierStart('+'));
+    }
+
+    /**
+     * java.lang.Character#isUnicodeIdentifierStart(int)
+     */
+    public void test_isUnicodeIdentifierStart_I() {
+
+        assertTrue(Character.isUnicodeIdentifierStart((int) 'a'));
+        assertFalse(Character.isUnicodeIdentifierStart((int) '2'));
+        assertFalse(Character.isUnicodeIdentifierStart((int) '+'));
+
+        assertTrue(Character.isUnicodeIdentifierStart(0x1FA9));
+        assertTrue(Character.isUnicodeIdentifierStart(0x1D400));
+        assertTrue(Character.isUnicodeIdentifierStart(0x1D622));
+        assertTrue(Character.isUnicodeIdentifierStart(0x10000));
+
+        assertTrue(Character.isUnicodeIdentifierStart(0x16EE));
+
+        // number is not a valid start of a Unicode identifier
+        assertFalse(Character.isUnicodeIdentifierStart(0x0030));
+        assertFalse(Character.isUnicodeIdentifierStart(0x0039));
+        assertFalse(Character.isUnicodeIdentifierStart(0x0660));
+        assertFalse(Character.isUnicodeIdentifierStart(0x0669));
+        assertFalse(Character.isUnicodeIdentifierStart(0x06F0));
+        assertFalse(Character.isUnicodeIdentifierStart(0x06F9));
+
+        assertFalse(Character.isUnicodeIdentifierPart(0x10FFFF));
+        assertFalse(Character.isUnicodeIdentifierPart(0x110000));
+    }
+
+    /**
+     * java.lang.Character#isUpperCase(char)
+     */
+    public void test_isUpperCaseC() {
+        assertTrue("Incorrect case value", !Character.isUpperCase('t'));
+        assertTrue("Incorrect case value", Character.isUpperCase('T'));
+    }
+
+    /**
+     * java.lang.Character#isUpperCase(int)
+     */
+    public void test_isUpperCase_I() {
+        assertFalse(Character.isUpperCase((int) 't'));
+        assertTrue(Character.isUpperCase((int) 'T'));
+
+        assertTrue(Character.isUpperCase(0x1D504));
+        assertTrue(Character.isUpperCase(0x1D608));
+
+        assertFalse(Character.isUpperCase(0x1D656));
+        assertFalse(Character.isUpperCase(0x10FFFD));
+        assertFalse(Character.isUpperCase(0x110000));
+    }
+
+    /**
+     * java.lang.Character#isWhitespace(char)
+     */
+    public void test_isWhitespaceC() {
+        assertTrue("space returned false", Character.isWhitespace('\n'));
+        assertTrue("non-space returned true", !Character.isWhitespace('T'));
+    }
+
+    /**
+     * java.lang.Character#isWhitespace(int)
+     */
+    public void test_isWhitespace_I() {
+        assertTrue(Character.isWhitespace((int) '\n'));
+        assertFalse(Character.isWhitespace((int) 'T'));
+
+        assertTrue(Character.isWhitespace(0x0009));
+        assertTrue(Character.isWhitespace(0x000A));
+        assertTrue(Character.isWhitespace(0x000B));
+        assertTrue(Character.isWhitespace(0x000C));
+        assertTrue(Character.isWhitespace(0x000D));
+        assertTrue(Character.isWhitespace(0x001C));
+        assertTrue(Character.isWhitespace(0x001D));
+        assertTrue(Character.isWhitespace(0x001F));
+        assertTrue(Character.isWhitespace(0x001E));
+
+        assertTrue(Character.isWhitespace(0x2000));
+        assertTrue(Character.isWhitespace(0x200A));
+
+        assertTrue(Character.isWhitespace(0x2028));
+        assertTrue(Character.isWhitespace(0x2029));
+
+        assertFalse(Character.isWhitespace(0x00A0));
+        assertFalse(Character.isWhitespace(0x202F));
+        assertFalse(Character.isWhitespace(0x110000));
+
+        assertFalse(Character.isWhitespace(0xFEFF));
+
+        //FIXME depend on ICU4J
+        //assertFalse(Character.isWhitespace(0x2007));
+
+    }
+
+    /**
+     * java.lang.Character#reverseBytes(char)
+     */
+    public void test_reverseBytesC() {
+        char original[] = new char[] { 0x0000, 0x0010, 0x00AA, 0xB000, 0xCC00, 0xABCD, 0xFFAA };
+        char reversed[] = new char[] { 0x0000, 0x1000, 0xAA00, 0x00B0, 0x00CC, 0xCDAB, 0xAAFF };
+        assertTrue("Test self check", original.length == reversed.length);
+
+        for (int i = 0; i < original.length; i++) {
+            char origChar = original[i];
+            char reversedChar = reversed[i];
+            char origReversed = Character.reverseBytes(origChar);
+
+            assertTrue("java.lang.Character.reverseBytes failed: orig char="
+                    + Integer.toHexString(origChar) + ", reversed char="
+                    + Integer.toHexString(origReversed), reversedChar == origReversed);
+        }
+    }
+
+    /**
+     * java.lang.Character#toLowerCase(char)
+     */
+    public void test_toLowerCaseC() {
+        assertEquals("Failed to change case", 't', Character.toLowerCase('T'));
+    }
+
+    /**
+     * java.lang.Character#toLowerCase(int)
+     */
+    public void test_toLowerCase_I() {
+        assertEquals('t', Character.toLowerCase((int) 'T'));
+
+        assertEquals(0x10428, Character.toLowerCase(0x10400));
+        assertEquals(0x10428, Character.toLowerCase(0x10428));
+
+        assertEquals(0x1D504, Character.toLowerCase(0x1D504));
+        assertEquals(0x10FFFD, Character.toLowerCase(0x10FFFD));
+        assertEquals(0x110000, Character.toLowerCase(0x110000));
+    }
+
+    /**
+     * java.lang.Character#toString()
+     */
+    public void test_toString() {
+        assertEquals("Incorrect String returned", "T", new Character('T').toString());
+    }
+
+    /**
+     * java.lang.Character#toTitleCase(char)
+     */
+    public void test_toTitleCaseC() {
+        assertEquals("Incorrect title case for a",
+                'A', Character.toTitleCase('a'));
+        assertEquals("Incorrect title case for A",
+                'A', Character.toTitleCase('A'));
+        assertEquals("Incorrect title case for 1",
+                '1', Character.toTitleCase('1'));
+    }
+
+    /**
+     * java.lang.Character#toTitleCase(int)
+     */
+    public void test_toTitleCase_I() {
+        assertEquals('A', Character.toTitleCase((int) 'a'));
+        assertEquals('A', Character.toTitleCase((int) 'A'));
+        assertEquals('1', Character.toTitleCase((int) '1'));
+
+        assertEquals(0x10400, Character.toTitleCase(0x10428));
+        assertEquals(0x10400, Character.toTitleCase(0x10400));
+
+        assertEquals(0x10FFFF, Character.toTitleCase(0x10FFFF));
+        assertEquals(0x110000, Character.toTitleCase(0x110000));
+    }
+
+    /**
+     * java.lang.Character#toUpperCase(char)
+     */
+    public void test_toUpperCaseC() {
+        // Test for method char java.lang.Character.toUpperCase(char)
+        assertEquals("Incorrect upper case for a",
+                'A', Character.toUpperCase('a'));
+        assertEquals("Incorrect upper case for A",
+                'A', Character.toUpperCase('A'));
+        assertEquals("Incorrect upper case for 1",
+                '1', Character.toUpperCase('1'));
+    }
+
+    /**
+     * java.lang.Character#toUpperCase(int)
+     */
+    public void test_toUpperCase_I() {
+        assertEquals('A', Character.toUpperCase((int) 'a'));
+        assertEquals('A', Character.toUpperCase((int) 'A'));
+        assertEquals('1', Character.toUpperCase((int) '1'));
+
+        assertEquals(0x10400, Character.toUpperCase(0x10428));
+        assertEquals(0x10400, Character.toUpperCase(0x10400));
+
+        assertEquals(0x10FFFF, Character.toUpperCase(0x10FFFF));
+        assertEquals(0x110000, Character.toUpperCase(0x110000));
+    }
+
+    /**
+     * java.lang.Character#getDirectionality(int)
+     */
+    public void test_isDirectionaliy_I() {
+        assertEquals(Character.DIRECTIONALITY_UNDEFINED, Character
+                .getDirectionality(0xFFFE));
+        assertEquals(Character.DIRECTIONALITY_UNDEFINED, Character
+                .getDirectionality(0x30000));
+        assertEquals(Character.DIRECTIONALITY_UNDEFINED, Character
+                .getDirectionality(0x110000));
+        assertEquals(Character.DIRECTIONALITY_UNDEFINED, Character
+                .getDirectionality(-1));
+
+        assertEquals(Character.DIRECTIONALITY_LEFT_TO_RIGHT, Character
+                .getDirectionality(0x0041));
+        assertEquals(Character.DIRECTIONALITY_LEFT_TO_RIGHT, Character
+                .getDirectionality(0x10000));
+        assertEquals(Character.DIRECTIONALITY_LEFT_TO_RIGHT, Character
+                .getDirectionality(0x104A9));
+
+        assertEquals(Character.DIRECTIONALITY_RIGHT_TO_LEFT, Character
+                .getDirectionality(0xFB4F));
+        assertEquals(Character.DIRECTIONALITY_RIGHT_TO_LEFT, Character
+                .getDirectionality(0x10838));
+        // Unicode standard 5.1 changed category of unicode point 0x0600 from AL to AN
+        assertEquals(Character.DIRECTIONALITY_ARABIC_NUMBER, Character
+                .getDirectionality(0x0600));
+        assertEquals(Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC, Character
+                .getDirectionality(0xFEFC));
+
+        assertEquals(Character.DIRECTIONALITY_EUROPEAN_NUMBER, Character
+                .getDirectionality(0x2070));
+        assertEquals(Character.DIRECTIONALITY_EUROPEAN_NUMBER, Character
+                .getDirectionality(0x1D7FF));
+
+        //RI fails ,this is non-bug difference between Unicode 4.0 and 4.1
+        assertEquals(Character.DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR, Character
+                .getDirectionality(0x002B));
+        assertEquals(Character.DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR, Character
+                .getDirectionality(0xFF0B));
+
+        assertEquals(Character.DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR, Character
+                .getDirectionality(0x0023));
+        assertEquals(Character.DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR, Character
+                .getDirectionality(0x17DB));
+
+        assertEquals(Character.DIRECTIONALITY_ARABIC_NUMBER, Character
+                .getDirectionality(0x0660));
+        assertEquals(Character.DIRECTIONALITY_ARABIC_NUMBER, Character
+                .getDirectionality(0x066C));
+
+        assertEquals(Character.DIRECTIONALITY_COMMON_NUMBER_SEPARATOR, Character
+                .getDirectionality(0x002C));
+        assertEquals(Character.DIRECTIONALITY_COMMON_NUMBER_SEPARATOR, Character
+                .getDirectionality(0xFF1A));
+
+        assertEquals(Character.DIRECTIONALITY_NONSPACING_MARK, Character
+                .getDirectionality(0x17CE));
+        assertEquals(Character.DIRECTIONALITY_NONSPACING_MARK, Character
+                .getDirectionality(0xE01DB));
+
+        assertEquals(Character.DIRECTIONALITY_BOUNDARY_NEUTRAL, Character
+                .getDirectionality(0x0000));
+        assertEquals(Character.DIRECTIONALITY_BOUNDARY_NEUTRAL, Character
+                .getDirectionality(0xE007F));
+
+        assertEquals(Character.DIRECTIONALITY_PARAGRAPH_SEPARATOR, Character
+                .getDirectionality(0x000A));
+        assertEquals(Character.DIRECTIONALITY_PARAGRAPH_SEPARATOR, Character
+                .getDirectionality(0x2029));
+
+        assertEquals(Character.DIRECTIONALITY_SEGMENT_SEPARATOR, Character
+                .getDirectionality(0x0009));
+        assertEquals(Character.DIRECTIONALITY_SEGMENT_SEPARATOR, Character
+                .getDirectionality(0x001F));
+
+        assertEquals(Character.DIRECTIONALITY_WHITESPACE, Character
+                .getDirectionality(0x0020));
+        assertEquals(Character.DIRECTIONALITY_WHITESPACE, Character
+                .getDirectionality(0x3000));
+
+        assertEquals(Character.DIRECTIONALITY_OTHER_NEUTRALS, Character
+                .getDirectionality(0x2FF0));
+        assertEquals(Character.DIRECTIONALITY_OTHER_NEUTRALS, Character
+                .getDirectionality(0x1D356));
+
+        assertEquals(Character.DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING, Character
+                .getDirectionality(0x202A));
+
+        assertEquals(Character.DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE, Character
+                .getDirectionality(0x202D));
+
+        assertEquals(Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING, Character
+                .getDirectionality(0x202B));
+
+        assertEquals(Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE, Character
+                .getDirectionality(0x202E));
+
+        assertEquals(Character.DIRECTIONALITY_POP_DIRECTIONAL_FORMAT, Character
+                .getDirectionality(0x202C));
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/Character_SubsetTest.java b/luni/src/test/java/tests/api/java/lang/Character_SubsetTest.java
new file mode 100644
index 0000000..7a271da
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/Character_SubsetTest.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 tests.api.java.lang;
+
+import junit.framework.TestCase;
+
+public class Character_SubsetTest extends TestCase {
+
+    /**
+     * java.lang.Character.Subset#Character.Subset(java.lang.String)
+     */
+    public void test_Ctor() {
+
+        try {
+            // Regression for HARMONY-888
+            new Character.Subset(null) {
+            };
+            fail("No expected NullPointerException");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    /**
+     * java.lang.Character.Subset#toString()
+     */
+    public void test_toString() {
+
+        String name = "name";
+        Character.Subset subset = new Character.Subset(name) {
+        };
+        assertSame(name, subset.toString());
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/lang/Character_UnicodeBlockTest.java b/luni/src/test/java/tests/api/java/lang/Character_UnicodeBlockTest.java
new file mode 100644
index 0000000..bc40b2c
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/Character_UnicodeBlockTest.java
@@ -0,0 +1,880 @@
+/* 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.lang;
+
+import junit.framework.TestCase;
+
+public class Character_UnicodeBlockTest extends TestCase {
+
+    public void test_ofC() {
+        assertEquals(Character.UnicodeBlock.BASIC_LATIN, Character.UnicodeBlock.of((char) 0x0));
+        assertEquals(Character.UnicodeBlock.BASIC_LATIN, Character.UnicodeBlock.of((char) 0x7f));
+        assertEquals(Character.UnicodeBlock.LATIN_1_SUPPLEMENT, Character.UnicodeBlock.of((char) 0x80));
+        assertEquals(Character.UnicodeBlock.LATIN_1_SUPPLEMENT, Character.UnicodeBlock.of((char) 0xff));
+        assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_A, Character.UnicodeBlock.of((char) 0x100));
+        assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_A, Character.UnicodeBlock.of((char) 0x17f));
+        assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_B, Character.UnicodeBlock.of((char) 0x180));
+        assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_B, Character.UnicodeBlock.of((char) 0x24f));
+        assertEquals(Character.UnicodeBlock.IPA_EXTENSIONS, Character.UnicodeBlock.of((char) 0x250));
+        assertEquals(Character.UnicodeBlock.IPA_EXTENSIONS, Character.UnicodeBlock.of((char) 0x2af));
+        assertEquals(Character.UnicodeBlock.SPACING_MODIFIER_LETTERS, Character.UnicodeBlock.of((char) 0x2b0));
+        assertEquals(Character.UnicodeBlock.SPACING_MODIFIER_LETTERS, Character.UnicodeBlock.of((char) 0x2ff));
+        assertEquals(Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS, Character.UnicodeBlock.of((char) 0x300));
+        assertEquals(Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS, Character.UnicodeBlock.of((char) 0x36f));
+        assertEquals(Character.UnicodeBlock.GREEK, Character.UnicodeBlock.of((char) 0x370));
+        assertEquals(Character.UnicodeBlock.GREEK, Character.UnicodeBlock.of((char) 0x3ff));
+        assertEquals(Character.UnicodeBlock.CYRILLIC, Character.UnicodeBlock.of((char) 0x400));
+        assertEquals(Character.UnicodeBlock.CYRILLIC, Character.UnicodeBlock.of((char) 0x4ff));
+        assertEquals(Character.UnicodeBlock.CYRILLIC_SUPPLEMENTARY, Character.UnicodeBlock.of((char) 0x500));
+        assertEquals(Character.UnicodeBlock.CYRILLIC_SUPPLEMENTARY, Character.UnicodeBlock.of((char) 0x52f));
+        assertEquals(Character.UnicodeBlock.ARMENIAN, Character.UnicodeBlock.of((char) 0x530));
+        assertEquals(Character.UnicodeBlock.ARMENIAN, Character.UnicodeBlock.of((char) 0x58f));
+        assertEquals(Character.UnicodeBlock.HEBREW, Character.UnicodeBlock.of((char) 0x590));
+        assertEquals(Character.UnicodeBlock.HEBREW, Character.UnicodeBlock.of((char) 0x5ff));
+        assertEquals(Character.UnicodeBlock.ARABIC, Character.UnicodeBlock.of((char) 0x600));
+        assertEquals(Character.UnicodeBlock.ARABIC, Character.UnicodeBlock.of((char) 0x6ff));
+        assertEquals(Character.UnicodeBlock.SYRIAC, Character.UnicodeBlock.of((char) 0x700));
+        assertEquals(Character.UnicodeBlock.SYRIAC, Character.UnicodeBlock.of((char) 0x74f));
+        assertNull(Character.UnicodeBlock.of((char) 0x750));
+        assertNull(Character.UnicodeBlock.of((char) 0x77f));
+        assertEquals(Character.UnicodeBlock.THAANA, Character.UnicodeBlock.of((char) 0x780));
+        assertEquals(Character.UnicodeBlock.THAANA, Character.UnicodeBlock.of((char) 0x7bf));
+        assertNull(Character.UnicodeBlock.of((char) 0x7c0));
+        assertNull(Character.UnicodeBlock.of((char) 0x8ff));
+        assertEquals(Character.UnicodeBlock.DEVANAGARI, Character.UnicodeBlock.of((char) 0x900));
+        assertEquals(Character.UnicodeBlock.DEVANAGARI, Character.UnicodeBlock.of((char) 0x97f));
+        assertEquals(Character.UnicodeBlock.BENGALI, Character.UnicodeBlock.of((char) 0x980));
+        assertEquals(Character.UnicodeBlock.BENGALI, Character.UnicodeBlock.of((char) 0x9ff));
+        assertEquals(Character.UnicodeBlock.GURMUKHI, Character.UnicodeBlock.of((char) 0xa00));
+        assertEquals(Character.UnicodeBlock.GURMUKHI, Character.UnicodeBlock.of((char) 0xa7f));
+        assertEquals(Character.UnicodeBlock.GUJARATI, Character.UnicodeBlock.of((char) 0xa80));
+        assertEquals(Character.UnicodeBlock.GUJARATI, Character.UnicodeBlock.of((char) 0xaff));
+        assertEquals(Character.UnicodeBlock.ORIYA, Character.UnicodeBlock.of((char) 0xb00));
+        assertEquals(Character.UnicodeBlock.ORIYA, Character.UnicodeBlock.of((char) 0xb7f));
+        assertEquals(Character.UnicodeBlock.TAMIL, Character.UnicodeBlock.of((char) 0xb80));
+        assertEquals(Character.UnicodeBlock.TAMIL, Character.UnicodeBlock.of((char) 0xbff));
+        assertEquals(Character.UnicodeBlock.TELUGU, Character.UnicodeBlock.of((char) 0xc00));
+        assertEquals(Character.UnicodeBlock.TELUGU, Character.UnicodeBlock.of((char) 0xc7f));
+        assertEquals(Character.UnicodeBlock.KANNADA, Character.UnicodeBlock.of((char) 0xc80));
+        assertEquals(Character.UnicodeBlock.KANNADA, Character.UnicodeBlock.of((char) 0xcff));
+        assertEquals(Character.UnicodeBlock.MALAYALAM, Character.UnicodeBlock.of((char) 0xd00));
+        assertEquals(Character.UnicodeBlock.MALAYALAM, Character.UnicodeBlock.of((char) 0xd7f));
+        assertEquals(Character.UnicodeBlock.SINHALA, Character.UnicodeBlock.of((char) 0xd80));
+        assertEquals(Character.UnicodeBlock.SINHALA, Character.UnicodeBlock.of((char) 0xdff));
+        assertEquals(Character.UnicodeBlock.THAI, Character.UnicodeBlock.of((char) 0xe00));
+        assertEquals(Character.UnicodeBlock.THAI, Character.UnicodeBlock.of((char) 0xe7f));
+        assertEquals(Character.UnicodeBlock.LAO, Character.UnicodeBlock.of((char) 0xe80));
+        assertEquals(Character.UnicodeBlock.LAO, Character.UnicodeBlock.of((char) 0xeff));
+        assertEquals(Character.UnicodeBlock.TIBETAN, Character.UnicodeBlock.of((char) 0xf00));
+        assertEquals(Character.UnicodeBlock.TIBETAN, Character.UnicodeBlock.of((char) 0xfff));
+        assertEquals(Character.UnicodeBlock.MYANMAR, Character.UnicodeBlock.of((char) 0x1000));
+        assertEquals(Character.UnicodeBlock.MYANMAR, Character.UnicodeBlock.of((char) 0x109f));
+        assertEquals(Character.UnicodeBlock.GEORGIAN, Character.UnicodeBlock.of((char) 0x10a0));
+        assertEquals(Character.UnicodeBlock.GEORGIAN, Character.UnicodeBlock.of((char) 0x10ff));
+        assertEquals(Character.UnicodeBlock.HANGUL_JAMO, Character.UnicodeBlock.of((char) 0x1100));
+        assertEquals(Character.UnicodeBlock.HANGUL_JAMO, Character.UnicodeBlock.of((char) 0x11ff));
+        assertEquals(Character.UnicodeBlock.ETHIOPIC, Character.UnicodeBlock.of((char) 0x1200));
+        assertEquals(Character.UnicodeBlock.ETHIOPIC, Character.UnicodeBlock.of((char) 0x137f));
+        assertNull(Character.UnicodeBlock.of((char) 0x1380));
+        assertNull(Character.UnicodeBlock.of((char) 0x139f));
+        assertEquals(Character.UnicodeBlock.CHEROKEE, Character.UnicodeBlock.of((char) 0x13a0));
+        assertEquals(Character.UnicodeBlock.CHEROKEE, Character.UnicodeBlock.of((char) 0x13ff));
+        assertEquals(Character.UnicodeBlock.UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS, Character.UnicodeBlock.of((char) 0x1400));
+        assertEquals(Character.UnicodeBlock.UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS, Character.UnicodeBlock.of((char) 0x167f));
+        assertEquals(Character.UnicodeBlock.OGHAM, Character.UnicodeBlock.of((char) 0x1680));
+        assertEquals(Character.UnicodeBlock.OGHAM, Character.UnicodeBlock.of((char) 0x169f));
+        assertEquals(Character.UnicodeBlock.RUNIC, Character.UnicodeBlock.of((char) 0x16a0));
+        assertEquals(Character.UnicodeBlock.RUNIC, Character.UnicodeBlock.of((char) 0x16ff));
+        assertEquals(Character.UnicodeBlock.TAGALOG, Character.UnicodeBlock.of((char) 0x1700));
+        assertEquals(Character.UnicodeBlock.TAGALOG, Character.UnicodeBlock.of((char) 0x171f));
+        assertEquals(Character.UnicodeBlock.HANUNOO, Character.UnicodeBlock.of((char) 0x1720));
+        assertEquals(Character.UnicodeBlock.HANUNOO, Character.UnicodeBlock.of((char) 0x173f));
+        assertEquals(Character.UnicodeBlock.BUHID, Character.UnicodeBlock.of((char) 0x1740));
+        assertEquals(Character.UnicodeBlock.BUHID, Character.UnicodeBlock.of((char) 0x175f));
+        assertEquals(Character.UnicodeBlock.TAGBANWA, Character.UnicodeBlock.of((char) 0x1760));
+        assertEquals(Character.UnicodeBlock.TAGBANWA, Character.UnicodeBlock.of((char) 0x177f));
+        assertEquals(Character.UnicodeBlock.KHMER, Character.UnicodeBlock.of((char) 0x1780));
+        assertEquals(Character.UnicodeBlock.KHMER, Character.UnicodeBlock.of((char) 0x17ff));
+        assertEquals(Character.UnicodeBlock.MONGOLIAN, Character.UnicodeBlock.of((char) 0x1800));
+        assertEquals(Character.UnicodeBlock.MONGOLIAN, Character.UnicodeBlock.of((char) 0x18af));
+        assertNull(Character.UnicodeBlock.of((char) 0x18b0));
+        assertNull(Character.UnicodeBlock.of((char) 0x18ff));
+        assertEquals(Character.UnicodeBlock.LIMBU, Character.UnicodeBlock.of((char) 0x1900));
+        assertEquals(Character.UnicodeBlock.LIMBU, Character.UnicodeBlock.of((char) 0x194f));
+        assertEquals(Character.UnicodeBlock.TAI_LE, Character.UnicodeBlock.of((char) 0x1950));
+        assertEquals(Character.UnicodeBlock.TAI_LE, Character.UnicodeBlock.of((char) 0x197f));
+        assertNull(Character.UnicodeBlock.of((char) 0x1980));
+        assertNull(Character.UnicodeBlock.of((char) 0x19df));
+        assertEquals(Character.UnicodeBlock.KHMER_SYMBOLS, Character.UnicodeBlock.of((char) 0x19e0));
+        assertEquals(Character.UnicodeBlock.KHMER_SYMBOLS, Character.UnicodeBlock.of((char) 0x19ff));
+        assertNull(Character.UnicodeBlock.of((char) 0x1a00));
+        assertNull(Character.UnicodeBlock.of((char) 0x1cff));
+        assertEquals(Character.UnicodeBlock.PHONETIC_EXTENSIONS, Character.UnicodeBlock.of((char) 0x1d00));
+        assertEquals(Character.UnicodeBlock.PHONETIC_EXTENSIONS, Character.UnicodeBlock.of((char) 0x1d7f));
+        assertNull(Character.UnicodeBlock.of((char) 0x1d80));
+        assertNull(Character.UnicodeBlock.of((char) 0x1dff));
+        assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_ADDITIONAL, Character.UnicodeBlock.of((char) 0x1e00));
+        assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_ADDITIONAL, Character.UnicodeBlock.of((char) 0x1eff));
+        assertEquals(Character.UnicodeBlock.GREEK_EXTENDED, Character.UnicodeBlock.of((char) 0x1f00));
+        assertEquals(Character.UnicodeBlock.GREEK_EXTENDED, Character.UnicodeBlock.of((char) 0x1fff));
+        assertEquals(Character.UnicodeBlock.GENERAL_PUNCTUATION, Character.UnicodeBlock.of((char) 0x2000));
+        assertEquals(Character.UnicodeBlock.GENERAL_PUNCTUATION, Character.UnicodeBlock.of((char) 0x206f));
+        assertEquals(Character.UnicodeBlock.SUPERSCRIPTS_AND_SUBSCRIPTS, Character.UnicodeBlock.of((char) 0x2070));
+        assertEquals(Character.UnicodeBlock.SUPERSCRIPTS_AND_SUBSCRIPTS, Character.UnicodeBlock.of((char) 0x209f));
+        assertEquals(Character.UnicodeBlock.CURRENCY_SYMBOLS, Character.UnicodeBlock.of((char) 0x20a0));
+        assertEquals(Character.UnicodeBlock.CURRENCY_SYMBOLS, Character.UnicodeBlock.of((char) 0x20cf));
+        assertEquals(Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS, Character.UnicodeBlock.of((char) 0x20d0));
+        assertEquals(Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS, Character.UnicodeBlock.of((char) 0x20ff));
+        assertEquals(Character.UnicodeBlock.LETTERLIKE_SYMBOLS, Character.UnicodeBlock.of((char) 0x2100));
+        assertEquals(Character.UnicodeBlock.LETTERLIKE_SYMBOLS, Character.UnicodeBlock.of((char) 0x214f));
+        assertEquals(Character.UnicodeBlock.NUMBER_FORMS, Character.UnicodeBlock.of((char) 0x2150));
+        assertEquals(Character.UnicodeBlock.NUMBER_FORMS, Character.UnicodeBlock.of((char) 0x218f));
+        assertEquals(Character.UnicodeBlock.ARROWS, Character.UnicodeBlock.of((char) 0x2190));
+        assertEquals(Character.UnicodeBlock.ARROWS, Character.UnicodeBlock.of((char) 0x21ff));
+        assertEquals(Character.UnicodeBlock.MATHEMATICAL_OPERATORS, Character.UnicodeBlock.of((char) 0x2200));
+        assertEquals(Character.UnicodeBlock.MATHEMATICAL_OPERATORS, Character.UnicodeBlock.of((char) 0x22ff));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_TECHNICAL, Character.UnicodeBlock.of((char) 0x2300));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_TECHNICAL, Character.UnicodeBlock.of((char) 0x23ff));
+        assertEquals(Character.UnicodeBlock.CONTROL_PICTURES, Character.UnicodeBlock.of((char) 0x2400));
+        assertEquals(Character.UnicodeBlock.CONTROL_PICTURES, Character.UnicodeBlock.of((char) 0x243f));
+        assertEquals(Character.UnicodeBlock.OPTICAL_CHARACTER_RECOGNITION, Character.UnicodeBlock.of((char) 0x2440));
+        assertEquals(Character.UnicodeBlock.OPTICAL_CHARACTER_RECOGNITION, Character.UnicodeBlock.of((char) 0x245f));
+        assertEquals(Character.UnicodeBlock.ENCLOSED_ALPHANUMERICS, Character.UnicodeBlock.of((char) 0x2460));
+        assertEquals(Character.UnicodeBlock.ENCLOSED_ALPHANUMERICS, Character.UnicodeBlock.of((char) 0x24ff));
+        assertEquals(Character.UnicodeBlock.BOX_DRAWING, Character.UnicodeBlock.of((char) 0x2500));
+        assertEquals(Character.UnicodeBlock.BOX_DRAWING, Character.UnicodeBlock.of((char) 0x257f));
+        assertEquals(Character.UnicodeBlock.BLOCK_ELEMENTS, Character.UnicodeBlock.of((char) 0x2580));
+        assertEquals(Character.UnicodeBlock.BLOCK_ELEMENTS, Character.UnicodeBlock.of((char) 0x259f));
+        assertEquals(Character.UnicodeBlock.GEOMETRIC_SHAPES, Character.UnicodeBlock.of((char) 0x25a0));
+        assertEquals(Character.UnicodeBlock.GEOMETRIC_SHAPES, Character.UnicodeBlock.of((char) 0x25ff));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS, Character.UnicodeBlock.of((char) 0x2600));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS, Character.UnicodeBlock.of((char) 0x26ff));
+        assertEquals(Character.UnicodeBlock.DINGBATS, Character.UnicodeBlock.of((char) 0x2700));
+        assertEquals(Character.UnicodeBlock.DINGBATS, Character.UnicodeBlock.of((char) 0x27bf));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A, Character.UnicodeBlock.of((char) 0x27c0));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A, Character.UnicodeBlock.of((char) 0x27ef));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_A, Character.UnicodeBlock.of((char) 0x27f0));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_A, Character.UnicodeBlock.of((char) 0x27ff));
+        assertEquals(Character.UnicodeBlock.BRAILLE_PATTERNS, Character.UnicodeBlock.of((char) 0x2800));
+        assertEquals(Character.UnicodeBlock.BRAILLE_PATTERNS, Character.UnicodeBlock.of((char) 0x28ff));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_B, Character.UnicodeBlock.of((char) 0x2900));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_B, Character.UnicodeBlock.of((char) 0x297f));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B, Character.UnicodeBlock.of((char) 0x2980));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B, Character.UnicodeBlock.of((char) 0x29ff));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_MATHEMATICAL_OPERATORS, Character.UnicodeBlock.of((char) 0x2a00));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_MATHEMATICAL_OPERATORS, Character.UnicodeBlock.of((char) 0x2aff));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS_AND_ARROWS, Character.UnicodeBlock.of((char) 0x2b00));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS_AND_ARROWS, Character.UnicodeBlock.of((char) 0x2bff));
+        assertNull(Character.UnicodeBlock.of((char) 0x2c00));
+        assertNull(Character.UnicodeBlock.of((char) 0x2e7f));
+        assertEquals(Character.UnicodeBlock.CJK_RADICALS_SUPPLEMENT, Character.UnicodeBlock.of((char) 0x2e80));
+        assertEquals(Character.UnicodeBlock.CJK_RADICALS_SUPPLEMENT, Character.UnicodeBlock.of((char) 0x2eff));
+        assertEquals(Character.UnicodeBlock.KANGXI_RADICALS, Character.UnicodeBlock.of((char) 0x2f00));
+        assertEquals(Character.UnicodeBlock.KANGXI_RADICALS, Character.UnicodeBlock.of((char) 0x2fdf));
+        assertNull(Character.UnicodeBlock.of((char) 0x2fe0));
+        assertNull(Character.UnicodeBlock.of((char) 0x2fef));
+        assertEquals(Character.UnicodeBlock.IDEOGRAPHIC_DESCRIPTION_CHARACTERS, Character.UnicodeBlock.of((char) 0x2ff0));
+        assertEquals(Character.UnicodeBlock.IDEOGRAPHIC_DESCRIPTION_CHARACTERS, Character.UnicodeBlock.of((char) 0x2fff));
+        assertEquals(Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION, Character.UnicodeBlock.of((char) 0x3000));
+        assertEquals(Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION, Character.UnicodeBlock.of((char) 0x303f));
+        assertEquals(Character.UnicodeBlock.HIRAGANA, Character.UnicodeBlock.of((char) 0x3040));
+        assertEquals(Character.UnicodeBlock.HIRAGANA, Character.UnicodeBlock.of((char) 0x309f));
+        assertEquals(Character.UnicodeBlock.KATAKANA, Character.UnicodeBlock.of((char) 0x30a0));
+        assertEquals(Character.UnicodeBlock.KATAKANA, Character.UnicodeBlock.of((char) 0x30ff));
+        assertEquals(Character.UnicodeBlock.BOPOMOFO, Character.UnicodeBlock.of((char) 0x3100));
+        assertEquals(Character.UnicodeBlock.BOPOMOFO, Character.UnicodeBlock.of((char) 0x312f));
+        assertEquals(Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO, Character.UnicodeBlock.of((char) 0x3130));
+        assertEquals(Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO, Character.UnicodeBlock.of((char) 0x318f));
+        assertEquals(Character.UnicodeBlock.KANBUN, Character.UnicodeBlock.of((char) 0x3190));
+        assertEquals(Character.UnicodeBlock.KANBUN, Character.UnicodeBlock.of((char) 0x319f));
+        assertEquals(Character.UnicodeBlock.BOPOMOFO_EXTENDED, Character.UnicodeBlock.of((char) 0x31a0));
+        assertEquals(Character.UnicodeBlock.BOPOMOFO_EXTENDED, Character.UnicodeBlock.of((char) 0x31bf));
+        assertNull(Character.UnicodeBlock.of((char) 0x31c0));
+        assertNull(Character.UnicodeBlock.of((char) 0x31ef));
+        assertEquals(Character.UnicodeBlock.KATAKANA_PHONETIC_EXTENSIONS, Character.UnicodeBlock.of((char) 0x31f0));
+        assertEquals(Character.UnicodeBlock.KATAKANA_PHONETIC_EXTENSIONS, Character.UnicodeBlock.of((char) 0x31ff));
+        assertEquals(Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS, Character.UnicodeBlock.of((char) 0x3200));
+        assertEquals(Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS, Character.UnicodeBlock.of((char) 0x32ff));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY, Character.UnicodeBlock.of((char) 0x3300));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY, Character.UnicodeBlock.of((char) 0x33ff));
+        assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A, Character.UnicodeBlock.of((char) 0x3400));
+        assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A, Character.UnicodeBlock.of((char) 0x4dbf));
+        assertEquals(Character.UnicodeBlock.YIJING_HEXAGRAM_SYMBOLS, Character.UnicodeBlock.of((char) 0x4dc0));
+        assertEquals(Character.UnicodeBlock.YIJING_HEXAGRAM_SYMBOLS, Character.UnicodeBlock.of((char) 0x4dff));
+        assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS, Character.UnicodeBlock.of((char) 0x4e00));
+        assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS, Character.UnicodeBlock.of((char) 0x9fff));
+        assertEquals(Character.UnicodeBlock.YI_SYLLABLES, Character.UnicodeBlock.of((char) 0xa000));
+        assertEquals(Character.UnicodeBlock.YI_SYLLABLES, Character.UnicodeBlock.of((char) 0xa48f));
+        assertEquals(Character.UnicodeBlock.YI_RADICALS, Character.UnicodeBlock.of((char) 0xa490));
+        assertEquals(Character.UnicodeBlock.YI_RADICALS, Character.UnicodeBlock.of((char) 0xa4cf));
+        assertNull(Character.UnicodeBlock.of((char) 0xa4d0));
+        assertNull(Character.UnicodeBlock.of((char) 0xabff));
+        assertEquals(Character.UnicodeBlock.HANGUL_SYLLABLES, Character.UnicodeBlock.of((char) 0xac00));
+        assertEquals(Character.UnicodeBlock.HANGUL_SYLLABLES, Character.UnicodeBlock.of((char) 0xd7af));
+        assertNull(Character.UnicodeBlock.of((char) 0xd7b0));
+        assertNull(Character.UnicodeBlock.of((char) 0xd7ff));
+        assertEquals(Character.UnicodeBlock.HIGH_SURROGATES, Character.UnicodeBlock.of((char) 0xd800));
+        assertEquals(Character.UnicodeBlock.HIGH_SURROGATES, Character.UnicodeBlock.of((char) 0xdb7f));
+        assertEquals(Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES, Character.UnicodeBlock.of((char) 0xdb80));
+        assertEquals(Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES, Character.UnicodeBlock.of((char) 0xdbff));
+        assertEquals(Character.UnicodeBlock.LOW_SURROGATES, Character.UnicodeBlock.of((char) 0xdc00));
+        assertEquals(Character.UnicodeBlock.LOW_SURROGATES, Character.UnicodeBlock.of((char) 0xdfff));
+        assertEquals(Character.UnicodeBlock.PRIVATE_USE_AREA, Character.UnicodeBlock.of((char) 0xe000));
+        assertEquals(Character.UnicodeBlock.PRIVATE_USE_AREA, Character.UnicodeBlock.of((char) 0xf8ff));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS, Character.UnicodeBlock.of((char) 0xf900));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS, Character.UnicodeBlock.of((char) 0xfaff));
+        assertEquals(Character.UnicodeBlock.ALPHABETIC_PRESENTATION_FORMS, Character.UnicodeBlock.of((char) 0xfb00));
+        assertEquals(Character.UnicodeBlock.ALPHABETIC_PRESENTATION_FORMS, Character.UnicodeBlock.of((char) 0xfb4f));
+        assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_A, Character.UnicodeBlock.of((char) 0xfb50));
+        assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_A, Character.UnicodeBlock.of((char) 0xfdff));
+        assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS, Character.UnicodeBlock.of((char) 0xfe00));
+        assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS, Character.UnicodeBlock.of((char) 0xfe0f));
+        assertNull(Character.UnicodeBlock.of((char) 0xfe10));
+        assertNull(Character.UnicodeBlock.of((char) 0xfe1f));
+        assertEquals(Character.UnicodeBlock.COMBINING_HALF_MARKS, Character.UnicodeBlock.of((char) 0xfe20));
+        assertEquals(Character.UnicodeBlock.COMBINING_HALF_MARKS, Character.UnicodeBlock.of((char) 0xfe2f));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS, Character.UnicodeBlock.of((char) 0xfe30));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS, Character.UnicodeBlock.of((char) 0xfe4f));
+        assertEquals(Character.UnicodeBlock.SMALL_FORM_VARIANTS, Character.UnicodeBlock.of((char) 0xfe50));
+        assertEquals(Character.UnicodeBlock.SMALL_FORM_VARIANTS, Character.UnicodeBlock.of((char) 0xfe6f));
+        assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_B, Character.UnicodeBlock.of((char) 0xfe70));
+        assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_B, Character.UnicodeBlock.of((char) 0xfeff));
+        assertEquals(Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS, Character.UnicodeBlock.of((char) 0xff00));
+        assertEquals(Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS, Character.UnicodeBlock.of((char) 0xffef));
+        assertEquals(Character.UnicodeBlock.SPECIALS, Character.UnicodeBlock.of((char) 0xfff0));
+        assertEquals(Character.UnicodeBlock.SPECIALS, Character.UnicodeBlock.of((char) 0xffff));
+    }
+
+    public void test_ofI() {
+        assertEquals(Character.UnicodeBlock.BASIC_LATIN, Character.UnicodeBlock.of(0x0));
+        assertEquals(Character.UnicodeBlock.BASIC_LATIN, Character.UnicodeBlock.of(0x7f));
+        assertEquals(Character.UnicodeBlock.LATIN_1_SUPPLEMENT, Character.UnicodeBlock.of(0x80));
+        assertEquals(Character.UnicodeBlock.LATIN_1_SUPPLEMENT, Character.UnicodeBlock.of(0xff));
+        assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_A, Character.UnicodeBlock.of(0x100));
+        assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_A, Character.UnicodeBlock.of(0x17f));
+        assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_B, Character.UnicodeBlock.of(0x180));
+        assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_B, Character.UnicodeBlock.of(0x24f));
+        assertEquals(Character.UnicodeBlock.IPA_EXTENSIONS, Character.UnicodeBlock.of(0x250));
+        assertEquals(Character.UnicodeBlock.IPA_EXTENSIONS, Character.UnicodeBlock.of(0x2af));
+        assertEquals(Character.UnicodeBlock.SPACING_MODIFIER_LETTERS, Character.UnicodeBlock.of(0x2b0));
+        assertEquals(Character.UnicodeBlock.SPACING_MODIFIER_LETTERS, Character.UnicodeBlock.of(0x2ff));
+        assertEquals(Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS, Character.UnicodeBlock.of(0x300));
+        assertEquals(Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS, Character.UnicodeBlock.of(0x36f));
+        assertEquals(Character.UnicodeBlock.GREEK, Character.UnicodeBlock.of(0x370));
+        assertEquals(Character.UnicodeBlock.GREEK, Character.UnicodeBlock.of(0x3ff));
+        assertEquals(Character.UnicodeBlock.CYRILLIC, Character.UnicodeBlock.of(0x400));
+        assertEquals(Character.UnicodeBlock.CYRILLIC, Character.UnicodeBlock.of(0x4ff));
+        assertEquals(Character.UnicodeBlock.CYRILLIC_SUPPLEMENTARY, Character.UnicodeBlock.of(0x500));
+        assertEquals(Character.UnicodeBlock.CYRILLIC_SUPPLEMENTARY, Character.UnicodeBlock.of(0x52f));
+        assertEquals(Character.UnicodeBlock.ARMENIAN, Character.UnicodeBlock.of(0x530));
+        assertEquals(Character.UnicodeBlock.ARMENIAN, Character.UnicodeBlock.of(0x58f));
+        assertEquals(Character.UnicodeBlock.HEBREW, Character.UnicodeBlock.of(0x590));
+        assertEquals(Character.UnicodeBlock.HEBREW, Character.UnicodeBlock.of(0x5ff));
+        assertEquals(Character.UnicodeBlock.ARABIC, Character.UnicodeBlock.of(0x600));
+        assertEquals(Character.UnicodeBlock.ARABIC, Character.UnicodeBlock.of(0x6ff));
+        assertEquals(Character.UnicodeBlock.SYRIAC, Character.UnicodeBlock.of(0x700));
+        assertEquals(Character.UnicodeBlock.SYRIAC, Character.UnicodeBlock.of(0x74f));
+        assertNull(Character.UnicodeBlock.of(0x750));
+        assertNull(Character.UnicodeBlock.of(0x77f));
+        assertEquals(Character.UnicodeBlock.THAANA, Character.UnicodeBlock.of(0x780));
+        assertEquals(Character.UnicodeBlock.THAANA, Character.UnicodeBlock.of(0x7bf));
+        assertNull(Character.UnicodeBlock.of(0x7c0));
+        assertNull(Character.UnicodeBlock.of(0x8ff));
+        assertEquals(Character.UnicodeBlock.DEVANAGARI, Character.UnicodeBlock.of(0x900));
+        assertEquals(Character.UnicodeBlock.DEVANAGARI, Character.UnicodeBlock.of(0x97f));
+        assertEquals(Character.UnicodeBlock.BENGALI, Character.UnicodeBlock.of(0x980));
+        assertEquals(Character.UnicodeBlock.BENGALI, Character.UnicodeBlock.of(0x9ff));
+        assertEquals(Character.UnicodeBlock.GURMUKHI, Character.UnicodeBlock.of(0xa00));
+        assertEquals(Character.UnicodeBlock.GURMUKHI, Character.UnicodeBlock.of(0xa7f));
+        assertEquals(Character.UnicodeBlock.GUJARATI, Character.UnicodeBlock.of(0xa80));
+        assertEquals(Character.UnicodeBlock.GUJARATI, Character.UnicodeBlock.of(0xaff));
+        assertEquals(Character.UnicodeBlock.ORIYA, Character.UnicodeBlock.of(0xb00));
+        assertEquals(Character.UnicodeBlock.ORIYA, Character.UnicodeBlock.of(0xb7f));
+        assertEquals(Character.UnicodeBlock.TAMIL, Character.UnicodeBlock.of(0xb80));
+        assertEquals(Character.UnicodeBlock.TAMIL, Character.UnicodeBlock.of(0xbff));
+        assertEquals(Character.UnicodeBlock.TELUGU, Character.UnicodeBlock.of(0xc00));
+        assertEquals(Character.UnicodeBlock.TELUGU, Character.UnicodeBlock.of(0xc7f));
+        assertEquals(Character.UnicodeBlock.KANNADA, Character.UnicodeBlock.of(0xc80));
+        assertEquals(Character.UnicodeBlock.KANNADA, Character.UnicodeBlock.of(0xcff));
+        assertEquals(Character.UnicodeBlock.MALAYALAM, Character.UnicodeBlock.of(0xd00));
+        assertEquals(Character.UnicodeBlock.MALAYALAM, Character.UnicodeBlock.of(0xd7f));
+        assertEquals(Character.UnicodeBlock.SINHALA, Character.UnicodeBlock.of(0xd80));
+        assertEquals(Character.UnicodeBlock.SINHALA, Character.UnicodeBlock.of(0xdff));
+        assertEquals(Character.UnicodeBlock.THAI, Character.UnicodeBlock.of(0xe00));
+        assertEquals(Character.UnicodeBlock.THAI, Character.UnicodeBlock.of(0xe7f));
+        assertEquals(Character.UnicodeBlock.LAO, Character.UnicodeBlock.of(0xe80));
+        assertEquals(Character.UnicodeBlock.LAO, Character.UnicodeBlock.of(0xeff));
+        assertEquals(Character.UnicodeBlock.TIBETAN, Character.UnicodeBlock.of(0xf00));
+        assertEquals(Character.UnicodeBlock.TIBETAN, Character.UnicodeBlock.of(0xfff));
+        assertEquals(Character.UnicodeBlock.MYANMAR, Character.UnicodeBlock.of(0x1000));
+        assertEquals(Character.UnicodeBlock.MYANMAR, Character.UnicodeBlock.of(0x109f));
+        assertEquals(Character.UnicodeBlock.GEORGIAN, Character.UnicodeBlock.of(0x10a0));
+        assertEquals(Character.UnicodeBlock.GEORGIAN, Character.UnicodeBlock.of(0x10ff));
+        assertEquals(Character.UnicodeBlock.HANGUL_JAMO, Character.UnicodeBlock.of(0x1100));
+        assertEquals(Character.UnicodeBlock.HANGUL_JAMO, Character.UnicodeBlock.of(0x11ff));
+        assertEquals(Character.UnicodeBlock.ETHIOPIC, Character.UnicodeBlock.of(0x1200));
+        assertEquals(Character.UnicodeBlock.ETHIOPIC, Character.UnicodeBlock.of(0x137f));
+        assertNull(Character.UnicodeBlock.of(0x1380));
+        assertNull(Character.UnicodeBlock.of(0x139f));
+        assertEquals(Character.UnicodeBlock.CHEROKEE, Character.UnicodeBlock.of(0x13a0));
+        assertEquals(Character.UnicodeBlock.CHEROKEE, Character.UnicodeBlock.of(0x13ff));
+        assertEquals(Character.UnicodeBlock.UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS, Character.UnicodeBlock.of(0x1400));
+        assertEquals(Character.UnicodeBlock.UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS, Character.UnicodeBlock.of(0x167f));
+        assertEquals(Character.UnicodeBlock.OGHAM, Character.UnicodeBlock.of(0x1680));
+        assertEquals(Character.UnicodeBlock.OGHAM, Character.UnicodeBlock.of(0x169f));
+        assertEquals(Character.UnicodeBlock.RUNIC, Character.UnicodeBlock.of(0x16a0));
+        assertEquals(Character.UnicodeBlock.RUNIC, Character.UnicodeBlock.of(0x16ff));
+        assertEquals(Character.UnicodeBlock.TAGALOG, Character.UnicodeBlock.of(0x1700));
+        assertEquals(Character.UnicodeBlock.TAGALOG, Character.UnicodeBlock.of(0x171f));
+        assertEquals(Character.UnicodeBlock.HANUNOO, Character.UnicodeBlock.of(0x1720));
+        assertEquals(Character.UnicodeBlock.HANUNOO, Character.UnicodeBlock.of(0x173f));
+        assertEquals(Character.UnicodeBlock.BUHID, Character.UnicodeBlock.of(0x1740));
+        assertEquals(Character.UnicodeBlock.BUHID, Character.UnicodeBlock.of(0x175f));
+        assertEquals(Character.UnicodeBlock.TAGBANWA, Character.UnicodeBlock.of(0x1760));
+        assertEquals(Character.UnicodeBlock.TAGBANWA, Character.UnicodeBlock.of(0x177f));
+        assertEquals(Character.UnicodeBlock.KHMER, Character.UnicodeBlock.of(0x1780));
+        assertEquals(Character.UnicodeBlock.KHMER, Character.UnicodeBlock.of(0x17ff));
+        assertEquals(Character.UnicodeBlock.MONGOLIAN, Character.UnicodeBlock.of(0x1800));
+        assertEquals(Character.UnicodeBlock.MONGOLIAN, Character.UnicodeBlock.of(0x18af));
+        assertNull(Character.UnicodeBlock.of(0x18b0));
+        assertNull(Character.UnicodeBlock.of(0x18ff));
+        assertEquals(Character.UnicodeBlock.LIMBU, Character.UnicodeBlock.of(0x1900));
+        assertEquals(Character.UnicodeBlock.LIMBU, Character.UnicodeBlock.of(0x194f));
+        assertEquals(Character.UnicodeBlock.TAI_LE, Character.UnicodeBlock.of(0x1950));
+        assertEquals(Character.UnicodeBlock.TAI_LE, Character.UnicodeBlock.of(0x197f));
+        assertNull(Character.UnicodeBlock.of(0x1980));
+        assertNull(Character.UnicodeBlock.of(0x19df));
+        assertEquals(Character.UnicodeBlock.KHMER_SYMBOLS, Character.UnicodeBlock.of(0x19e0));
+        assertEquals(Character.UnicodeBlock.KHMER_SYMBOLS, Character.UnicodeBlock.of(0x19ff));
+        assertNull(Character.UnicodeBlock.of(0x1a00));
+        assertNull(Character.UnicodeBlock.of(0x1cff));
+        assertEquals(Character.UnicodeBlock.PHONETIC_EXTENSIONS, Character.UnicodeBlock.of(0x1d00));
+        assertEquals(Character.UnicodeBlock.PHONETIC_EXTENSIONS, Character.UnicodeBlock.of(0x1d7f));
+        assertNull(Character.UnicodeBlock.of(0x1d80));
+        assertNull(Character.UnicodeBlock.of(0x1dff));
+        assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_ADDITIONAL, Character.UnicodeBlock.of(0x1e00));
+        assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_ADDITIONAL, Character.UnicodeBlock.of(0x1eff));
+        assertEquals(Character.UnicodeBlock.GREEK_EXTENDED, Character.UnicodeBlock.of(0x1f00));
+        assertEquals(Character.UnicodeBlock.GREEK_EXTENDED, Character.UnicodeBlock.of(0x1fff));
+        assertEquals(Character.UnicodeBlock.GENERAL_PUNCTUATION, Character.UnicodeBlock.of(0x2000));
+        assertEquals(Character.UnicodeBlock.GENERAL_PUNCTUATION, Character.UnicodeBlock.of(0x206f));
+        assertEquals(Character.UnicodeBlock.SUPERSCRIPTS_AND_SUBSCRIPTS, Character.UnicodeBlock.of(0x2070));
+        assertEquals(Character.UnicodeBlock.SUPERSCRIPTS_AND_SUBSCRIPTS, Character.UnicodeBlock.of(0x209f));
+        assertEquals(Character.UnicodeBlock.CURRENCY_SYMBOLS, Character.UnicodeBlock.of(0x20a0));
+        assertEquals(Character.UnicodeBlock.CURRENCY_SYMBOLS, Character.UnicodeBlock.of(0x20cf));
+        assertEquals(Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS, Character.UnicodeBlock.of(0x20d0));
+        assertEquals(Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS, Character.UnicodeBlock.of(0x20ff));
+        assertEquals(Character.UnicodeBlock.LETTERLIKE_SYMBOLS, Character.UnicodeBlock.of(0x2100));
+        assertEquals(Character.UnicodeBlock.LETTERLIKE_SYMBOLS, Character.UnicodeBlock.of(0x214f));
+        assertEquals(Character.UnicodeBlock.NUMBER_FORMS, Character.UnicodeBlock.of(0x2150));
+        assertEquals(Character.UnicodeBlock.NUMBER_FORMS, Character.UnicodeBlock.of(0x218f));
+        assertEquals(Character.UnicodeBlock.ARROWS, Character.UnicodeBlock.of(0x2190));
+        assertEquals(Character.UnicodeBlock.ARROWS, Character.UnicodeBlock.of(0x21ff));
+        assertEquals(Character.UnicodeBlock.MATHEMATICAL_OPERATORS, Character.UnicodeBlock.of(0x2200));
+        assertEquals(Character.UnicodeBlock.MATHEMATICAL_OPERATORS, Character.UnicodeBlock.of(0x22ff));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_TECHNICAL, Character.UnicodeBlock.of(0x2300));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_TECHNICAL, Character.UnicodeBlock.of(0x23ff));
+        assertEquals(Character.UnicodeBlock.CONTROL_PICTURES, Character.UnicodeBlock.of(0x2400));
+        assertEquals(Character.UnicodeBlock.CONTROL_PICTURES, Character.UnicodeBlock.of(0x243f));
+        assertEquals(Character.UnicodeBlock.OPTICAL_CHARACTER_RECOGNITION, Character.UnicodeBlock.of(0x2440));
+        assertEquals(Character.UnicodeBlock.OPTICAL_CHARACTER_RECOGNITION, Character.UnicodeBlock.of(0x245f));
+        assertEquals(Character.UnicodeBlock.ENCLOSED_ALPHANUMERICS, Character.UnicodeBlock.of(0x2460));
+        assertEquals(Character.UnicodeBlock.ENCLOSED_ALPHANUMERICS, Character.UnicodeBlock.of(0x24ff));
+        assertEquals(Character.UnicodeBlock.BOX_DRAWING, Character.UnicodeBlock.of(0x2500));
+        assertEquals(Character.UnicodeBlock.BOX_DRAWING, Character.UnicodeBlock.of(0x257f));
+        assertEquals(Character.UnicodeBlock.BLOCK_ELEMENTS, Character.UnicodeBlock.of(0x2580));
+        assertEquals(Character.UnicodeBlock.BLOCK_ELEMENTS, Character.UnicodeBlock.of(0x259f));
+        assertEquals(Character.UnicodeBlock.GEOMETRIC_SHAPES, Character.UnicodeBlock.of(0x25a0));
+        assertEquals(Character.UnicodeBlock.GEOMETRIC_SHAPES, Character.UnicodeBlock.of(0x25ff));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS, Character.UnicodeBlock.of(0x2600));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS, Character.UnicodeBlock.of(0x26ff));
+        assertEquals(Character.UnicodeBlock.DINGBATS, Character.UnicodeBlock.of(0x2700));
+        assertEquals(Character.UnicodeBlock.DINGBATS, Character.UnicodeBlock.of(0x27bf));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A, Character.UnicodeBlock.of(0x27c0));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A, Character.UnicodeBlock.of(0x27ef));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_A, Character.UnicodeBlock.of(0x27f0));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_A, Character.UnicodeBlock.of(0x27ff));
+        assertEquals(Character.UnicodeBlock.BRAILLE_PATTERNS, Character.UnicodeBlock.of(0x2800));
+        assertEquals(Character.UnicodeBlock.BRAILLE_PATTERNS, Character.UnicodeBlock.of(0x28ff));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_B, Character.UnicodeBlock.of(0x2900));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_B, Character.UnicodeBlock.of(0x297f));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B, Character.UnicodeBlock.of(0x2980));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B, Character.UnicodeBlock.of(0x29ff));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_MATHEMATICAL_OPERATORS, Character.UnicodeBlock.of(0x2a00));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_MATHEMATICAL_OPERATORS, Character.UnicodeBlock.of(0x2aff));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS_AND_ARROWS, Character.UnicodeBlock.of(0x2b00));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS_AND_ARROWS, Character.UnicodeBlock.of(0x2bff));
+        assertNull(Character.UnicodeBlock.of(0x2c00));
+        assertNull(Character.UnicodeBlock.of(0x2e7f));
+        assertEquals(Character.UnicodeBlock.CJK_RADICALS_SUPPLEMENT, Character.UnicodeBlock.of(0x2e80));
+        assertEquals(Character.UnicodeBlock.CJK_RADICALS_SUPPLEMENT, Character.UnicodeBlock.of(0x2eff));
+        assertEquals(Character.UnicodeBlock.KANGXI_RADICALS, Character.UnicodeBlock.of(0x2f00));
+        assertEquals(Character.UnicodeBlock.KANGXI_RADICALS, Character.UnicodeBlock.of(0x2fdf));
+        assertNull(Character.UnicodeBlock.of(0x2fe0));
+        assertNull(Character.UnicodeBlock.of(0x2fef));
+        assertEquals(Character.UnicodeBlock.IDEOGRAPHIC_DESCRIPTION_CHARACTERS, Character.UnicodeBlock.of(0x2ff0));
+        assertEquals(Character.UnicodeBlock.IDEOGRAPHIC_DESCRIPTION_CHARACTERS, Character.UnicodeBlock.of(0x2fff));
+        assertEquals(Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION, Character.UnicodeBlock.of(0x3000));
+        assertEquals(Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION, Character.UnicodeBlock.of(0x303f));
+        assertEquals(Character.UnicodeBlock.HIRAGANA, Character.UnicodeBlock.of(0x3040));
+        assertEquals(Character.UnicodeBlock.HIRAGANA, Character.UnicodeBlock.of(0x309f));
+        assertEquals(Character.UnicodeBlock.KATAKANA, Character.UnicodeBlock.of(0x30a0));
+        assertEquals(Character.UnicodeBlock.KATAKANA, Character.UnicodeBlock.of(0x30ff));
+        assertEquals(Character.UnicodeBlock.BOPOMOFO, Character.UnicodeBlock.of(0x3100));
+        assertEquals(Character.UnicodeBlock.BOPOMOFO, Character.UnicodeBlock.of(0x312f));
+        assertEquals(Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO, Character.UnicodeBlock.of(0x3130));
+        assertEquals(Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO, Character.UnicodeBlock.of(0x318f));
+        assertEquals(Character.UnicodeBlock.KANBUN, Character.UnicodeBlock.of(0x3190));
+        assertEquals(Character.UnicodeBlock.KANBUN, Character.UnicodeBlock.of(0x319f));
+        assertEquals(Character.UnicodeBlock.BOPOMOFO_EXTENDED, Character.UnicodeBlock.of(0x31a0));
+        assertEquals(Character.UnicodeBlock.BOPOMOFO_EXTENDED, Character.UnicodeBlock.of(0x31bf));
+        assertNull(Character.UnicodeBlock.of(0x31c0));
+        assertNull(Character.UnicodeBlock.of(0x31ef));
+        assertEquals(Character.UnicodeBlock.KATAKANA_PHONETIC_EXTENSIONS, Character.UnicodeBlock.of(0x31f0));
+        assertEquals(Character.UnicodeBlock.KATAKANA_PHONETIC_EXTENSIONS, Character.UnicodeBlock.of(0x31ff));
+        assertEquals(Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS, Character.UnicodeBlock.of(0x3200));
+        assertEquals(Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS, Character.UnicodeBlock.of(0x32ff));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY, Character.UnicodeBlock.of(0x3300));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY, Character.UnicodeBlock.of(0x33ff));
+        assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A, Character.UnicodeBlock.of(0x3400));
+        assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A, Character.UnicodeBlock.of(0x4dbf));
+        assertEquals(Character.UnicodeBlock.YIJING_HEXAGRAM_SYMBOLS, Character.UnicodeBlock.of(0x4dc0));
+        assertEquals(Character.UnicodeBlock.YIJING_HEXAGRAM_SYMBOLS, Character.UnicodeBlock.of(0x4dff));
+        assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS, Character.UnicodeBlock.of(0x4e00));
+        assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS, Character.UnicodeBlock.of(0x9fff));
+        assertEquals(Character.UnicodeBlock.YI_SYLLABLES, Character.UnicodeBlock.of(0xa000));
+        assertEquals(Character.UnicodeBlock.YI_SYLLABLES, Character.UnicodeBlock.of(0xa48f));
+        assertEquals(Character.UnicodeBlock.YI_RADICALS, Character.UnicodeBlock.of(0xa490));
+        assertEquals(Character.UnicodeBlock.YI_RADICALS, Character.UnicodeBlock.of(0xa4cf));
+        assertNull(Character.UnicodeBlock.of(0xa4d0));
+        assertNull(Character.UnicodeBlock.of(0xabff));
+        assertEquals(Character.UnicodeBlock.HANGUL_SYLLABLES, Character.UnicodeBlock.of(0xac00));
+        assertEquals(Character.UnicodeBlock.HANGUL_SYLLABLES, Character.UnicodeBlock.of(0xd7af));
+        assertNull(Character.UnicodeBlock.of(0xd7b0));
+        assertNull(Character.UnicodeBlock.of(0xd7ff));
+        assertEquals(Character.UnicodeBlock.HIGH_SURROGATES, Character.UnicodeBlock.of(0xd800));
+        assertEquals(Character.UnicodeBlock.HIGH_SURROGATES, Character.UnicodeBlock.of(0xdb7f));
+        assertEquals(Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES, Character.UnicodeBlock.of(0xdb80));
+        assertEquals(Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES, Character.UnicodeBlock.of(0xdbff));
+        assertEquals(Character.UnicodeBlock.LOW_SURROGATES, Character.UnicodeBlock.of(0xdc00));
+        assertEquals(Character.UnicodeBlock.LOW_SURROGATES, Character.UnicodeBlock.of(0xdfff));
+        assertEquals(Character.UnicodeBlock.PRIVATE_USE_AREA, Character.UnicodeBlock.of(0xe000));
+        assertEquals(Character.UnicodeBlock.PRIVATE_USE_AREA, Character.UnicodeBlock.of(0xf8ff));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS, Character.UnicodeBlock.of(0xf900));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS, Character.UnicodeBlock.of(0xfaff));
+        assertEquals(Character.UnicodeBlock.ALPHABETIC_PRESENTATION_FORMS, Character.UnicodeBlock.of(0xfb00));
+        assertEquals(Character.UnicodeBlock.ALPHABETIC_PRESENTATION_FORMS, Character.UnicodeBlock.of(0xfb4f));
+        assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_A, Character.UnicodeBlock.of(0xfb50));
+        assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_A, Character.UnicodeBlock.of(0xfdff));
+        assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS, Character.UnicodeBlock.of(0xfe00));
+        assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS, Character.UnicodeBlock.of(0xfe0f));
+        assertNull(Character.UnicodeBlock.of(0xfe10));
+        assertNull(Character.UnicodeBlock.of(0xfe1f));
+        assertEquals(Character.UnicodeBlock.COMBINING_HALF_MARKS, Character.UnicodeBlock.of(0xfe20));
+        assertEquals(Character.UnicodeBlock.COMBINING_HALF_MARKS, Character.UnicodeBlock.of(0xfe2f));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS, Character.UnicodeBlock.of(0xfe30));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS, Character.UnicodeBlock.of(0xfe4f));
+        assertEquals(Character.UnicodeBlock.SMALL_FORM_VARIANTS, Character.UnicodeBlock.of(0xfe50));
+        assertEquals(Character.UnicodeBlock.SMALL_FORM_VARIANTS, Character.UnicodeBlock.of(0xfe6f));
+        assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_B, Character.UnicodeBlock.of(0xfe70));
+        assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_B, Character.UnicodeBlock.of(0xfeff));
+        assertEquals(Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS, Character.UnicodeBlock.of(0xff00));
+        assertEquals(Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS, Character.UnicodeBlock.of(0xffef));
+        assertEquals(Character.UnicodeBlock.SPECIALS, Character.UnicodeBlock.of(0xfff0));
+        assertEquals(Character.UnicodeBlock.SPECIALS, Character.UnicodeBlock.of(0xffff));
+        assertEquals(Character.UnicodeBlock.LINEAR_B_SYLLABARY, Character.UnicodeBlock.of(0x10000));
+        assertEquals(Character.UnicodeBlock.LINEAR_B_SYLLABARY, Character.UnicodeBlock.of(0x1007f));
+        assertEquals(Character.UnicodeBlock.LINEAR_B_IDEOGRAMS, Character.UnicodeBlock.of(0x10080));
+        assertEquals(Character.UnicodeBlock.LINEAR_B_IDEOGRAMS, Character.UnicodeBlock.of(0x100ff));
+        assertEquals(Character.UnicodeBlock.AEGEAN_NUMBERS, Character.UnicodeBlock.of(0x10100));
+        assertEquals(Character.UnicodeBlock.AEGEAN_NUMBERS, Character.UnicodeBlock.of(0x1013f));
+        assertNull(Character.UnicodeBlock.of(0x10140));
+        assertNull(Character.UnicodeBlock.of(0x102ff));
+        assertEquals(Character.UnicodeBlock.OLD_ITALIC, Character.UnicodeBlock.of(0x10300));
+        assertEquals(Character.UnicodeBlock.OLD_ITALIC, Character.UnicodeBlock.of(0x1032f));
+        assertEquals(Character.UnicodeBlock.GOTHIC, Character.UnicodeBlock.of(0x10330));
+        assertEquals(Character.UnicodeBlock.GOTHIC, Character.UnicodeBlock.of(0x1034f));
+        assertNull(Character.UnicodeBlock.of(0x10350));
+        assertNull(Character.UnicodeBlock.of(0x1037f));
+        assertEquals(Character.UnicodeBlock.UGARITIC, Character.UnicodeBlock.of(0x10380));
+        assertEquals(Character.UnicodeBlock.UGARITIC, Character.UnicodeBlock.of(0x1039f));
+        assertNull(Character.UnicodeBlock.of(0x103a0));
+        assertNull(Character.UnicodeBlock.of(0x103ff));
+        assertEquals(Character.UnicodeBlock.DESERET, Character.UnicodeBlock.of(0x10400));
+        assertEquals(Character.UnicodeBlock.DESERET, Character.UnicodeBlock.of(0x1044f));
+        assertEquals(Character.UnicodeBlock.SHAVIAN, Character.UnicodeBlock.of(0x10450));
+        assertEquals(Character.UnicodeBlock.SHAVIAN, Character.UnicodeBlock.of(0x1047f));
+        assertEquals(Character.UnicodeBlock.OSMANYA, Character.UnicodeBlock.of(0x10480));
+        assertEquals(Character.UnicodeBlock.OSMANYA, Character.UnicodeBlock.of(0x104af));
+        assertNull(Character.UnicodeBlock.of(0x104b0));
+        assertNull(Character.UnicodeBlock.of(0x107ff));
+        assertEquals(Character.UnicodeBlock.CYPRIOT_SYLLABARY, Character.UnicodeBlock.of(0x10800));
+        assertEquals(Character.UnicodeBlock.CYPRIOT_SYLLABARY, Character.UnicodeBlock.of(0x1083f));
+        assertNull(Character.UnicodeBlock.of(0x10840));
+        assertNull(Character.UnicodeBlock.of(0x1cfff));
+        assertEquals(Character.UnicodeBlock.BYZANTINE_MUSICAL_SYMBOLS, Character.UnicodeBlock.of(0x1d000));
+        assertEquals(Character.UnicodeBlock.BYZANTINE_MUSICAL_SYMBOLS, Character.UnicodeBlock.of(0x1d0ff));
+        assertEquals(Character.UnicodeBlock.MUSICAL_SYMBOLS, Character.UnicodeBlock.of(0x1d100));
+        assertEquals(Character.UnicodeBlock.MUSICAL_SYMBOLS, Character.UnicodeBlock.of(0x1d1ff));
+        assertNull(Character.UnicodeBlock.of(0x1d200));
+        assertNull(Character.UnicodeBlock.of(0x1d2ff));
+        assertEquals(Character.UnicodeBlock.TAI_XUAN_JING_SYMBOLS, Character.UnicodeBlock.of(0x1d300));
+        assertEquals(Character.UnicodeBlock.TAI_XUAN_JING_SYMBOLS, Character.UnicodeBlock.of(0x1d35f));
+        assertNull(Character.UnicodeBlock.of(0x1d360));
+        assertNull(Character.UnicodeBlock.of(0x1d3ff));
+        assertEquals(Character.UnicodeBlock.MATHEMATICAL_ALPHANUMERIC_SYMBOLS, Character.UnicodeBlock.of(0x1d400));
+        assertEquals(Character.UnicodeBlock.MATHEMATICAL_ALPHANUMERIC_SYMBOLS, Character.UnicodeBlock.of(0x1d7ff));
+        assertNull(Character.UnicodeBlock.of(0x1d800));
+        assertNull(Character.UnicodeBlock.of(0x1ffff));
+        assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B, Character.UnicodeBlock.of(0x20000));
+        assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B, Character.UnicodeBlock.of(0x2a6df));
+        assertNull(Character.UnicodeBlock.of(0x2a6e0));
+        assertNull(Character.UnicodeBlock.of(0x2f7ff));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT, Character.UnicodeBlock.of(0x2f800));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT, Character.UnicodeBlock.of(0x2fa1f));
+        assertNull(Character.UnicodeBlock.of(0x2fa20));
+        assertNull(Character.UnicodeBlock.of(0xdffff));
+        assertEquals(Character.UnicodeBlock.TAGS, Character.UnicodeBlock.of(0xe0000));
+        assertEquals(Character.UnicodeBlock.TAGS, Character.UnicodeBlock.of(0xe007f));
+        assertNull(Character.UnicodeBlock.of(0xe0080));
+        assertNull(Character.UnicodeBlock.of(0xe00ff));
+        assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS_SUPPLEMENT, Character.UnicodeBlock.of(0xe0100));
+        assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS_SUPPLEMENT, Character.UnicodeBlock.of(0xe01ef));
+        assertNull(Character.UnicodeBlock.of(0xe01f0));
+        assertNull(Character.UnicodeBlock.of(0xeffff));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_A, Character.UnicodeBlock.of(0xf0000));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_A, Character.UnicodeBlock.of(0xfffff));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_B, Character.UnicodeBlock.of(0x100000));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_B, Character.UnicodeBlock.of(0x10ffff));
+    }
+
+    public void test_ofIExceptions() {
+        try {
+            Character.UnicodeBlock.of(Character.MAX_CODE_POINT + 1);
+            fail("No illegal argument exception");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void test_forNameLjava_lang_String() {
+        assertEquals(Character.UnicodeBlock.SURROGATES_AREA, Character.UnicodeBlock.forName("SURROGATES_AREA"));
+        assertEquals(Character.UnicodeBlock.BASIC_LATIN, Character.UnicodeBlock.forName("BASIC_LATIN"));
+        assertEquals(Character.UnicodeBlock.BASIC_LATIN, Character.UnicodeBlock.forName("Basic Latin"));
+        assertEquals(Character.UnicodeBlock.BASIC_LATIN, Character.UnicodeBlock.forName("BasicLatin"));
+        assertEquals(Character.UnicodeBlock.LATIN_1_SUPPLEMENT, Character.UnicodeBlock.forName("LATIN_1_SUPPLEMENT"));
+        assertEquals(Character.UnicodeBlock.LATIN_1_SUPPLEMENT, Character.UnicodeBlock.forName("Latin-1 Supplement"));
+        assertEquals(Character.UnicodeBlock.LATIN_1_SUPPLEMENT, Character.UnicodeBlock.forName("Latin-1Supplement"));
+        assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_A, Character.UnicodeBlock.forName("LATIN_EXTENDED_A"));
+        assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_A, Character.UnicodeBlock.forName("Latin Extended-A"));
+        assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_A, Character.UnicodeBlock.forName("LatinExtended-A"));
+        assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_B, Character.UnicodeBlock.forName("LATIN_EXTENDED_B"));
+        assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_B, Character.UnicodeBlock.forName("Latin Extended-B"));
+        assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_B, Character.UnicodeBlock.forName("LatinExtended-B"));
+        assertEquals(Character.UnicodeBlock.IPA_EXTENSIONS, Character.UnicodeBlock.forName("IPA_EXTENSIONS"));
+        assertEquals(Character.UnicodeBlock.IPA_EXTENSIONS, Character.UnicodeBlock.forName("IPA Extensions"));
+        assertEquals(Character.UnicodeBlock.IPA_EXTENSIONS, Character.UnicodeBlock.forName("IPAExtensions"));
+        assertEquals(Character.UnicodeBlock.SPACING_MODIFIER_LETTERS, Character.UnicodeBlock.forName("SPACING_MODIFIER_LETTERS"));
+        assertEquals(Character.UnicodeBlock.SPACING_MODIFIER_LETTERS, Character.UnicodeBlock.forName("Spacing Modifier Letters"));
+        assertEquals(Character.UnicodeBlock.SPACING_MODIFIER_LETTERS, Character.UnicodeBlock.forName("SpacingModifierLetters"));
+        assertEquals(Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS, Character.UnicodeBlock.forName("COMBINING_DIACRITICAL_MARKS"));
+        assertEquals(Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS, Character.UnicodeBlock.forName("Combining Diacritical Marks"));
+        assertEquals(Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS, Character.UnicodeBlock.forName("CombiningDiacriticalMarks"));
+        assertEquals(Character.UnicodeBlock.GREEK, Character.UnicodeBlock.forName("GREEK"));
+        assertEquals(Character.UnicodeBlock.GREEK, Character.UnicodeBlock.forName("Greek and Coptic"));
+        assertEquals(Character.UnicodeBlock.GREEK, Character.UnicodeBlock.forName("GreekandCoptic"));
+        assertEquals(Character.UnicodeBlock.GREEK, Character.UnicodeBlock.forName("Greek"));
+        assertEquals(Character.UnicodeBlock.GREEK, Character.UnicodeBlock.forName("Greek"));
+        assertEquals(Character.UnicodeBlock.CYRILLIC, Character.UnicodeBlock.forName("CYRILLIC"));
+        assertEquals(Character.UnicodeBlock.CYRILLIC_SUPPLEMENTARY, Character.UnicodeBlock.forName("CYRILLIC_SUPPLEMENTARY"));
+        assertEquals(Character.UnicodeBlock.CYRILLIC_SUPPLEMENTARY, Character.UnicodeBlock.forName("Cyrillic Supplementary"));
+        assertEquals(Character.UnicodeBlock.CYRILLIC_SUPPLEMENTARY, Character.UnicodeBlock.forName("CyrillicSupplementary"));
+        assertEquals(Character.UnicodeBlock.ARMENIAN, Character.UnicodeBlock.forName("ARMENIAN"));
+        assertEquals(Character.UnicodeBlock.HEBREW, Character.UnicodeBlock.forName("HEBREW"));
+        assertEquals(Character.UnicodeBlock.ARABIC, Character.UnicodeBlock.forName("ARABIC"));
+        assertEquals(Character.UnicodeBlock.SYRIAC, Character.UnicodeBlock.forName("SYRIAC"));
+        assertEquals(Character.UnicodeBlock.THAANA, Character.UnicodeBlock.forName("THAANA"));
+        assertEquals(Character.UnicodeBlock.DEVANAGARI, Character.UnicodeBlock.forName("DEVANAGARI"));
+        assertEquals(Character.UnicodeBlock.BENGALI, Character.UnicodeBlock.forName("BENGALI"));
+        assertEquals(Character.UnicodeBlock.GURMUKHI, Character.UnicodeBlock.forName("GURMUKHI"));
+        assertEquals(Character.UnicodeBlock.GUJARATI, Character.UnicodeBlock.forName("GUJARATI"));
+        assertEquals(Character.UnicodeBlock.ORIYA, Character.UnicodeBlock.forName("ORIYA"));
+        assertEquals(Character.UnicodeBlock.TAMIL, Character.UnicodeBlock.forName("TAMIL"));
+        assertEquals(Character.UnicodeBlock.TELUGU, Character.UnicodeBlock.forName("TELUGU"));
+        assertEquals(Character.UnicodeBlock.KANNADA, Character.UnicodeBlock.forName("KANNADA"));
+        assertEquals(Character.UnicodeBlock.MALAYALAM, Character.UnicodeBlock.forName("MALAYALAM"));
+        assertEquals(Character.UnicodeBlock.SINHALA, Character.UnicodeBlock.forName("SINHALA"));
+        assertEquals(Character.UnicodeBlock.THAI, Character.UnicodeBlock.forName("THAI"));
+        assertEquals(Character.UnicodeBlock.LAO, Character.UnicodeBlock.forName("LAO"));
+        assertEquals(Character.UnicodeBlock.TIBETAN, Character.UnicodeBlock.forName("TIBETAN"));
+        assertEquals(Character.UnicodeBlock.MYANMAR, Character.UnicodeBlock.forName("MYANMAR"));
+        assertEquals(Character.UnicodeBlock.GEORGIAN, Character.UnicodeBlock.forName("GEORGIAN"));
+        assertEquals(Character.UnicodeBlock.HANGUL_JAMO, Character.UnicodeBlock.forName("HANGUL_JAMO"));
+        assertEquals(Character.UnicodeBlock.HANGUL_JAMO, Character.UnicodeBlock.forName("Hangul Jamo"));
+        assertEquals(Character.UnicodeBlock.HANGUL_JAMO, Character.UnicodeBlock.forName("HangulJamo"));
+        assertEquals(Character.UnicodeBlock.ETHIOPIC, Character.UnicodeBlock.forName("ETHIOPIC"));
+        assertEquals(Character.UnicodeBlock.CHEROKEE, Character.UnicodeBlock.forName("CHEROKEE"));
+        assertEquals(Character.UnicodeBlock.UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS, Character.UnicodeBlock.forName("UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS"));
+        assertEquals(Character.UnicodeBlock.UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS, Character.UnicodeBlock.forName("Unified Canadian Aboriginal Syllabics"));
+        assertEquals(Character.UnicodeBlock.UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS, Character.UnicodeBlock.forName("UnifiedCanadianAboriginalSyllabics"));
+        assertEquals(Character.UnicodeBlock.OGHAM, Character.UnicodeBlock.forName("OGHAM"));
+        assertEquals(Character.UnicodeBlock.RUNIC, Character.UnicodeBlock.forName("RUNIC"));
+        assertEquals(Character.UnicodeBlock.TAGALOG, Character.UnicodeBlock.forName("TAGALOG"));
+        assertEquals(Character.UnicodeBlock.HANUNOO, Character.UnicodeBlock.forName("HANUNOO"));
+        assertEquals(Character.UnicodeBlock.BUHID, Character.UnicodeBlock.forName("BUHID"));
+        assertEquals(Character.UnicodeBlock.TAGBANWA, Character.UnicodeBlock.forName("TAGBANWA"));
+        assertEquals(Character.UnicodeBlock.KHMER, Character.UnicodeBlock.forName("KHMER"));
+        assertEquals(Character.UnicodeBlock.MONGOLIAN, Character.UnicodeBlock.forName("MONGOLIAN"));
+        assertEquals(Character.UnicodeBlock.LIMBU, Character.UnicodeBlock.forName("LIMBU"));
+        assertEquals(Character.UnicodeBlock.TAI_LE, Character.UnicodeBlock.forName("TAI_LE"));
+        assertEquals(Character.UnicodeBlock.TAI_LE, Character.UnicodeBlock.forName("Tai Le"));
+        assertEquals(Character.UnicodeBlock.TAI_LE, Character.UnicodeBlock.forName("TaiLe"));
+        assertEquals(Character.UnicodeBlock.KHMER_SYMBOLS, Character.UnicodeBlock.forName("KHMER_SYMBOLS"));
+        assertEquals(Character.UnicodeBlock.KHMER_SYMBOLS, Character.UnicodeBlock.forName("Khmer Symbols"));
+        assertEquals(Character.UnicodeBlock.KHMER_SYMBOLS, Character.UnicodeBlock.forName("KhmerSymbols"));
+        assertEquals(Character.UnicodeBlock.PHONETIC_EXTENSIONS, Character.UnicodeBlock.forName("PHONETIC_EXTENSIONS"));
+        assertEquals(Character.UnicodeBlock.PHONETIC_EXTENSIONS, Character.UnicodeBlock.forName("Phonetic Extensions"));
+        assertEquals(Character.UnicodeBlock.PHONETIC_EXTENSIONS, Character.UnicodeBlock.forName("PhoneticExtensions"));
+        assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_ADDITIONAL, Character.UnicodeBlock.forName("LATIN_EXTENDED_ADDITIONAL"));
+        assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_ADDITIONAL, Character.UnicodeBlock.forName("Latin Extended Additional"));
+        assertEquals(Character.UnicodeBlock.LATIN_EXTENDED_ADDITIONAL, Character.UnicodeBlock.forName("LatinExtendedAdditional"));
+        assertEquals(Character.UnicodeBlock.GREEK_EXTENDED, Character.UnicodeBlock.forName("GREEK_EXTENDED"));
+        assertEquals(Character.UnicodeBlock.GREEK_EXTENDED, Character.UnicodeBlock.forName("Greek Extended"));
+        assertEquals(Character.UnicodeBlock.GREEK_EXTENDED, Character.UnicodeBlock.forName("GreekExtended"));
+        assertEquals(Character.UnicodeBlock.GENERAL_PUNCTUATION, Character.UnicodeBlock.forName("GENERAL_PUNCTUATION"));
+        assertEquals(Character.UnicodeBlock.GENERAL_PUNCTUATION, Character.UnicodeBlock.forName("General Punctuation"));
+        assertEquals(Character.UnicodeBlock.GENERAL_PUNCTUATION, Character.UnicodeBlock.forName("GeneralPunctuation"));
+        assertEquals(Character.UnicodeBlock.SUPERSCRIPTS_AND_SUBSCRIPTS, Character.UnicodeBlock.forName("SUPERSCRIPTS_AND_SUBSCRIPTS"));
+        assertEquals(Character.UnicodeBlock.SUPERSCRIPTS_AND_SUBSCRIPTS, Character.UnicodeBlock.forName("Superscripts and Subscripts"));
+        assertEquals(Character.UnicodeBlock.SUPERSCRIPTS_AND_SUBSCRIPTS, Character.UnicodeBlock.forName("SuperscriptsandSubscripts"));
+        assertEquals(Character.UnicodeBlock.CURRENCY_SYMBOLS, Character.UnicodeBlock.forName("CURRENCY_SYMBOLS"));
+        assertEquals(Character.UnicodeBlock.CURRENCY_SYMBOLS, Character.UnicodeBlock.forName("Currency Symbols"));
+        assertEquals(Character.UnicodeBlock.CURRENCY_SYMBOLS, Character.UnicodeBlock.forName("CurrencySymbols"));
+        assertEquals(Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS, Character.UnicodeBlock.forName("COMBINING_MARKS_FOR_SYMBOLS"));
+        assertEquals(Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS, Character.UnicodeBlock.forName("Combining Diacritical Marks for Symbols"));
+        assertEquals(Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS, Character.UnicodeBlock.forName("CombiningDiacriticalMarksforSymbols"));
+        assertEquals(Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS, Character.UnicodeBlock.forName("Combining Marks for Symbols"));
+        assertEquals(Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS, Character.UnicodeBlock.forName("CombiningMarksforSymbols"));
+        assertEquals(Character.UnicodeBlock.LETTERLIKE_SYMBOLS, Character.UnicodeBlock.forName("LETTERLIKE_SYMBOLS"));
+        assertEquals(Character.UnicodeBlock.LETTERLIKE_SYMBOLS, Character.UnicodeBlock.forName("Letterlike Symbols"));
+        assertEquals(Character.UnicodeBlock.LETTERLIKE_SYMBOLS, Character.UnicodeBlock.forName("LetterlikeSymbols"));
+        assertEquals(Character.UnicodeBlock.NUMBER_FORMS, Character.UnicodeBlock.forName("NUMBER_FORMS"));
+        assertEquals(Character.UnicodeBlock.NUMBER_FORMS, Character.UnicodeBlock.forName("Number Forms"));
+        assertEquals(Character.UnicodeBlock.NUMBER_FORMS, Character.UnicodeBlock.forName("NumberForms"));
+        assertEquals(Character.UnicodeBlock.ARROWS, Character.UnicodeBlock.forName("ARROWS"));
+        assertEquals(Character.UnicodeBlock.MATHEMATICAL_OPERATORS, Character.UnicodeBlock.forName("MATHEMATICAL_OPERATORS"));
+        assertEquals(Character.UnicodeBlock.MATHEMATICAL_OPERATORS, Character.UnicodeBlock.forName("Mathematical Operators"));
+        assertEquals(Character.UnicodeBlock.MATHEMATICAL_OPERATORS, Character.UnicodeBlock.forName("MathematicalOperators"));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_TECHNICAL, Character.UnicodeBlock.forName("MISCELLANEOUS_TECHNICAL"));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_TECHNICAL, Character.UnicodeBlock.forName("Miscellaneous Technical"));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_TECHNICAL, Character.UnicodeBlock.forName("MiscellaneousTechnical"));
+        assertEquals(Character.UnicodeBlock.CONTROL_PICTURES, Character.UnicodeBlock.forName("CONTROL_PICTURES"));
+        assertEquals(Character.UnicodeBlock.CONTROL_PICTURES, Character.UnicodeBlock.forName("Control Pictures"));
+        assertEquals(Character.UnicodeBlock.CONTROL_PICTURES, Character.UnicodeBlock.forName("ControlPictures"));
+        assertEquals(Character.UnicodeBlock.OPTICAL_CHARACTER_RECOGNITION, Character.UnicodeBlock.forName("OPTICAL_CHARACTER_RECOGNITION"));
+        assertEquals(Character.UnicodeBlock.OPTICAL_CHARACTER_RECOGNITION, Character.UnicodeBlock.forName("Optical Character Recognition"));
+        assertEquals(Character.UnicodeBlock.OPTICAL_CHARACTER_RECOGNITION, Character.UnicodeBlock.forName("OpticalCharacterRecognition"));
+        assertEquals(Character.UnicodeBlock.ENCLOSED_ALPHANUMERICS, Character.UnicodeBlock.forName("ENCLOSED_ALPHANUMERICS"));
+        assertEquals(Character.UnicodeBlock.ENCLOSED_ALPHANUMERICS, Character.UnicodeBlock.forName("Enclosed Alphanumerics"));
+        assertEquals(Character.UnicodeBlock.ENCLOSED_ALPHANUMERICS, Character.UnicodeBlock.forName("EnclosedAlphanumerics"));
+        assertEquals(Character.UnicodeBlock.BOX_DRAWING, Character.UnicodeBlock.forName("BOX_DRAWING"));
+        assertEquals(Character.UnicodeBlock.BOX_DRAWING, Character.UnicodeBlock.forName("Box Drawing"));
+        assertEquals(Character.UnicodeBlock.BOX_DRAWING, Character.UnicodeBlock.forName("BoxDrawing"));
+        assertEquals(Character.UnicodeBlock.BLOCK_ELEMENTS, Character.UnicodeBlock.forName("BLOCK_ELEMENTS"));
+        assertEquals(Character.UnicodeBlock.BLOCK_ELEMENTS, Character.UnicodeBlock.forName("Block Elements"));
+        assertEquals(Character.UnicodeBlock.BLOCK_ELEMENTS, Character.UnicodeBlock.forName("BlockElements"));
+        assertEquals(Character.UnicodeBlock.GEOMETRIC_SHAPES, Character.UnicodeBlock.forName("GEOMETRIC_SHAPES"));
+        assertEquals(Character.UnicodeBlock.GEOMETRIC_SHAPES, Character.UnicodeBlock.forName("Geometric Shapes"));
+        assertEquals(Character.UnicodeBlock.GEOMETRIC_SHAPES, Character.UnicodeBlock.forName("GeometricShapes"));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS, Character.UnicodeBlock.forName("MISCELLANEOUS_SYMBOLS"));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS, Character.UnicodeBlock.forName("Miscellaneous Symbols"));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS, Character.UnicodeBlock.forName("MiscellaneousSymbols"));
+        assertEquals(Character.UnicodeBlock.DINGBATS, Character.UnicodeBlock.forName("DINGBATS"));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A, Character.UnicodeBlock.forName("MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A"));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A, Character.UnicodeBlock.forName("Miscellaneous Mathematical Symbols-A"));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A, Character.UnicodeBlock.forName("MiscellaneousMathematicalSymbols-A"));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_A, Character.UnicodeBlock.forName("SUPPLEMENTAL_ARROWS_A"));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_A, Character.UnicodeBlock.forName("Supplemental Arrows-A"));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_A, Character.UnicodeBlock.forName("SupplementalArrows-A"));
+        assertEquals(Character.UnicodeBlock.BRAILLE_PATTERNS, Character.UnicodeBlock.forName("BRAILLE_PATTERNS"));
+        assertEquals(Character.UnicodeBlock.BRAILLE_PATTERNS, Character.UnicodeBlock.forName("Braille Patterns"));
+        assertEquals(Character.UnicodeBlock.BRAILLE_PATTERNS, Character.UnicodeBlock.forName("BraillePatterns"));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_B, Character.UnicodeBlock.forName("SUPPLEMENTAL_ARROWS_B"));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_B, Character.UnicodeBlock.forName("Supplemental Arrows-B"));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_ARROWS_B, Character.UnicodeBlock.forName("SupplementalArrows-B"));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B, Character.UnicodeBlock.forName("MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B"));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B, Character.UnicodeBlock.forName("Miscellaneous Mathematical Symbols-B"));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B, Character.UnicodeBlock.forName("MiscellaneousMathematicalSymbols-B"));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_MATHEMATICAL_OPERATORS, Character.UnicodeBlock.forName("SUPPLEMENTAL_MATHEMATICAL_OPERATORS"));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_MATHEMATICAL_OPERATORS, Character.UnicodeBlock.forName("Supplemental Mathematical Operators"));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTAL_MATHEMATICAL_OPERATORS, Character.UnicodeBlock.forName("SupplementalMathematicalOperators"));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS_AND_ARROWS, Character.UnicodeBlock.forName("MISCELLANEOUS_SYMBOLS_AND_ARROWS"));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS_AND_ARROWS, Character.UnicodeBlock.forName("Miscellaneous Symbols and Arrows"));
+        assertEquals(Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS_AND_ARROWS, Character.UnicodeBlock.forName("MiscellaneousSymbolsandArrows"));
+        assertEquals(Character.UnicodeBlock.CJK_RADICALS_SUPPLEMENT, Character.UnicodeBlock.forName("CJK_RADICALS_SUPPLEMENT"));
+        assertEquals(Character.UnicodeBlock.CJK_RADICALS_SUPPLEMENT, Character.UnicodeBlock.forName("CJK Radicals Supplement"));
+        assertEquals(Character.UnicodeBlock.CJK_RADICALS_SUPPLEMENT, Character.UnicodeBlock.forName("CJKRadicalsSupplement"));
+        assertEquals(Character.UnicodeBlock.KANGXI_RADICALS, Character.UnicodeBlock.forName("KANGXI_RADICALS"));
+        assertEquals(Character.UnicodeBlock.KANGXI_RADICALS, Character.UnicodeBlock.forName("Kangxi Radicals"));
+        assertEquals(Character.UnicodeBlock.KANGXI_RADICALS, Character.UnicodeBlock.forName("KangxiRadicals"));
+        assertEquals(Character.UnicodeBlock.IDEOGRAPHIC_DESCRIPTION_CHARACTERS, Character.UnicodeBlock.forName("IDEOGRAPHIC_DESCRIPTION_CHARACTERS"));
+        assertEquals(Character.UnicodeBlock.IDEOGRAPHIC_DESCRIPTION_CHARACTERS, Character.UnicodeBlock.forName("Ideographic Description Characters"));
+        assertEquals(Character.UnicodeBlock.IDEOGRAPHIC_DESCRIPTION_CHARACTERS, Character.UnicodeBlock.forName("IdeographicDescriptionCharacters"));
+        assertEquals(Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION, Character.UnicodeBlock.forName("CJK_SYMBOLS_AND_PUNCTUATION"));
+        assertEquals(Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION, Character.UnicodeBlock.forName("CJK Symbols and Punctuation"));
+        assertEquals(Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION, Character.UnicodeBlock.forName("CJKSymbolsandPunctuation"));
+        assertEquals(Character.UnicodeBlock.HIRAGANA, Character.UnicodeBlock.forName("HIRAGANA"));
+        assertEquals(Character.UnicodeBlock.KATAKANA, Character.UnicodeBlock.forName("KATAKANA"));
+        assertEquals(Character.UnicodeBlock.BOPOMOFO, Character.UnicodeBlock.forName("BOPOMOFO"));
+        assertEquals(Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO, Character.UnicodeBlock.forName("HANGUL_COMPATIBILITY_JAMO"));
+        assertEquals(Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO, Character.UnicodeBlock.forName("Hangul Compatibility Jamo"));
+        assertEquals(Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO, Character.UnicodeBlock.forName("HangulCompatibilityJamo"));
+        assertEquals(Character.UnicodeBlock.KANBUN, Character.UnicodeBlock.forName("KANBUN"));
+        assertEquals(Character.UnicodeBlock.BOPOMOFO_EXTENDED, Character.UnicodeBlock.forName("BOPOMOFO_EXTENDED"));
+        assertEquals(Character.UnicodeBlock.BOPOMOFO_EXTENDED, Character.UnicodeBlock.forName("Bopomofo Extended"));
+        assertEquals(Character.UnicodeBlock.BOPOMOFO_EXTENDED, Character.UnicodeBlock.forName("BopomofoExtended"));
+        assertEquals(Character.UnicodeBlock.KATAKANA_PHONETIC_EXTENSIONS, Character.UnicodeBlock.forName("KATAKANA_PHONETIC_EXTENSIONS"));
+        assertEquals(Character.UnicodeBlock.KATAKANA_PHONETIC_EXTENSIONS, Character.UnicodeBlock.forName("Katakana Phonetic Extensions"));
+        assertEquals(Character.UnicodeBlock.KATAKANA_PHONETIC_EXTENSIONS, Character.UnicodeBlock.forName("KatakanaPhoneticExtensions"));
+        assertEquals(Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS, Character.UnicodeBlock.forName("ENCLOSED_CJK_LETTERS_AND_MONTHS"));
+        assertEquals(Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS, Character.UnicodeBlock.forName("Enclosed CJK Letters and Months"));
+        assertEquals(Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS, Character.UnicodeBlock.forName("EnclosedCJKLettersandMonths"));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY, Character.UnicodeBlock.forName("CJK_COMPATIBILITY"));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY, Character.UnicodeBlock.forName("CJK Compatibility"));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY, Character.UnicodeBlock.forName("CJKCompatibility"));
+        assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A, Character.UnicodeBlock.forName("CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A"));
+        assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A, Character.UnicodeBlock.forName("CJK Unified Ideographs Extension A"));
+        assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A, Character.UnicodeBlock.forName("CJKUnifiedIdeographsExtensionA"));
+        assertEquals(Character.UnicodeBlock.YIJING_HEXAGRAM_SYMBOLS, Character.UnicodeBlock.forName("YIJING_HEXAGRAM_SYMBOLS"));
+        assertEquals(Character.UnicodeBlock.YIJING_HEXAGRAM_SYMBOLS, Character.UnicodeBlock.forName("Yijing Hexagram Symbols"));
+        assertEquals(Character.UnicodeBlock.YIJING_HEXAGRAM_SYMBOLS, Character.UnicodeBlock.forName("YijingHexagramSymbols"));
+        assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS, Character.UnicodeBlock.forName("CJK_UNIFIED_IDEOGRAPHS"));
+        assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS, Character.UnicodeBlock.forName("CJK Unified Ideographs"));
+        assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS, Character.UnicodeBlock.forName("CJKUnifiedIdeographs"));
+        assertEquals(Character.UnicodeBlock.YI_SYLLABLES, Character.UnicodeBlock.forName("YI_SYLLABLES"));
+        assertEquals(Character.UnicodeBlock.YI_SYLLABLES, Character.UnicodeBlock.forName("Yi Syllables"));
+        assertEquals(Character.UnicodeBlock.YI_SYLLABLES, Character.UnicodeBlock.forName("YiSyllables"));
+        assertEquals(Character.UnicodeBlock.YI_RADICALS, Character.UnicodeBlock.forName("YI_RADICALS"));
+        assertEquals(Character.UnicodeBlock.YI_RADICALS, Character.UnicodeBlock.forName("Yi Radicals"));
+        assertEquals(Character.UnicodeBlock.YI_RADICALS, Character.UnicodeBlock.forName("YiRadicals"));
+        assertEquals(Character.UnicodeBlock.HANGUL_SYLLABLES, Character.UnicodeBlock.forName("HANGUL_SYLLABLES"));
+        assertEquals(Character.UnicodeBlock.HANGUL_SYLLABLES, Character.UnicodeBlock.forName("Hangul Syllables"));
+        assertEquals(Character.UnicodeBlock.HANGUL_SYLLABLES, Character.UnicodeBlock.forName("HangulSyllables"));
+        assertEquals(Character.UnicodeBlock.HIGH_SURROGATES, Character.UnicodeBlock.forName("HIGH_SURROGATES"));
+        assertEquals(Character.UnicodeBlock.HIGH_SURROGATES, Character.UnicodeBlock.forName("High Surrogates"));
+        assertEquals(Character.UnicodeBlock.HIGH_SURROGATES, Character.UnicodeBlock.forName("HighSurrogates"));
+        assertEquals(Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES, Character.UnicodeBlock.forName("HIGH_PRIVATE_USE_SURROGATES"));
+        assertEquals(Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES, Character.UnicodeBlock.forName("High Private Use Surrogates"));
+        assertEquals(Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES, Character.UnicodeBlock.forName("HighPrivateUseSurrogates"));
+        assertEquals(Character.UnicodeBlock.LOW_SURROGATES, Character.UnicodeBlock.forName("LOW_SURROGATES"));
+        assertEquals(Character.UnicodeBlock.LOW_SURROGATES, Character.UnicodeBlock.forName("Low Surrogates"));
+        assertEquals(Character.UnicodeBlock.LOW_SURROGATES, Character.UnicodeBlock.forName("LowSurrogates"));
+        assertEquals(Character.UnicodeBlock.PRIVATE_USE_AREA, Character.UnicodeBlock.forName("PRIVATE_USE_AREA"));
+        assertEquals(Character.UnicodeBlock.PRIVATE_USE_AREA, Character.UnicodeBlock.forName("Private Use Area"));
+        assertEquals(Character.UnicodeBlock.PRIVATE_USE_AREA, Character.UnicodeBlock.forName("PrivateUseArea"));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS, Character.UnicodeBlock.forName("CJK_COMPATIBILITY_IDEOGRAPHS"));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS, Character.UnicodeBlock.forName("CJK Compatibility Ideographs"));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS, Character.UnicodeBlock.forName("CJKCompatibilityIdeographs"));
+        assertEquals(Character.UnicodeBlock.ALPHABETIC_PRESENTATION_FORMS, Character.UnicodeBlock.forName("ALPHABETIC_PRESENTATION_FORMS"));
+        assertEquals(Character.UnicodeBlock.ALPHABETIC_PRESENTATION_FORMS, Character.UnicodeBlock.forName("Alphabetic Presentation Forms"));
+        assertEquals(Character.UnicodeBlock.ALPHABETIC_PRESENTATION_FORMS, Character.UnicodeBlock.forName("AlphabeticPresentationForms"));
+        assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_A, Character.UnicodeBlock.forName("ARABIC_PRESENTATION_FORMS_A"));
+        assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_A, Character.UnicodeBlock.forName("Arabic Presentation Forms-A"));
+        assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_A, Character.UnicodeBlock.forName("ArabicPresentationForms-A"));
+        assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS, Character.UnicodeBlock.forName("VARIATION_SELECTORS"));
+        assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS, Character.UnicodeBlock.forName("Variation Selectors"));
+        assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS, Character.UnicodeBlock.forName("VariationSelectors"));
+        assertEquals(Character.UnicodeBlock.COMBINING_HALF_MARKS, Character.UnicodeBlock.forName("COMBINING_HALF_MARKS"));
+        assertEquals(Character.UnicodeBlock.COMBINING_HALF_MARKS, Character.UnicodeBlock.forName("Combining Half Marks"));
+        assertEquals(Character.UnicodeBlock.COMBINING_HALF_MARKS, Character.UnicodeBlock.forName("CombiningHalfMarks"));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS, Character.UnicodeBlock.forName("CJK_COMPATIBILITY_FORMS"));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS, Character.UnicodeBlock.forName("CJK Compatibility Forms"));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS, Character.UnicodeBlock.forName("CJKCompatibilityForms"));
+        assertEquals(Character.UnicodeBlock.SMALL_FORM_VARIANTS, Character.UnicodeBlock.forName("SMALL_FORM_VARIANTS"));
+        assertEquals(Character.UnicodeBlock.SMALL_FORM_VARIANTS, Character.UnicodeBlock.forName("Small Form Variants"));
+        assertEquals(Character.UnicodeBlock.SMALL_FORM_VARIANTS, Character.UnicodeBlock.forName("SmallFormVariants"));
+        assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_B, Character.UnicodeBlock.forName("ARABIC_PRESENTATION_FORMS_B"));
+        assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_B, Character.UnicodeBlock.forName("Arabic Presentation Forms-B"));
+        assertEquals(Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_B, Character.UnicodeBlock.forName("ArabicPresentationForms-B"));
+        assertEquals(Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS, Character.UnicodeBlock.forName("HALFWIDTH_AND_FULLWIDTH_FORMS"));
+        assertEquals(Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS, Character.UnicodeBlock.forName("Halfwidth and Fullwidth Forms"));
+        assertEquals(Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS, Character.UnicodeBlock.forName("HalfwidthandFullwidthForms"));
+        assertEquals(Character.UnicodeBlock.SPECIALS, Character.UnicodeBlock.forName("SPECIALS"));
+        assertEquals(Character.UnicodeBlock.LINEAR_B_SYLLABARY, Character.UnicodeBlock.forName("LINEAR_B_SYLLABARY"));
+        assertEquals(Character.UnicodeBlock.LINEAR_B_SYLLABARY, Character.UnicodeBlock.forName("Linear B Syllabary"));
+        assertEquals(Character.UnicodeBlock.LINEAR_B_SYLLABARY, Character.UnicodeBlock.forName("LinearBSyllabary"));
+        assertEquals(Character.UnicodeBlock.LINEAR_B_IDEOGRAMS, Character.UnicodeBlock.forName("LINEAR_B_IDEOGRAMS"));
+        assertEquals(Character.UnicodeBlock.LINEAR_B_IDEOGRAMS, Character.UnicodeBlock.forName("Linear B Ideograms"));
+        assertEquals(Character.UnicodeBlock.LINEAR_B_IDEOGRAMS, Character.UnicodeBlock.forName("LinearBIdeograms"));
+        assertEquals(Character.UnicodeBlock.AEGEAN_NUMBERS, Character.UnicodeBlock.forName("AEGEAN_NUMBERS"));
+        assertEquals(Character.UnicodeBlock.AEGEAN_NUMBERS, Character.UnicodeBlock.forName("Aegean Numbers"));
+        assertEquals(Character.UnicodeBlock.AEGEAN_NUMBERS, Character.UnicodeBlock.forName("AegeanNumbers"));
+        assertEquals(Character.UnicodeBlock.OLD_ITALIC, Character.UnicodeBlock.forName("OLD_ITALIC"));
+        assertEquals(Character.UnicodeBlock.OLD_ITALIC, Character.UnicodeBlock.forName("Old Italic"));
+        assertEquals(Character.UnicodeBlock.OLD_ITALIC, Character.UnicodeBlock.forName("OldItalic"));
+        assertEquals(Character.UnicodeBlock.GOTHIC, Character.UnicodeBlock.forName("GOTHIC"));
+        assertEquals(Character.UnicodeBlock.UGARITIC, Character.UnicodeBlock.forName("UGARITIC"));
+        assertEquals(Character.UnicodeBlock.DESERET, Character.UnicodeBlock.forName("DESERET"));
+        assertEquals(Character.UnicodeBlock.SHAVIAN, Character.UnicodeBlock.forName("SHAVIAN"));
+        assertEquals(Character.UnicodeBlock.OSMANYA, Character.UnicodeBlock.forName("OSMANYA"));
+        assertEquals(Character.UnicodeBlock.CYPRIOT_SYLLABARY, Character.UnicodeBlock.forName("CYPRIOT_SYLLABARY"));
+        assertEquals(Character.UnicodeBlock.CYPRIOT_SYLLABARY, Character.UnicodeBlock.forName("Cypriot Syllabary"));
+        assertEquals(Character.UnicodeBlock.CYPRIOT_SYLLABARY, Character.UnicodeBlock.forName("CypriotSyllabary"));
+        assertEquals(Character.UnicodeBlock.BYZANTINE_MUSICAL_SYMBOLS, Character.UnicodeBlock.forName("BYZANTINE_MUSICAL_SYMBOLS"));
+        assertEquals(Character.UnicodeBlock.BYZANTINE_MUSICAL_SYMBOLS, Character.UnicodeBlock.forName("Byzantine Musical Symbols"));
+        assertEquals(Character.UnicodeBlock.BYZANTINE_MUSICAL_SYMBOLS, Character.UnicodeBlock.forName("ByzantineMusicalSymbols"));
+        assertEquals(Character.UnicodeBlock.MUSICAL_SYMBOLS, Character.UnicodeBlock.forName("MUSICAL_SYMBOLS"));
+        assertEquals(Character.UnicodeBlock.MUSICAL_SYMBOLS, Character.UnicodeBlock.forName("Musical Symbols"));
+        assertEquals(Character.UnicodeBlock.MUSICAL_SYMBOLS, Character.UnicodeBlock.forName("MusicalSymbols"));
+        assertEquals(Character.UnicodeBlock.TAI_XUAN_JING_SYMBOLS, Character.UnicodeBlock.forName("TAI_XUAN_JING_SYMBOLS"));
+        assertEquals(Character.UnicodeBlock.TAI_XUAN_JING_SYMBOLS, Character.UnicodeBlock.forName("Tai Xuan Jing Symbols"));
+        assertEquals(Character.UnicodeBlock.TAI_XUAN_JING_SYMBOLS, Character.UnicodeBlock.forName("TaiXuanJingSymbols"));
+        assertEquals(Character.UnicodeBlock.MATHEMATICAL_ALPHANUMERIC_SYMBOLS, Character.UnicodeBlock.forName("MATHEMATICAL_ALPHANUMERIC_SYMBOLS"));
+        assertEquals(Character.UnicodeBlock.MATHEMATICAL_ALPHANUMERIC_SYMBOLS, Character.UnicodeBlock.forName("Mathematical Alphanumeric Symbols"));
+        assertEquals(Character.UnicodeBlock.MATHEMATICAL_ALPHANUMERIC_SYMBOLS, Character.UnicodeBlock.forName("MathematicalAlphanumericSymbols"));
+        assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B, Character.UnicodeBlock.forName("CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B"));
+        assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B, Character.UnicodeBlock.forName("CJK Unified Ideographs Extension B"));
+        assertEquals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B, Character.UnicodeBlock.forName("CJKUnifiedIdeographsExtensionB"));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT, Character.UnicodeBlock.forName("CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT"));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT, Character.UnicodeBlock.forName("CJK Compatibility Ideographs Supplement"));
+        assertEquals(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT, Character.UnicodeBlock.forName("CJKCompatibilityIdeographsSupplement"));
+        assertEquals(Character.UnicodeBlock.TAGS, Character.UnicodeBlock.forName("TAGS"));
+        assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS_SUPPLEMENT, Character.UnicodeBlock.forName("VARIATION_SELECTORS_SUPPLEMENT"));
+        assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS_SUPPLEMENT, Character.UnicodeBlock.forName("Variation Selectors Supplement"));
+        assertEquals(Character.UnicodeBlock.VARIATION_SELECTORS_SUPPLEMENT, Character.UnicodeBlock.forName("VariationSelectorsSupplement"));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_A, Character.UnicodeBlock.forName("SUPPLEMENTARY_PRIVATE_USE_AREA_A"));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_A, Character.UnicodeBlock.forName("Supplementary Private Use Area-A"));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_A, Character.UnicodeBlock.forName("SupplementaryPrivateUseArea-A"));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_B, Character.UnicodeBlock.forName("SUPPLEMENTARY_PRIVATE_USE_AREA_B"));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_B, Character.UnicodeBlock.forName("Supplementary Private Use Area-B"));
+        assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_B, Character.UnicodeBlock.forName("SupplementaryPrivateUseArea-B"));
+    }
+
+    public void test_forNameLjava_lang_StringExceptions() {
+        try {
+            Character.UnicodeBlock.forName(null);
+            fail("No NPE");
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            Character.UnicodeBlock.forName("INVALID_NAME");
+            fail("No illegal argument exception");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/ClassCastExceptionTest.java b/luni/src/test/java/tests/api/java/lang/ClassCastExceptionTest.java
new file mode 100644
index 0000000..4ed7c9a
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/ClassCastExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class ClassCastExceptionTest extends TestCase {
+
+    /**
+     * java.lang.ClassCastException#ClassCastException()
+     */
+    public void test_Constructor() {
+        ClassCastException e = new ClassCastException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * 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/tests/api/java/lang/ClassCircularityErrorTest.java b/luni/src/test/java/tests/api/java/lang/ClassCircularityErrorTest.java
new file mode 100644
index 0000000..91499b6
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/ClassCircularityErrorTest.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 tests.api.java.lang;
+
+import junit.framework.TestCase;
+
+public class ClassCircularityErrorTest extends TestCase {
+    // Thrown when a circularity has been detected while initializing a class.
+
+    /**
+     * java.lang.ClassCircularityError#ClassCircularityError()
+     */
+    public void test_ClassCircularityError() {
+        new ClassCircularityError();
+    }
+
+    /**
+     * 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/tests/api/java/lang/ClassFormatErrorTest.java b/luni/src/test/java/tests/api/java/lang/ClassFormatErrorTest.java
new file mode 100644
index 0000000..d8b3c15
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/ClassFormatErrorTest.java
@@ -0,0 +1,43 @@
+/*
+ * 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.lang;
+
+import junit.framework.TestCase;
+
+public class ClassFormatErrorTest extends TestCase {
+    /**
+     * 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.
+     */
+
+    /**
+     * java.lang.ClassFormatError#ClassFormatError()
+     */
+    public void test_ClassFormatError() {
+        new ClassFormatError();
+    }
+
+    /**
+     * 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/tests/api/java/lang/ClassLoaderTest.java b/luni/src/test/java/tests/api/java/lang/ClassLoaderTest.java
new file mode 100644
index 0000000..014eff3
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/ClassLoaderTest.java
@@ -0,0 +1,269 @@
+/*
+ * 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.lang;
+
+import java.io.InputStream;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+import java.security.SecurityPermission;
+
+import junit.framework.TestCase;
+
+public class ClassLoaderTest extends TestCase {
+
+    public static volatile int flag;
+
+    /**
+     * Tests that Classloader.defineClass() assigns appropriate
+     * default domains to the defined classes.
+     */
+    public void test_defineClass_defaultDomain() throws Exception {
+        // Regression for HARMONY-765 
+        DynamicPolicy plc = new DynamicPolicy();
+        Policy back = Policy.getPolicy();
+        try {
+            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);
+        }
+    }
+
+    static class SyncTestClassLoader extends ClassLoader {
+        Object lock;
+        volatile int numFindClassCalled;
+
+        SyncTestClassLoader(Object o) {
+            this.lock = o;
+            numFindClassCalled = 0;
+        }
+
+        /*
+         * Byte array of bytecode equivalent to the following source code:
+         * public class TestClass {
+         * }
+         */
+        private byte[] classData = new byte[] {
+                -54, -2, -70, -66, 0, 0, 0, 49, 0, 13,
+                10, 0, 3, 0, 10, 7, 0, 11, 7, 0,
+                12, 1, 0, 6, 60, 105, 110, 105, 116, 62,
+                1, 0, 3, 40, 41, 86, 1, 0, 4, 67,
+                111, 100, 101, 1, 0, 15, 76, 105, 110, 101,
+                78, 117, 109, 98, 101, 114, 84, 97, 98, 108,
+                101, 1, 0, 10, 83, 111, 117, 114, 99, 101,
+                70, 105, 108, 101, 1, 0, 14, 84, 101, 115,
+                116, 67, 108, 97, 115, 115, 46, 106, 97, 118,
+                97, 12, 0, 4, 0, 5, 1, 0, 9, 84,
+                101, 115, 116, 67, 108, 97, 115, 115, 1, 0,
+                16, 106, 97, 118, 97, 47, 108, 97, 110, 103,
+                47, 79, 98, 106, 101, 99, 116, 0, 33, 0,
+                2, 0, 3, 0, 0, 0, 0, 0, 1, 0,
+                1, 0, 4, 0, 5, 0, 1, 0, 6, 0,
+                0, 0, 29, 0, 1, 0, 1, 0, 0, 0,
+                5, 42, -73, 0, 1, -79, 0, 0, 0, 1,
+                0, 7, 0, 0, 0, 6, 0, 1, 0, 0,
+                0, 1, 0, 1, 0, 8, 0, 0, 0, 2,
+                0, 9 };
+
+        @Override
+        protected Class<?> findClass(String name) throws ClassNotFoundException {
+            try {
+                while (flag != 2) {
+                    synchronized (lock) {
+                        lock.wait();
+                    }
+                }
+            } catch (InterruptedException ie) {
+            }
+
+            if (name.equals("TestClass")) {
+                numFindClassCalled++;
+                return defineClass(null, classData, 0, classData.length);
+            }
+            throw new ClassNotFoundException("Class " + name + " not found.");
+        }
+    }
+
+    static class SyncLoadTestThread extends Thread {
+        volatile boolean started;
+        ClassLoader cl;
+        Class<?> cls;
+
+        SyncLoadTestThread(ClassLoader cl) {
+            this.cl = cl;
+        }
+
+        @Override
+        public void run() {
+            try {
+                started = true;
+                cls = Class.forName("TestClass", false, cl);
+            } catch (Exception ex) {
+                ex.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * Regression test for HARMONY-1939:
+     * 2 threads simultaneously run Class.forName() method for the same classname
+     * and the same classloader. It is expected that both threads succeed but
+     * class must be defined just once.
+     */
+    public void test_loadClass_concurrentLoad() throws Exception {
+        Object lock = new Object();
+        SyncTestClassLoader cl = new SyncTestClassLoader(lock);
+        SyncLoadTestThread tt1 = new SyncLoadTestThread(cl);
+        SyncLoadTestThread tt2 = new SyncLoadTestThread(cl);
+        flag = 1;
+        tt1.start();
+        tt2.start();
+
+        while (!tt1.started && !tt2.started) {
+            Thread.sleep(100);
+        }
+
+        flag = 2;
+        synchronized (lock) {
+            lock.notifyAll();
+        }
+        tt1.join();
+        tt2.join();
+
+        assertSame("Bad or redefined class", tt1.cls, tt2.cls);
+        assertEquals("Both threads tried to define class", 1, cl.numFindClassCalled);
+    }
+
+    /**
+     * java.lang.ClassLoader#getResource(java.lang.String)
+     */
+    public void test_getResourceLjava_lang_String() {
+        // Test for method java.net.URL
+        // java.lang.ClassLoader.getResource(java.lang.String)
+        java.net.URL u = ClassLoader.getSystemClassLoader().getResource("hyts_Foo.c");
+        assertNotNull("Unable to find resource", u);
+        java.io.InputStream is = null;
+        try {
+            is = u.openStream();
+            assertNotNull("Resource returned is invalid", is);
+            is.close();
+        } catch (java.io.IOException e) {
+            fail("IOException getting stream for resource : " + e.getMessage());
+        }
+    }
+
+    /**
+     * java.lang.ClassLoader#getResourceAsStream(java.lang.String)
+     */
+    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: hyts_Foo.c", (is = ClassLoader
+                .getSystemClassLoader().getResourceAsStream("hyts_Foo.c")));
+        try {
+            is.close();
+        } catch (java.io.IOException e) {
+            fail("Exception during getResourceAsStream: " + e.toString());
+        }
+    }
+
+    /**
+     * java.lang.ClassLoader#getSystemClassLoader()
+     */
+    public void test_getSystemClassLoader() {
+        // Test for method java.lang.ClassLoader
+        // java.lang.ClassLoader.getSystemClassLoader()
+        ClassLoader cl = ClassLoader.getSystemClassLoader();
+        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) {
+        }
+
+    }
+
+    /**
+     * java.lang.ClassLoader#getSystemResource(java.lang.String)
+     */
+    public void test_getSystemResourceLjava_lang_String() {
+        // Test for method java.net.URL
+        // java.lang.ClassLoader.getSystemResource(java.lang.String)
+        // Need better test...
+        assertNotNull("Failed to find resource: hyts_Foo.c", ClassLoader
+                .getSystemResource("hyts_Foo.c"));
+    }
+
+
+    //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 {
+
+    public PermissionCollection pc;
+
+    @Override
+    public PermissionCollection getPermissions(ProtectionDomain pd) {
+        return pc;
+    }
+
+    @Override
+    public PermissionCollection getPermissions(CodeSource codesource) {
+        return pc;
+    }
+
+    @Override
+    public void refresh() {
+    }
+}
+
+class A {
+}
+
+class Ldr extends ClassLoader {
+    @SuppressWarnings("deprecation")
+    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);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/ClassNotFoundExceptionTest.java b/luni/src/test/java/tests/api/java/lang/ClassNotFoundExceptionTest.java
new file mode 100644
index 0000000..9a56281
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/ClassNotFoundExceptionTest.java
@@ -0,0 +1,60 @@
+/*
+ *  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.lang;
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+public class ClassNotFoundExceptionTest extends TestCase {
+    /**
+     * Thrown when an application tries to load in a class through its string
+     * name using the forName method in class Class.
+     */
+
+    /**
+     * java.lang.ClassNotFoundException#ClassNotFoundException()
+     */
+    public void test_Constructor() {
+        ClassNotFoundException e = new ClassNotFoundException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/lang/ClassTest.java b/luni/src/test/java/tests/api/java/lang/ClassTest.java
new file mode 100644
index 0000000..882d43c
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/ClassTest.java
@@ -0,0 +1,643 @@
+/*
+ *  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.lang;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.BasicPermission;
+import java.security.DomainCombiner;
+import java.security.Permission;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.security.Security;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Vector;
+
+import tests.support.resource.Support_Resources;
+
+public class ClassTest extends junit.framework.TestCase {
+
+    public static final String FILENAME = ClassTest.class.getPackage().getName().replace('.', '/') + "/test#.properties";
+
+    static class StaticMember$Class {
+        class Member2$A {
+        }
+    }
+
+    class Member$Class {
+        class Member3$B {
+        }
+    }
+
+    public static class TestClass {
+        @SuppressWarnings("unused")
+        private int privField = 1;
+
+        public int pubField = 2;
+
+        private Object cValue = null;
+
+        public Object ack = new Object();
+
+        @SuppressWarnings("unused")
+        private int privMethod() {
+            return 1;
+        }
+
+        public int pubMethod() {
+            return 2;
+        }
+
+        public Object cValue() {
+            return cValue;
+        }
+
+        public TestClass() {
+        }
+
+        @SuppressWarnings("unused")
+        private TestClass(Object o) {
+        }
+    }
+
+    public static class SubTestClass extends TestClass {
+    }
+
+    /**
+     * java.lang.Class#forName(java.lang.String)
+     */
+    public void test_forNameLjava_lang_String() throws Exception {
+        assertSame("Class for name failed for java.lang.Object",
+                Object.class, Class.forName("java.lang.Object"));
+        assertSame("Class for name failed for [[Ljava.lang.Object;",
+                Object[][].class, Class.forName("[[Ljava.lang.Object;"));
+
+        assertSame("Class for name failed for [I",
+                int[].class, Class.forName("[I"));
+
+        try {
+            Class.forName("int");
+            fail();
+        } catch (ClassNotFoundException e) {
+        }
+
+        try {
+            Class.forName("byte");
+            fail();
+        } catch (ClassNotFoundException e) {
+        }
+        try {
+            Class.forName("char");
+            fail();
+        } catch (ClassNotFoundException e) {
+        }
+
+        try {
+            Class.forName("void");
+            fail();
+        } catch (ClassNotFoundException e) {
+        }
+
+        try {
+            Class.forName("short");
+            fail();
+        } catch (ClassNotFoundException e) {
+        }
+        try {
+            Class.forName("long");
+            fail();
+        } catch (ClassNotFoundException e) {
+        }
+
+        try {
+            Class.forName("boolean");
+            fail();
+        } catch (ClassNotFoundException e) {
+        }
+        try {
+            Class.forName("float");
+            fail();
+        } catch (ClassNotFoundException e) {
+        }
+        try {
+            Class.forName("double");
+            fail();
+        } catch (ClassNotFoundException e) {
+        }
+
+        //regression test for JIRA 2162
+        try {
+            Class.forName("%");
+            fail("should throw ClassNotFoundException.");
+        } catch (ClassNotFoundException e) {
+        }
+
+        //Regression Test for HARMONY-3332
+        String securityProviderClassName;
+        int count = 1;
+        while ((securityProviderClassName = Security
+                .getProperty("security.provider." + count++)) != null) {
+            Class.forName(securityProviderClassName);
+        }
+    }
+
+    /**
+     * java.lang.Class#getClasses()
+     */
+    public void test_getClasses() {
+        assertEquals("Incorrect class array returned",
+                2, ClassTest.class.getClasses().length);
+    }
+
+    /**
+     * java.lang.Class#getClasses()
+     */
+    public void test_getClasses_subtest0() {
+        final Permission privCheckPermission = new BasicPermission("Privilege check") {
+            private static final long serialVersionUID = 1L;
+        };
+
+        class MyCombiner implements DomainCombiner {
+            boolean combine;
+
+            public ProtectionDomain[] combine(ProtectionDomain[] executionDomains,
+                    ProtectionDomain[] parentDomains) {
+                combine = true;
+                return new ProtectionDomain[0];
+            }
+
+            private boolean recurring = false;
+
+            public boolean isPriviledged() {
+                if (recurring) {
+                    return true;
+                }
+                try {
+                    recurring = true;
+                    combine = false;
+                    try {
+                        AccessController.checkPermission(privCheckPermission);
+                    } catch (SecurityException e) {
+                    }
+                    return !combine;
+                } finally {
+                    recurring = false;
+                }
+            }
+        }
+    }
+
+    /**
+     * java.lang.Class#getComponentType()
+     */
+    public void test_getComponentType() {
+        assertSame("int array does not have int component type", int.class, int[].class
+                .getComponentType());
+        assertSame("Object array does not have Object component type", Object.class,
+                Object[].class.getComponentType());
+        assertNull("Object has non-null component type", Object.class.getComponentType());
+    }
+
+    /**
+     * java.lang.Class#getConstructor(java.lang.Class[])
+     */
+    public void test_getConstructor$Ljava_lang_Class()
+            throws NoSuchMethodException {
+        TestClass.class.getConstructor(new Class[0]);
+        try {
+            TestClass.class.getConstructor(Object.class);
+            fail("Found private constructor");
+        } catch (NoSuchMethodException e) {
+            // Correct - constructor with obj is private
+        }
+    }
+
+    /**
+     * java.lang.Class#getConstructors()
+     */
+    public void test_getConstructors() throws Exception {
+        Constructor[] c = TestClass.class.getConstructors();
+        assertEquals("Incorrect number of constructors returned", 1, c.length);
+    }
+
+    /**
+     * java.lang.Class#getDeclaredClasses()
+     */
+    public void test_getDeclaredClasses() {
+        assertEquals("Incorrect class array returned", 2, ClassTest.class.getClasses().length);
+    }
+
+    /**
+     * java.lang.Class#getDeclaredConstructor(java.lang.Class[])
+     */
+    public void test_getDeclaredConstructor$Ljava_lang_Class() throws Exception {
+        Constructor<TestClass> c = TestClass.class.getDeclaredConstructor(new Class[0]);
+        assertNull("Incorrect constructor returned", c.newInstance().cValue());
+        c = TestClass.class.getDeclaredConstructor(Object.class);
+    }
+
+    /**
+     * java.lang.Class#getDeclaredConstructors()
+     */
+    public void test_getDeclaredConstructors() throws Exception {
+        Constructor[] c = TestClass.class.getDeclaredConstructors();
+        assertEquals("Incorrect number of constructors returned", 2, c.length);
+    }
+
+    /**
+     * java.lang.Class#getDeclaredField(java.lang.String)
+     */
+    public void test_getDeclaredFieldLjava_lang_String() throws Exception {
+        Field f = TestClass.class.getDeclaredField("pubField");
+        assertEquals("Returned incorrect field", 2, f.getInt(new TestClass()));
+    }
+
+    /**
+     * java.lang.Class#getDeclaredFields()
+     */
+    public void test_getDeclaredFields() throws Exception {
+        Field[] f = TestClass.class.getDeclaredFields();
+        assertEquals("Returned incorrect number of fields", 4, f.length);
+        f = SubTestClass.class.getDeclaredFields();
+        // Declared fields do not include inherited
+        assertEquals("Returned incorrect number of fields", 0, f.length);
+    }
+
+    /**
+     * java.lang.Class#getDeclaredMethod(java.lang.String,
+     *java.lang.Class[])
+     */
+    public void test_getDeclaredMethodLjava_lang_String$Ljava_lang_Class() throws Exception {
+        Method m = TestClass.class.getDeclaredMethod("pubMethod", new Class[0]);
+        assertEquals("Returned incorrect method", 2, ((Integer) (m.invoke(new TestClass())))
+                .intValue());
+        m = TestClass.class.getDeclaredMethod("privMethod", new Class[0]);
+    }
+
+    /**
+     * java.lang.Class#getDeclaredMethods()
+     */
+    public void test_getDeclaredMethods() throws Exception {
+        Method[] m = TestClass.class.getDeclaredMethods();
+        assertEquals("Returned incorrect number of methods", 3, m.length);
+        m = SubTestClass.class.getDeclaredMethods();
+        assertEquals("Returned incorrect number of methods", 0, m.length);
+    }
+
+    /**
+     * java.lang.Class#getDeclaringClass()
+     */
+    public void test_getDeclaringClass() {
+        assertEquals(ClassTest.class, TestClass.class.getDeclaringClass());
+    }
+
+    /**
+     * java.lang.Class#getField(java.lang.String)
+     */
+    public void test_getFieldLjava_lang_String() throws Exception {
+        Field f = TestClass.class.getField("pubField");
+        assertEquals("Returned incorrect field", 2, f.getInt(new TestClass()));
+        try {
+            f = TestClass.class.getField("privField");
+            fail("Private field access failed to throw exception");
+        } catch (NoSuchFieldException e) {
+            // Correct
+        }
+    }
+
+    /**
+     * java.lang.Class#getFields()
+     */
+    public void test_getFields() throws Exception {
+        Field[] f = TestClass.class.getFields();
+        assertEquals("Incorrect number of fields", 2, f.length);
+        f = SubTestClass.class.getFields();
+        // Check inheritance of pub fields
+        assertEquals("Incorrect number of fields", 2, f.length);
+    }
+
+    /**
+     * java.lang.Class#getInterfaces()
+     */
+    public void test_getInterfaces() {
+        Class[] interfaces;
+        List<?> interfaceList;
+        interfaces = Object.class.getInterfaces();
+        assertEquals("Incorrect interface list for Object", 0, interfaces.length);
+        interfaceList = Arrays.asList(Vector.class.getInterfaces());
+        assertTrue("Incorrect interface list for Vector", interfaceList
+                .contains(Cloneable.class)
+                && interfaceList.contains(Serializable.class)
+                && interfaceList.contains(List.class));
+    }
+
+    /**
+     * java.lang.Class#getMethod(java.lang.String, java.lang.Class[])
+     */
+    public void test_getMethodLjava_lang_String$Ljava_lang_Class() throws Exception {
+        Method m = TestClass.class.getMethod("pubMethod", new Class[0]);
+        assertEquals("Returned incorrect method", 2, ((Integer) (m.invoke(new TestClass())))
+                .intValue());
+        try {
+            m = TestClass.class.getMethod("privMethod", new Class[0]);
+            fail("Failed to throw exception accessing private method");
+        } catch (NoSuchMethodException e) {
+            // Correct
+            return;
+        }
+    }
+
+    /**
+     * java.lang.Class#getMethods()
+     */
+    public void test_getMethods() throws Exception {
+        Method[] m = TestClass.class.getMethods();
+        assertEquals("Returned incorrect number of methods",
+                2 + Object.class.getMethods().length, m.length);
+        m = SubTestClass.class.getMethods();
+        assertEquals("Returned incorrect number of sub-class methods",
+                2 + Object.class.getMethods().length, m.length);
+        // Number of inherited methods
+    }
+
+    private static final class PrivateClass {
+    }
+
+    /**
+     * java.lang.Class#getModifiers()
+     */
+    public void test_getModifiers() {
+        int dcm = PrivateClass.class.getModifiers();
+        assertFalse("default class is public", Modifier.isPublic(dcm));
+        assertFalse("default class is protected", Modifier.isProtected(dcm));
+        assertTrue("default class is not private", Modifier.isPrivate(dcm));
+
+        int ocm = Object.class.getModifiers();
+        assertTrue("public class is not public", Modifier.isPublic(ocm));
+        assertFalse("public class is protected", Modifier.isProtected(ocm));
+        assertFalse("public class is private", Modifier.isPrivate(ocm));
+    }
+
+    /**
+     * java.lang.Class#getName()
+     */
+    public void test_getName() throws Exception {
+        String className = Class.forName("java.lang.Object").getName();
+        assertNotNull(className);
+
+        assertEquals("Class getName printed wrong value", "java.lang.Object", className);
+        assertEquals("Class getName printed wrong value", "int", int.class.getName());
+        className = Class.forName("[I").getName();
+        assertNotNull(className);
+        assertEquals("Class getName printed wrong value", "[I", className);
+
+        className = Class.forName("[Ljava.lang.Object;").getName();
+        assertNotNull(className);
+
+        assertEquals("Class getName printed wrong value", "[Ljava.lang.Object;", className);
+    }
+
+    /**
+     * java.lang.Class#getResource(java.lang.String)
+     */
+    public void test_getResourceLjava_lang_String() {
+        final String name = "/org/apache/harmony/luni/tests/test_resource.txt";
+        URL res = getClass().getResource(name);
+        assertNotNull(res);
+    }
+
+    /**
+     * java.lang.Class#getResourceAsStream(java.lang.String)
+     */
+    public void test_getResourceAsStreamLjava_lang_String() throws Exception {
+        final String name = "/org/apache/harmony/luni/tests/test_resource.txt";
+        assertNotNull("the file " + name + " can not be found in this directory", getClass()
+                .getResourceAsStream(name));
+
+        final String nameBadURI = "org/apache/harmony/luni/tests/test_resource.txt";
+        assertNull("the file " + nameBadURI + " should not be found in this directory",
+                getClass().getResourceAsStream(nameBadURI));
+
+        InputStream str = Object.class.getResourceAsStream("Class.class");
+        assertNotNull("java.lang.Object couldn't find its class with getResource...", str);
+
+        assertTrue("Cannot read single byte", str.read() != -1);
+        assertEquals("Cannot read multiple bytes", 5, str.read(new byte[5]));
+        str.close();
+
+        InputStream str2 = getClass().getResourceAsStream("ClassTest.class");
+        assertNotNull("Can't find resource", str2);
+        assertTrue("Cannot read single byte", str2.read() != -1);
+        assertEquals("Cannot read multiple bytes", 5, str2.read(new byte[5]));
+        str2.close();
+    }
+
+    /**
+     * java.lang.Class#getSuperclass()
+     */
+    public void test_getSuperclass() {
+        assertNull("Object has a superclass???", Object.class.getSuperclass());
+        assertSame("Normal class has bogus superclass", InputStream.class,
+                FileInputStream.class.getSuperclass());
+        assertSame("Array class has bogus superclass", Object.class, FileInputStream[].class
+                .getSuperclass());
+        assertNull("Base class has a superclass", int.class.getSuperclass());
+        assertNull("Interface class has a superclass", Cloneable.class.getSuperclass());
+    }
+
+    /**
+     * java.lang.Class#isArray()
+     */
+    public void test_isArray() throws ClassNotFoundException {
+        assertTrue("Non-array type claims to be.", !int.class.isArray());
+        Class<?> clazz = null;
+        clazz = Class.forName("[I");
+        assertTrue("int Array type claims not to be.", clazz.isArray());
+
+        clazz = Class.forName("[Ljava.lang.Object;");
+        assertTrue("Object Array type claims not to be.", clazz.isArray());
+
+        clazz = Class.forName("java.lang.Object");
+        assertTrue("Non-array Object type claims to be.", !clazz.isArray());
+    }
+
+    /**
+     * java.lang.Class#isAssignableFrom(java.lang.Class)
+     */
+    public void test_isAssignableFromLjava_lang_Class() {
+        Class<?> clazz1 = null;
+        Class<?> clazz2 = null;
+
+        clazz1 = Object.class;
+        clazz2 = Class.class;
+        assertTrue("returned false for superclass", clazz1.isAssignableFrom(clazz2));
+
+        clazz1 = TestClass.class;
+        assertTrue("returned false for same class", clazz1.isAssignableFrom(clazz1));
+
+        clazz1 = Runnable.class;
+        clazz2 = Thread.class;
+        assertTrue("returned false for implemented interface", clazz1.isAssignableFrom(clazz2));
+    }
+
+    /**
+     * java.lang.Class#isInterface()
+     */
+    public void test_isInterface() throws ClassNotFoundException {
+        assertTrue("Prim type claims to be interface.", !int.class.isInterface());
+        Class<?> clazz = null;
+        clazz = Class.forName("[I");
+        assertTrue("Prim Array type claims to be interface.", !clazz.isInterface());
+
+        clazz = Class.forName("java.lang.Runnable");
+        assertTrue("Interface type claims not to be interface.", clazz.isInterface());
+        clazz = Class.forName("java.lang.Object");
+        assertTrue("Object type claims to be interface.", !clazz.isInterface());
+
+        clazz = Class.forName("[Ljava.lang.Object;");
+        assertTrue("Array type claims to be interface.", !clazz.isInterface());
+    }
+
+    /**
+     * java.lang.Class#isPrimitive()
+     */
+    public void test_isPrimitive() {
+        assertFalse("Interface type claims to be primitive.", Runnable.class.isPrimitive());
+        assertFalse("Object type claims to be primitive.", Object.class.isPrimitive());
+        assertFalse("Prim Array type claims to be primitive.", int[].class.isPrimitive());
+        assertFalse("Array type claims to be primitive.", Object[].class.isPrimitive());
+        assertTrue("Prim type claims not to be primitive.", int.class.isPrimitive());
+        assertFalse("Object type claims to be primitive.", Object.class.isPrimitive());
+    }
+
+    /**
+     * java.lang.Class#newInstance()
+     */
+    public void test_newInstance() throws Exception {
+        Class<?> clazz = null;
+        clazz = Class.forName("java.lang.Object");
+        assertNotNull("new object instance was null", clazz.newInstance());
+
+        clazz = Class.forName("java.lang.Throwable");
+        assertSame("new Throwable instance was not a throwable",
+                clazz, clazz.newInstance().getClass());
+
+        clazz = Class.forName("java.lang.Integer");
+        try {
+            clazz.newInstance();
+            fail("Exception for instantiating a newInstance with no default constructor is not thrown");
+        } catch (InstantiationException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.lang.Class#toString()
+     */
+    public void test_toString() throws ClassNotFoundException {
+        assertEquals("Class toString printed wrong value",
+                "int", int.class.toString());
+        Class<?> clazz = null;
+        clazz = Class.forName("[I");
+        assertEquals("Class toString printed wrong value",
+                "class [I", clazz.toString());
+
+        clazz = Class.forName("java.lang.Object");
+        assertEquals("Class toString printed wrong value",
+                "class java.lang.Object", clazz.toString());
+
+        clazz = Class.forName("[Ljava.lang.Object;");
+        assertEquals("Class toString printed wrong value",
+                "class [Ljava.lang.Object;", clazz.toString());
+    }
+
+
+    // Regression Test for JIRA-2047
+    public void test_getResourceAsStream_withSharpChar() throws Exception {
+        InputStream in = getClass().getResourceAsStream("/" + FILENAME);
+        assertNotNull(in);
+        in.close();
+
+        in = getClass().getResourceAsStream(FILENAME);
+        assertNull(in);
+
+        in = this.getClass().getClassLoader().getResourceAsStream(
+                FILENAME);
+        assertNotNull(in);
+        in.close();
+    }
+
+    /*
+    * Regression test for HARMONY-2644:
+    * Load system and non-system array classes via Class.forName()
+    */
+    public void test_forName_arrays() throws Exception {
+        Class c1 = getClass();
+        String s = c1.getName();
+        Class a1 = Class.forName("[L" + s + ";");
+        Class a2 = Class.forName("[[L" + s + ";");
+        assertSame(c1, a1.getComponentType());
+        assertSame(a1, a2.getComponentType());
+        Class l4 = Class.forName("[[[[[J");
+        assertSame(long[][][][][].class, l4);
+
+        try {
+            System.out.println(Class.forName("[;"));
+            fail("1");
+        } catch (ClassNotFoundException ok) {
+        }
+        try {
+            System.out.println(Class.forName("[["));
+            fail("2");
+        } catch (ClassNotFoundException ok) {
+        }
+        try {
+            System.out.println(Class.forName("[L"));
+            fail("3");
+        } catch (ClassNotFoundException ok) {
+        }
+        try {
+            System.out.println(Class.forName("[L;"));
+            fail("4");
+        } catch (ClassNotFoundException ok) {
+        }
+        try {
+            System.out.println(Class.forName(";"));
+            fail("5");
+        } catch (ClassNotFoundException ok) {
+        }
+        try {
+            System.out.println(Class.forName(""));
+            fail("6");
+        } catch (ClassNotFoundException ok) {
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/CloneNotSupportedExceptionTest.java b/luni/src/test/java/tests/api/java/lang/CloneNotSupportedExceptionTest.java
new file mode 100644
index 0000000..ec6a9fa
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/CloneNotSupportedExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class CloneNotSupportedExceptionTest extends TestCase {
+
+    /**
+     * java.lang.CloneNotSupportedException#CloneNotSupportedException()
+     */
+    public void test_Constructor() {
+        CloneNotSupportedException e = new CloneNotSupportedException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * 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/tests/api/java/lang/CompilerTest.java b/luni/src/test/java/tests/api/java/lang/CompilerTest.java
new file mode 100644
index 0000000..027c99b
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/CompilerTest.java
@@ -0,0 +1,65 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class CompilerTest extends TestCase {
+
+    /**
+     * java.lang.Compiler#command(java.lang.Object)
+     */
+    public void test_commandLjava_lang_Object() {
+        assertNull("Incorrect behavior.", Compiler.command(new Object()));
+    }
+
+    /**
+     * java.lang.Compiler#compileClass(java.lang.Class)
+     */
+    public void test_compileClassLjava_lang_Class() {
+        // 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);
+    }
+
+    /**
+     * java.lang.Compiler#compileClasses(java.lang.String)
+     */
+    public void test_compileClassesLjava_lang_String() {
+        // 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");
+    }
+
+    /**
+     * java.lang.Compiler#disable()
+     */
+    public void test_disable() {
+        Compiler.disable();
+        Compiler.compileClass(Compiler.class);
+    }
+
+    /**
+     * java.lang.Compiler#enable()
+     */
+    public void test_enable() {
+        Compiler.disable();
+        Compiler.enable();
+        Compiler.compileClass(Compiler.class);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/DoubleTest.java b/luni/src/test/java/tests/api/java/lang/DoubleTest.java
new file mode 100644
index 0000000..b61d345
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/DoubleTest.java
@@ -0,0 +1,1444 @@
+/* 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.lang;
+
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+public class DoubleTest extends TestCase {
+    private static final long rawBitsFor3_4en324ToN1[] = { 0x1L, 0x7L, 0x45L, 0x2b0L, 0x1ae2L,
+            0x10cd1L, 0xa8028L, 0x69018dL, 0x41a0f7eL, 0x29049aedL, 0x19a2e0d44L,
+            0x1005cc84acL, 0xa039fd2ebdL, 0x64243e3d361L, 0x3e96a6e641c6L, 0x271e284fe91b8L,
+            0x1872d931f1b131L, 0x4e8f8f7e6e1d7dL, 0x8319b9af04d26eL, 0xb7e0281ac6070aL,
+            0xedd832217788ccL, 0x122a71f54eab580L, 0x15750e72a2562e0L, 0x18d2520f4aebb98L,
+            0x1c2373498ed353fL, 0x1f6c501bf28828eL, 0x22c76422ef2a332L, 0x261c9e95d57a5ffL,
+            0x2963c63b4ad8f7fL, 0x2cbcb7ca1d8f35fL, 0x3015f2de527981bL, 0x335b6f95e717e22L,
+            0x36b24b7b60dddabL, 0x3a0f6f2d1c8aa8bL, 0x3d534af863ad52dL, 0x40a81db67c98a79L,
+            0x440912920ddf68bL, 0x474b5736915742eL, 0x4a9e2d0435ad13aL, 0x4e02dc22a18c2c4L,
+            0x5143932b49ef375L, 0x549477f61c6b052L, 0x57f995f3a385c67L, 0x5b3bfdb846339c0L,
+            0x5e8afd2657c0830L, 0x61edbc6fedb0a3dL, 0x653495c5f48e666L, 0x6881bb3771b1fffL,
+            0x6be22a054e1e7ffL, 0x6f2d5a4350d30ffL, 0x7278b0d42507d3fL, 0x75d6dd092e49c8fL,
+            0x79264a25bcee1daL, 0x7c6fdcaf2c29a50L, 0x7fcbd3daf7340e4L, 0x831f6468da8088eL,
+            0x86673d831120ab2L, 0x89c10ce3d568d5fL, 0x8d18a80e656185bL, 0x905ed211feb9e72L,
+            0x93b686967e6860eL, 0x9712141e0f013c9L, 0x9a56992592c18bbL, 0x9dac3f6ef771eeaL,
+            0xa10ba7a55aa7352L, 0xa44e918eb151027L, 0xa7a235f25da5430L, 0xab0561b77a8749eL,
+            0xae46ba2559291c6L, 0xb19868aeaf73637L, 0xb4fe82da5b503c5L, 0xb83f11c8791225bL,
+            0xbb8ed63a9756af2L, 0xbef28bc93d2c5afL, 0xc237975dc63bb8dL, 0xc5857d3537caa70L,
+            0xc8e6dc8285bd50cL, 0xcc3049d19396528L, 0xcf7c5c45f87be72L, 0xd2db7357769ae0eL,
+            0xd6292816aa20cc9L, 0xd973721c54a8ffbL, 0xdcd04ea369d33faL, 0xe0223126222407cL,
+            0xe36abd6faaad09bL, 0xe6c56ccb95584c2L, 0xea1b63ff3d572f9L, 0xed623cff0cacfb8L,
+            0xf0bacc3ecfd83a5L, 0xf414bfa741e7247L, 0xf759ef911260ed9L, 0xfab06b7556f9290L,
+            0xfe0e4329565bb9aL, 0x10151d3f3abf2a80L, 0x104a648f096ef520L, 0x10807ed965e55934L,
+            0x10b49e8fbf5eaf81L, 0x10e9c633af365b61L, 0x11201be04d81f91dL, 0x115422d860e27764L,
+            0x11892b8e791b153dL, 0x11bf76721761da8cL, 0x11f3aa074e9d2898L, 0x12289489224472beL,
+            0x125eb9ab6ad58f6dL, 0x1293340b22c579a4L, 0x12c8010deb76d80dL, 0x12fe015166548e11L,
+            0x1332c0d2dff4d8caL, 0x1367710797f20efdL, 0x139d4d497dee92bcL, 0x13d2504deeb51bb6L,
+            0x1406e4616a6262a3L, 0x143c9d79c4fafb4cL, 0x1471e26c1b1cdd0fL, 0x14a65b0721e41453L,
+            0x14dbf1c8ea5d1968L, 0x1511771d927a2fe1L, 0x1545d4e4f718bbd9L, 0x157b4a1e34deead0L,
+            0x15b10e52e10b52c2L, 0x15e551e7994e2772L, 0x161aa6617fa1b14fL, 0x1650a7fcefc50ed1L,
+            0x1684d1fc2bb65286L, 0x16ba067b36a3e727L, 0x16f0440d02267078L, 0x1724551042b00c96L,
+            0x17596a54535c0fbcL, 0x178fc4e9683313abL, 0x17c3db11e11fec4bL, 0x17f8d1d65967e75eL,
+            0x182f064befc1e135L, 0x186363ef75d92cc1L, 0x18983ceb534f77f1L, 0x18ce4c26282355eeL,
+            0x1902ef97d91615b5L, 0x1937ab7dcf5b9b22L, 0x196d965d433281eaL, 0x19a27dfa49ff9132L,
+            0x19d71d78dc7f757fL, 0x1a0ce4d7139f52dfL, 0x1a420f066c4393cbL, 0x1a7692c8075478beL,
+            0x1aac377a092996edL, 0x1ae1a2ac45b9fe54L, 0x1b160b5757287de9L, 0x1b4b8e2d2cf29d64L,
+            0x1b8138dc3c17a25eL, 0x1bb587134b1d8af6L, 0x1beae8d81de4edb4L, 0x1c20d18712af1490L,
+            0x1c5505e8d75ad9b4L, 0x1c8a47630d319021L, 0x1cc06c9de83efa15L, 0x1cf487c5624eb89aL,
+            0x1d29a9b6bae266c1L, 0x1d600a1234cd8038L, 0x1d940c96c200e046L, 0x1dc90fbc72811858L,
+            0x1dff53ab8f215e6eL, 0x1e33944b3974db05L, 0x1e68795e07d211c6L, 0x1e9e97b589c69637L,
+            0x1ed31ed1761c1de3L, 0x1f07e685d3a3255bL, 0x1f3de027488beeb2L, 0x1f72ac188d57752fL,
+            0x1fa7571eb0ad527bL, 0x1fdd2ce65cd8a71aL, 0x20123c0ffa076870L, 0x2046cb13f889428cL,
+            0x207c7dd8f6ab932fL, 0x20b1cea79a2b3bfeL, 0x20e6425180b60afdL, 0x211bd2e5e0e38dbcL,
+            0x215163cfac8e3896L, 0x2185bcc397b1c6bbL, 0x21bb2bf47d9e386aL, 0x21f0fb78ce82e342L,
+            0x22253a5702239c13L, 0x225a88ecc2ac8317L, 0x22909593f9abd1efL, 0x22c4baf8f816c66aL,
+            0x22f9e9b7361c7805L, 0x2330321281d1cb03L, 0x23643e9722463dc4L, 0x23994e3cead7cd35L,
+            0x23cfa1cc258dc082L, 0x2403c51f97789851L, 0x2438b6677d56be65L, 0x246ee4015cac6dffL,
+            0x24a34e80d9ebc4bfL, 0x24d822211066b5efL, 0x250e2aa95480636bL, 0x2542daa9d4d03e23L,
+            0x257791544a044dabL, 0x25ad75a95c856116L, 0x25e26989d9d35caeL, 0x261703ec504833d9L,
+            0x264cc4e7645a40d0L, 0x2681fb109eb86882L, 0x26b679d4c66682a2L, 0x26ec1849f800234bL,
+            0x27218f2e3b00160fL, 0x2755f2f9c9c01b93L, 0x278b6fb83c302277L, 0x27c125d3259e158bL,
+            0x27f56f47ef059aedL, 0x282acb19eac701a8L, 0x2860bef032bc6109L, 0x2894eeac3f6b794cL,
+            0x28ca2a574f46579eL, 0x29005a76918bf6c3L, 0x2934711435eef474L, 0x29698d59436ab191L,
+            0x299ff0af94455df5L, 0x29d3f66dbcab5ab9L, 0x2a08f4092bd63167L, 0x2a3f310b76cbbdc1L,
+            0x2a737ea72a3f5699L, 0x2aa85e50f4cf2c3fL, 0x2ade75e53202f74fL, 0x2b1309af3f41da91L,
+            0x2b47cc1b0f125135L, 0x2b7dbf21d2d6e583L, 0x2bb2977523c64f72L, 0x2be73d526cb7e34eL,
+            0x2c1d0ca707e5dc22L, 0x2c5227e864efa995L, 0x2c86b1e27e2b93faL, 0x2cbc5e5b1db678f9L,
+            0x2cf1baf8f2920b9cL, 0x2d2629b72f368e83L, 0x2d5bb424fb043223L, 0x2d9150971ce29f56L,
+            0x2dc5a4bce41b472bL, 0x2dfb0dec1d2218f6L, 0x2e30e8b392354f9aL, 0x2e6522e076c2a380L,
+            0x2e9a6b9894734c61L, 0x2ed0833f5cc80fbcL, 0x2f04a40f33fa13abL, 0x2f39cd1300f89896L,
+            0x2f70202be09b5f5eL, 0x2fa42836d8c23735L, 0x2fd932448ef2c503L, 0x300f7ed5b2af7643L,
+            0x3043af458fada9eaL, 0x30789b16f3991465L, 0x30aec1dcb07f597eL, 0x30e33929ee4f97efL,
+            0x3118077469e37deaL, 0x314e0951845c5d65L, 0x3182c5d2f2b9ba5fL, 0x31b77747af6828f7L,
+            0x31ed55199b423335L, 0x3222553001096001L, 0x3256ea7c014bb801L, 0x328ca51b019ea601L,
+            0x32c1e730e10327c1L, 0x32f660fd1943f1b1L, 0x332bf93c5f94ee1dL, 0x33617bc5bbbd14d2L,
+            0x3395dab72aac5a07L, 0x33cb5164f5577089L, 0x340112df1956a655L, 0x34355796dfac4febL,
+            0x346aad7c979763e5L, 0x34a0ac6ddebe9e6fL, 0x34d4d789566e460bL, 0x350a0d6bac09d78eL,
+            0x354048634b8626b9L, 0x35745a7c1e67b067L, 0x35a9711b26019c81L, 0x35dfcd61ef8203a1L,
+            0x3613e05d35b14245L, 0x3648d874831d92d6L, 0x367f0e91a3e4f78bL, 0x36b3691b066f1ab7L,
+            0x36e84361c80ae165L, 0x371e543a3a0d99beL, 0x3752f4a464488017L, 0x3787b1cd7d5aa01cL,
+            0x37bd9e40dcb14823L, 0x37f282e889eecd16L, 0x382723a2ac6a805cL, 0x385cec8b57852073L,
+            0x389213d716b33448L, 0x38c698ccdc60015aL, 0x38fc3f00137801b0L, 0x3931a7600c2b010eL,
+            0x396611380f35c151L, 0x399b9586130331a6L, 0x39d13d73cbe1ff08L, 0x3a058cd0beda7ec9L,
+            0x3a3af004ee911e7cL, 0x3a70d603151ab30dL, 0x3aa50b83da615fd1L, 0x3ada4e64d0f9b7c5L,
+            0x3b1070ff029c12dbL, 0x3b448d3ec3431792L, 0x3b79b08e7413dd76L, 0x3bb00e59088c6a6aL,
+            0x3be411ef4aaf8504L, 0x3c19166b1d5b6646L, 0x3c4f5c05e4b23fd7L, 0x3c839983aeef67e6L,
+            0x3cb87fe49aab41e0L, 0x3cee9fddc1561258L, 0x3d2323ea98d5cb77L, 0x3d57ece53f0b3e55L,
+            0x3d8de81e8ece0deaL, 0x3dc2b1131940c8b2L, 0x3df75d57df90fadfL, 0x3e2d34add7753996L,
+            0x3e6240eca6a943feL, 0x3e96d127d05394fdL, 0x3ecc8571c4687a3dL, 0x3f01d3671ac14c66L,
+            0x3f364840e1719f80L, 0x3f6bda5119ce075fL, 0x3fa16872b020c49cL, 0x3fd5c28f5c28f5c3L,
+            0x400B333333333333L };
+
+    private static final long rawBitsFor1_2e0To309[] = { 0x3ff3333333333333L, 0x4028000000000000L,
+            0x405e000000000000L, 0x4092c00000000000L, 0x40c7700000000000L, 0x40fd4c0000000000L,
+            0x41324f8000000000L, 0x4166e36000000000L, 0x419c9c3800000000L, 0x41d1e1a300000000L,
+            0x42065a0bc0000000L, 0x423bf08eb0000000L, 0x427176592e000000L, 0x42a5d3ef79800000L,
+            0x42db48eb57e00000L, 0x43110d9316ec0000L, 0x434550f7dca70000L, 0x437aa535d3d0c000L,
+            0x43b0a741a4627800L, 0x43e4d1120d7b1600L, 0x441a055690d9db80L, 0x445043561a882930L,
+            0x4484542ba12a337cL, 0x44b969368974c05bL, 0x44efc3842bd1f072L, 0x4523da329b633647L,
+            0x4558d0bf423c03d9L, 0x458f04ef12cb04cfL, 0x45c363156bbee301L, 0x45f83bdac6ae9bc2L,
+            0x462e4ad1785a42b2L, 0x4662eec2eb3869afL, 0x4697aa73a606841bL, 0x46cd95108f882522L,
+            0x47027d2a59b51735L, 0x47371c74f0225d03L, 0x476ce3922c2af443L, 0x47a20e3b5b9ad8aaL,
+            0x47d691ca32818ed5L, 0x480c363cbf21f28aL, 0x4841a1e5f7753796L, 0x48760a5f7552857cL,
+            0x48ab8cf752a726daL, 0x48e1381a93a87849L, 0x491586213892965bL, 0x494ae7a986b73bf1L,
+            0x4980d0c9f4328577L, 0x49b504fc713f26d5L, 0x49ea463b8d8ef08aL, 0x4a206be538795656L,
+            0x4a5486de8697abecL, 0x4a89a896283d96e6L, 0x4ac0095dd9267e50L, 0x4af40bb54f701de4L,
+            0x4b290ea2a34c255dL, 0x4b5f524b4c1f2eb4L, 0x4b93936f0f937d31L, 0x4bc8784ad3785c7dL,
+            0x4bfe965d8856739cL, 0x4c331dfa75360842L, 0x4c67e57912838a52L, 0x4c9dded757246ce6L,
+            0x4cd2ab469676c410L, 0x4d0756183c147514L, 0x4d3d2b9e4b199259L, 0x4d723b42eeeffb78L,
+            0x4da6ca13aaabfa56L, 0x4ddc7c989556f8ebL, 0x4e11cddf5d565b93L, 0x4e46415734abf278L,
+            0x4e7bd1ad01d6ef15L, 0x4eb1630c2126556dL, 0x4ee5bbcf296feac9L, 0x4f1b2ac2f3cbe57bL,
+            0x4f50fab9d85f6f6dL, 0x4f8539684e774b48L, 0x4fba87c262151e1aL, 0x4ff094d97d4d32d0L,
+            0x5024ba0fdca07f84L, 0x5059e893d3c89f65L, 0x5090315c645d639fL, 0x50c43db37d74bc87L,
+            0x50f94d205cd1eba9L, 0x512fa06874066693L, 0x5163c4414884001cL, 0x5198b5519aa50023L,
+            0x51cee2a6014e402cL, 0x52034da7c0d0e81bL, 0x52382111b1052222L, 0x526e29561d466aabL,
+            0x52a2d9d5d24c02abL, 0x52d7904b46df0355L, 0x530d745e1896c42bL, 0x534268bacf5e3a9bL,
+            0x537702e98335c941L, 0x53acc3a3e4033b92L, 0x53e1fa466e82053bL, 0x541678d80a22868aL,
+            0x544c170e0cab282cL, 0x54818e68c7eaf91cL, 0x54b5f202f9e5b763L, 0x54eb6e83b85f253bL,
+            0x55212512533b7745L, 0x55556e56e80a5516L, 0x558ac9eca20cea5cL, 0x55c0be33e5481279L,
+            0x55f4edc0de9a1718L, 0x562a293116409cdeL, 0x566059beade8620bL, 0x5694702e59627a8dL,
+            0x56c98c39efbb1931L, 0x56ffef486ba9df7dL, 0x5733f58d434a2baeL, 0x5768f2f0941cb699L,
+            0x579f2facb923e440L, 0x57d37dcbf3b66ea8L, 0x58085d3ef0a40a52L, 0x583e748eaccd0ce6L,
+            0x587308d92c002810L, 0x58a7cb0f77003214L, 0x58ddbdd354c03e99L, 0x591296a414f82720L,
+            0x59473c4d1a3630e8L, 0x597d0b6060c3bd21L, 0x59b2271c3c7a5635L, 0x59e6b0e34b98ebc2L,
+            0x5a1c5d1c1e7f26b3L, 0x5a51ba31930f7830L, 0x5a8628bdf7d3563cL, 0x5abbb2ed75c82bcaL,
+            0x5af14fd4699d1b5fL, 0x5b25a3c984046236L, 0x5b5b0cbbe5057ac4L, 0x5b90e7f56f236cbaL,
+            0x5bc521f2caec47e9L, 0x5bfa6a6f7da759e3L, 0x5c308285ae88982eL, 0x5c64a3271a2abe39L,
+            0x5c99cbf0e0b56dc8L, 0x5cd01f768c71649dL, 0x5d0427542f8dbdc4L, 0x5d3931293b712d35L,
+            0x5d6f7d738a4d7882L, 0x5da3ae6836706b51L, 0x5dd89a02440c8626L, 0x5e0ec082d50fa7afL,
+            0x5e433851c529c8ceL, 0x5e78066636743b01L, 0x5eae07ffc41149c1L, 0x5ee2c4ffda8ace19L,
+            0x5f17763fd12d819fL, 0x5f4d53cfc578e207L, 0x5f825461db6b8d44L, 0x5fb6e97a52467095L,
+            0x5feca3d8e6d80cbbL, 0x6021e667904707f5L, 0x605660017458c9f2L, 0x608bf801d16efc6eL,
+            0x60c17b0122e55dc5L, 0x60f5d9c16b9eb536L, 0x612b5031c6866284L, 0x6161121f1c13fd92L,
+            0x619556a6e318fcf7L, 0x61caac509bdf3c34L, 0x6200abb2616b85a1L, 0x6234d69ef9c66709L,
+            0x626a0c46b83800cbL, 0x62a047ac3323007fL, 0x62d459973febc09fL, 0x63096ffd0fe6b0c6L,
+            0x633fcbfc53e05cf8L, 0x6373df7db46c3a1bL, 0x63a8d75d218748a2L, 0x63df0d3469e91acaL,
+            0x64136840c231b0beL, 0x64484250f2be1ceeL, 0x647e52e52f6da42aL, 0x64b2f3cf3da4869aL,
+            0x64e7b0c30d0da840L, 0x651d9cf3d0511251L, 0x655282186232ab72L, 0x6587229e7abf564fL,
+            0x65bceb46196f2be3L, 0x65f2130bcfe57b6eL, 0x662697cec3deda49L, 0x665c3dc274d690dbL,
+            0x6691a69989061a89L, 0x66c6103feb47a12bL, 0x66fb944fe6198976L, 0x67313cb1efcff5eaL,
+            0x67658bde6bc3f364L, 0x679aeed606b4f03dL, 0x67d0d545c4311626L, 0x68050a97353d5bb0L,
+            0x683a4d3d028cb29cL, 0x687070462197efa2L, 0x68a48c57a9fdeb8aL, 0x68d9af6d947d666cL,
+            0x69100da47cce6004L, 0x6944110d9c01f805L, 0x6979155103027606L, 0x69af5aa543c31387L,
+            0x69e398a74a59ec35L, 0x6a187ed11cf06742L, 0x6a4e9e85642c8112L, 0x6a8323135e9bd0abL,
+            0x6ab7ebd83642c4d6L, 0x6aede6ce43d3760cL, 0x6b22b040ea6429c7L, 0x6b575c5124fd3439L,
+            0x6b8d33656e3c8147L, 0x6bc2401f64e5d0cdL, 0x6bf6d0273e1f4500L, 0x6c2c84310da71640L,
+            0x6c61d29ea8886de8L, 0x6c96474652aa8962L, 0x6ccbd917e7552bbaL, 0x6d0167aef0953b54L,
+            0x6d35c19aacba8a29L, 0x6d6b320157e92cb4L, 0x6da0ff40d6f1bbf0L, 0x6dd53f110cae2aedL,
+            0x6e0a8ed54fd9b5a8L, 0x6e40994551e81189L, 0x6e74bf96a66215ebL, 0x6ea9ef7c4ffa9b66L,
+            0x6ee035adb1fca120L, 0x6f1443191e7bc967L, 0x6f4953df661abbc1L, 0x6f7fa8d73fa16ab2L,
+            0x6fb3c98687c4e2afL, 0x6fe8bbe829b61b5bL, 0x701eeae23423a232L, 0x705352cd6096455fL,
+            0x70882780b8bbd6b7L, 0x70be3160e6eacc64L, 0x70f2dedc9052bfbfL, 0x71279693b4676faeL,
+            0x715d7c38a1814b9aL, 0x71926da364f0cf40L, 0x71c7090c3e2d0310L, 0x71fccb4f4db843d4L,
+            0x7231ff1190932a65L, 0x72667ed5f4b7f4feL, 0x729c1e8b71e5f23dL, 0x72d19317272fb766L,
+            0x7305f7dcf0fba540L, 0x733b75d42d3a8e90L, 0x737129a49c44991aL, 0x73a5740dc355bf60L,
+            0x73dad111342b2f39L, 0x7410c2aac09afd83L, 0x7444f35570c1bce4L, 0x747a302accf22c1dL,
+            0x74b05e1ac0175b92L, 0x74e475a1701d3277L, 0x75199309cc247f15L, 0x754ff7cc3f2d9edaL,
+            0x7583fadfa77c8348L, 0x75b8f997915ba41aL, 0x75ef37fd75b28d21L, 0x762382fe698f9834L,
+            0x765863be03f37e41L, 0x768e7cad84f05dd2L, 0x76c30dec73163aa3L, 0x76f7d1678fdbc94cL,
+            0x772dc5c173d2bb9fL, 0x77629b98e863b543L, 0x7797427f227ca294L, 0x77cd131eeb1bcb39L,
+            0x78022bf352f15f04L, 0x7836b6f027adb6c5L, 0x786c64ac31992476L, 0x78a1beeb9effb6caL,
+            0x78d62ea686bfa47cL, 0x790bba50286f8d9bL, 0x794154721945b881L, 0x7975a98e9f9726a1L,
+            0x79ab13f2477cf049L, 0x79e0ec776cae162eL, 0x7a15279547d99bb9L, 0x7a4a717a99d002a8L,
+            0x7a8086eca02201a9L, 0x7ab4a8a7c82a8213L, 0x7ae9d2d1ba352298L, 0x7b2023c31461359fL,
+            0x7b542cb3d9798307L, 0x7b8937e0cfd7e3c8L, 0x7bbf85d903cddcbaL, 0x7bf3b3a7a260a9f4L,
+            0x7c28a0918af8d472L, 0x7c5ec8b5edb7098eL, 0x7c933d71b49265f9L, 0x7cc80cce21b6ff77L,
+            0x7cfe1001aa24bf55L, 0x7d32ca010a56f795L, 0x7d677c814cecb57aL, 0x7d9d5ba1a027e2d9L,
+            0x7dd259450418edc7L, 0x7e06ef96451f2939L, 0x7e3cab7bd666f388L, 0x7e71eb2d66005835L,
+            0x7ea665f8bf806e42L, 0x7edbff76ef6089d2L, 0x7f117faa559c5623L, 0x7f45df94eb036bacL,
+            0x7f7b577a25c44697L, 0x7fb116ac579aac1fL, 0x7fe55c576d815726L, 0x7ff0000000000000L };
+
+    private void doTestCompareRawBits(String originalDoubleString, long expectedRawBits,
+            String expectedString) {
+        double result;
+        long rawBits;
+        String convertedString;
+        result = Double.parseDouble(originalDoubleString);
+        rawBits = Double.doubleToLongBits(result);
+        convertedString = new Double(result).toString();
+        assertEquals(expectedRawBits, rawBits);
+        assertEquals(expectedString.toLowerCase(Locale.US), convertedString
+                .toLowerCase(Locale.US));
+    }
+
+    private void test_toString(double dd, String answer) {
+        assertEquals(answer, Double.toString(dd));
+        Double d = new Double(dd);
+        assertEquals(answer, Double.toString(d.doubleValue()));
+        assertEquals(answer, d.toString());
+    }
+
+    /**
+     * java.lang.Double#Double(double)
+     */
+    public void test_ConstructorD() {
+        Double d = new Double(39089.88888888888888888888888888888888);
+        assertEquals("Created incorrect double", 39089.88888888888888888888888888888888, d
+                .doubleValue(), 0D);
+    }
+
+    /**
+     * java.lang.Double#Double(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        Double d = new Double("39089.88888888888888888888888888888888");
+        assertEquals("Created incorrect double", 39089.88888888888888888888888888888888, d
+                .doubleValue(), 0D);
+
+        // Regression test for HARMONY-489
+        try {
+            d = new Double("1E+-20");
+            fail("new Double(\"1E+-20\") should throw exception");
+        } catch (NumberFormatException e) {
+            // expected
+        }
+
+        // Regression test for HARMONY-329
+        d = Double.parseDouble("-1.233999999999999965116738099630936817275852021384209929081813042837802886790127428328465579708849276001782791006814286802871737087810957327493372866733334925806221045495205250590286471187577636646208155890426896101636282423463443661040209738873506655844025580428394216030152374941053494694642722606658935546875E-112");
+        assertEquals("Failed to parse long string", -1.234E-112D, d.doubleValue(), 0D);
+    }
+
+    /**
+     * java.lang.Double#byteValue()
+     */
+    public void test_byteValue() {
+        Double d = new Double(1923311.47712);
+        assertEquals("Returned incorrect byte value", (byte) -17, d.byteValue());
+    }
+
+    /**
+     * java.lang.Double#compareTo(java.lang.Double)
+     * java.lang.Double#compare(double, double)
+     */
+    public void test_compare() {
+        double[] values = 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 < values.length; i++) {
+            double d1 = values[i];
+            assertTrue("compare() should be equal: " + d1, Double.compare(d1, d1) == 0);
+            Double D1 = new Double(d1);
+            assertTrue("compareTo() should be equal: " + d1, D1.compareTo(D1) == 0);
+            for (int j = i + 1; j < values.length; j++) {
+                double d2 = values[j];
+                assertTrue("compare() " + d1 + " should be less " + d2,
+                        Double.compare(d1, d2) == -1);
+                assertTrue("compare() " + d2 + " should be greater " + d1, Double.compare(d2,
+                        d1) == 1);
+                Double D2 = new Double(d2);
+                assertTrue("compareTo() " + d1 + " should be less " + d2,
+                        D1.compareTo(D2) == -1);
+                assertTrue("compareTo() " + d2 + " should be greater " + d1,
+                        D2.compareTo(D1) == 1);
+            }
+        }
+
+        try {
+            new Double(0.0D).compareTo(null);
+            fail("No NPE");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    /**
+     * java.lang.Double#doubleToLongBits(double)
+     */
+    public void test_doubleToLongBitsD() {
+        // Test for method long java.lang.Double.doubleToLongBits(double)
+        Double d = new Double(Double.MAX_VALUE);
+        long lbits = Double.doubleToLongBits(d.doubleValue());
+        double r = Double.longBitsToDouble(lbits);
+
+        assertTrue("Bit conversion failed", d.doubleValue() == r);
+    }
+
+    /**
+     * java.lang.Double#doubleToRawLongBits(double)
+     */
+    public void test_doubleToRawLongBitsD() {
+        long l = 0x7ff80000000004d2L;
+        double d = Double.longBitsToDouble(l);
+        assertTrue("Wrong raw bits", Double.doubleToRawLongBits(d) == l);
+    }
+
+    /**
+     * java.lang.Double#doubleValue()
+     */
+    public void test_doubleValue() {
+        assertEquals("Incorrect double value returned", 999999999999999.9999999999999,
+                new Double(999999999999999.9999999999999).doubleValue(), 0D);
+    }
+
+    /**
+     * java.lang.Double#floatValue()
+     */
+    public void test_floatValue() {
+        // Test for method float java.lang.Double.floatValue()
+        assertTrue(
+                "Incorrect float value returned ",
+                Math
+                        .abs(new Double(999999999999999.9999999999999d).floatValue() - 999999999999999.9999999999999f) < 1);
+    }
+
+    /**
+     * java.lang.Double#hashCode()
+     */
+    public void test_hashCode() {
+        // Test for method int java.lang.Double.hashCode()
+        for (int i = -1000; i < 1000; i++) {
+            Double d = new Double(i);
+            Double dd = new Double(i);
+            assertTrue("Should not be identical ", d != dd);
+            assertTrue("Should be equals 1 ", d.equals(dd));
+            assertTrue("Should be equals 2 ", dd.equals(d));
+            assertTrue("Should have identical values ", dd.doubleValue() == d.doubleValue());
+            assertTrue("Invalid hash for equal but not identical doubles ", d.hashCode() == dd
+                    .hashCode());
+        }
+        assertEquals("Magic assumption hasCode (0.0) = 0 failed", 0, new Double(0.0).hashCode());
+    }
+
+    /**
+     * java.lang.Double#intValue()
+     */
+    public void test_intValue() {
+        // Test for method int java.lang.Double.intValue()
+        Double d = new Double(1923311.47712);
+        assertEquals("Returned incorrect int value", 1923311, d.intValue());
+    }
+
+    /**
+     * java.lang.Double#isInfinite()
+     */
+    public void test_isInfinite() {
+        // Test for method boolean java.lang.Double.isInfinite()
+        assertTrue("NEGATIVE_INFINITY returned false", new Double(Double.NEGATIVE_INFINITY)
+                .isInfinite());
+        assertTrue("POSITIVE_INFINITY returned false", new Double(Double.POSITIVE_INFINITY)
+                .isInfinite());
+        assertTrue("Non infinite number returned true", !(new Double(1000).isInfinite()));
+    }
+
+    /**
+     * java.lang.Double#isInfinite(double)
+     */
+    public void test_isInfiniteD() {
+        // Test for method boolean java.lang.Double.isInfinite(double)
+        assertTrue("Infinity check failed", Double.isInfinite(Double.NEGATIVE_INFINITY)
+                && (Double.isInfinite(Double.POSITIVE_INFINITY))
+                && !(Double.isInfinite(Double.MAX_VALUE)));
+    }
+
+    /**
+     * java.lang.Double#isNaN()
+     */
+    public void test_isNaN() {
+        // Test for method boolean java.lang.Double.isNaN()
+        Double d = new Double(0.0 / 0.0);
+        assertTrue("NAN returned false", d.isNaN());
+        d = new Double(0);
+        assertTrue("Non NAN returned true", !d.isNaN());
+    }
+
+    /**
+     * java.lang.Double#isNaN(double)
+     */
+    public void test_isNaND() {
+        // Test for method boolean java.lang.Double.isNaN(double)
+
+        Double d = new Double(0.0 / 0.0);
+        assertTrue("NAN check failed", Double.isNaN(d.doubleValue()));
+    }
+
+    /**
+     * java.lang.Double#longBitsToDouble(long)
+     */
+    public void test_longBitsToDoubleJ() {
+        // Test for method double java.lang.Double.longBitsToDouble(long)
+
+        Double d = new Double(Double.MAX_VALUE);
+        long lbits = Double.doubleToLongBits(d.doubleValue());
+        double r = Double.longBitsToDouble(lbits);
+
+        assertTrue("Bit conversion failed", d.doubleValue() == r);
+    }
+
+    /**
+     * java.lang.Double#longValue()
+     */
+    public void test_longValue() {
+        // Test for method long java.lang.Double.longValue()
+        Double d = new Double(1923311.47712);
+        assertEquals("Returned incorrect long value", 1923311, d.longValue());
+    }
+
+    /**
+     * java.lang.Double#parseDouble(java.lang.String)
+     */
+    public void test_parseDoubleLjava_lang_String() {
+        assertEquals("Incorrect double returned, expected zero.", 0.0, Double
+                .parseDouble("2.4703282292062327208828439643411e-324"), 0.0);
+        assertTrue("Incorrect double returned, expected minimum double.", Double
+                .parseDouble("2.4703282292062327208828439643412e-324") == Double.MIN_VALUE);
+
+        for (int i = 324; i > 0; i--) {
+            Double.parseDouble("3.4e-" + i);
+        }
+        for (int i = 0; i <= 309; i++) {
+            Double.parseDouble("1.2e" + i);
+        }
+
+        /*
+         * The first two cases and the last four cases have to placed outside
+         * the loop due to the difference in the expected output string.
+         */
+        doTestCompareRawBits("3.4e-324", rawBitsFor3_4en324ToN1[0], "4.9e-324");
+        doTestCompareRawBits("3.4e-323", rawBitsFor3_4en324ToN1[1], "3.5e-323");
+        for (int i = 322; i > 3; i--) {
+            String testString, expectedString;
+            testString = expectedString = "3.4e-" + i;
+            doTestCompareRawBits(testString, rawBitsFor3_4en324ToN1[324 - i], expectedString);
+        }
+        doTestCompareRawBits("3.4e-3", rawBitsFor3_4en324ToN1[321], "0.0034");
+        doTestCompareRawBits("3.4e-2", rawBitsFor3_4en324ToN1[322], "0.034");
+        doTestCompareRawBits("3.4e-1", rawBitsFor3_4en324ToN1[323], "0.34");
+        doTestCompareRawBits("3.4e-0", rawBitsFor3_4en324ToN1[324], "3.4");
+
+        doTestCompareRawBits("1.2e0", rawBitsFor1_2e0To309[0], "1.2");
+        doTestCompareRawBits("1.2e1", rawBitsFor1_2e0To309[1], "12.0");
+        doTestCompareRawBits("1.2e2", rawBitsFor1_2e0To309[2], "120.0");
+        doTestCompareRawBits("1.2e3", rawBitsFor1_2e0To309[3], "1200.0");
+        doTestCompareRawBits("1.2e4", rawBitsFor1_2e0To309[4], "12000.0");
+        doTestCompareRawBits("1.2e5", rawBitsFor1_2e0To309[5], "120000.0");
+        doTestCompareRawBits("1.2e6", rawBitsFor1_2e0To309[6], "1200000.0");
+        for (int i = 7; i <= 308; i++) {
+            String testString, expectedString;
+            testString = expectedString = "1.2e" + i;
+            doTestCompareRawBits(testString, rawBitsFor1_2e0To309[i], expectedString);
+        }
+        doTestCompareRawBits("1.2e309", rawBitsFor1_2e0To309[309], "Infinity");
+
+        doTestCompareRawBits(
+                "111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000.92233720368547758079223372036854775807",
+                0x7e054218c295e43fL, "1.1122233344455567E299");
+        doTestCompareRawBits(
+                "-111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000.92233720368547758079223372036854775807",
+                0xfe054218c295e43fL, "-1.1122233344455567E299");
+
+        doTestCompareRawBits("1.234123412431233E107", 0x562ae7a25fe706ebL,
+                "1.234123412431233E107");
+        doTestCompareRawBits("1.2341234124312331E107", 0x562ae7a25fe706ecL,
+                "1.2341234124312331E107");
+        doTestCompareRawBits("1.2341234124312332E107", 0x562ae7a25fe706ecL,
+                "1.2341234124312331E107");
+        doTestCompareRawBits("-1.234123412431233E107", 0xd62ae7a25fe706ebL,
+                "-1.234123412431233E107");
+        doTestCompareRawBits("-1.2341234124312331E107", 0xd62ae7a25fe706ecL,
+                "-1.2341234124312331E107");
+        doTestCompareRawBits("-1.2341234124312332E107", 0xd62ae7a25fe706ecL,
+                "-1.2341234124312331E107");
+
+        doTestCompareRawBits("1e23", 0x44b52d02c7e14af6L, "1.0e23");
+
+        /*
+         * These particular tests verify that the extreme boundary conditions
+         * are converted correctly.
+         */
+        doTestCompareRawBits("0.0e-309", 0L, "0.0");
+        doTestCompareRawBits("-0.0e-309", 0x8000000000000000L, "-0.0");
+        doTestCompareRawBits("0.0e309", 0L, "0.0");
+        doTestCompareRawBits("-0.0e309", 0x8000000000000000L, "-0.0");
+        doTestCompareRawBits("0.1e309", 0x7fe1ccf385ebc8a0L, "1.0e308");
+        doTestCompareRawBits("0.2e309", 0x7ff0000000000000L, "Infinity");
+        doTestCompareRawBits("65e-325", 1L, "4.9e-324");
+        doTestCompareRawBits("1000e-326", 2L, "1.0e-323");
+
+        doTestCompareRawBits("4.0e-306", 0x86789e3750f791L, "4.0e-306");
+        doTestCompareRawBits("2.22507e-308", 0xffffe2e8159d0L, "2.22507e-308");
+        doTestCompareRawBits(
+                "111222333444555666777888999000111228999000.92233720368547758079223372036854775807",
+                0x48746da623f1dd8bL, "1.1122233344455567E41");
+        doTestCompareRawBits(
+                "-111222333444555666777888999000111228999000.92233720368547758079223372036854775807",
+                0xc8746da623f1dd8bL, "-1.1122233344455567E41");
+        doTestCompareRawBits(
+                "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890.987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210",
+                0x54820fe0ba17f469L, "1.2345678901234567E99");
+        doTestCompareRawBits(
+                "-1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890.987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210",
+                0xd4820fe0ba17f469L, "-1.2345678901234567E99");
+
+        doTestCompareRawBits(
+                "179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.01",
+                0x7fefffffffffffffL, "1.7976931348623157E308");
+        doTestCompareRawBits(
+                "-179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.01",
+                0xffefffffffffffffL, "-1.7976931348623157E308");
+        doTestCompareRawBits(
+                "1112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001234567890",
+                0x7ff0000000000000L, "Infinity");
+        doTestCompareRawBits(
+                "-1112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001112223334445556667778889990001234567890",
+                0xfff0000000000000L, "-Infinity");
+        doTestCompareRawBits(
+                "179769313486231590000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.01",
+                0x7ff0000000000000L, "Infinity");
+        doTestCompareRawBits(
+                "-179769313486231590000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.01",
+                0xfff0000000000000L, "-Infinity");
+        doTestCompareRawBits(
+                "0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017976931348623157",
+                0x2b392a32afcc661eL, "1.7976931348623157E-100");
+        doTestCompareRawBits(
+                "-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017976931348623157",
+                0xab392a32afcc661eL, "-1.7976931348623157E-100");
+        doTestCompareRawBits(
+                "0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017976931348623157",
+                0x1b3432f0cb68e61L, "1.7976931348623157E-300");
+        doTestCompareRawBits(
+                "-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017976931348623157",
+                0x81b3432f0cb68e61L, "-1.7976931348623157E-300");
+        doTestCompareRawBits(
+                "0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017976931348623157",
+                0x2117b590b942L, "1.79769313486234E-310");
+        doTestCompareRawBits(
+                "-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017976931348623157",
+                0x80002117b590b942L, "-1.79769313486234E-310");
+        doTestCompareRawBits(
+                "0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017976931348623157",
+                0xe37L, "1.798E-320");
+        doTestCompareRawBits(
+                "-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017976931348623157",
+                0x8000000000000e37L, "-1.798E-320");
+        doTestCompareRawBits(
+                "0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+                0x2L, "1.0E-323");
+        doTestCompareRawBits(
+                "-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+                0x8000000000000002L, "-1.0E-323");
+        doTestCompareRawBits(
+                "0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055595409854908458349204328908234982349050934129878452378432452458968024357823490509341298784523784324524589680243578234905093412987845237843245245896802435782349050934129878452378432452458968024357868024357823490509341298784523784324524589680243578234905093412987845237843245245896802435786802435782349050934129878452378432452458968024357823490509341298784523784324524589680243578",
+                0x1L, "4.9E-324");
+        doTestCompareRawBits(
+                "-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055595409854908458349204328908234982349050934129878452378432452458968024357823490509341298784523784324524589680243578234905093412987845237843245245896802435782349050934129878452378432452458968024357868024357823490509341298784523784324524589680243578234905093412987845237843245245896802435786802435782349050934129878452378432452458968024357823490509341298784523784324524589680243578",
+                0x8000000000000001L, "-4.9E-324");
+    }
+
+    /**
+     * java.lang.Double#parseDouble(java.lang.String)
+     */
+    public void test_parseDouble_LString_Illegal() {
+        try {
+            Double.parseDouble("0.0p0D");
+            fail("Should throw NumberFormatException.");
+        } catch (NumberFormatException e) {
+            // expected
+        }
+
+        try {
+            Double.parseDouble("+0x.p1d");
+            fail("Should throw NumberFormatException.");
+        } catch (NumberFormatException e) {
+            // expected
+        }
+
+        try {
+            Double.parseDouble("0Xg.gp1D");
+            fail("Should throw NumberFormatException.");
+        } catch (NumberFormatException e) {
+            // expected
+        }
+
+        try {
+            Double.parseDouble("-0x1.1p");
+            fail("Should throw NumberFormatException.");
+        } catch (NumberFormatException e) {
+            // expected
+        }
+
+        try {
+            Double.parseDouble("+0x 1.1 p2d");
+            fail("Should throw NumberFormatException.");
+        } catch (NumberFormatException e) {
+            // expected
+        }
+
+        try {
+            Double.parseDouble("x1.1p2d");
+            fail("Should throw NumberFormatException.");
+        } catch (NumberFormatException e) {
+            // expected
+        }
+
+        try {
+            Double.parseDouble(" 0x-2.1p2");
+            fail("Should throw NumberFormatException.");
+        } catch (NumberFormatException e) {
+            // expected
+        }
+
+        try {
+            Double.parseDouble(" 0x2.1pad");
+            fail("Should throw NumberFormatException.");
+        } catch (NumberFormatException e) {
+            // expected
+        }
+
+        try {
+            Double.parseDouble(" 0x111.222p 22d");
+            fail("Should throw NumberFormatException.");
+        } catch (NumberFormatException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.lang.Double#parseDouble(java.lang.String)
+     */
+    public void test_parseDouble_LString_FromHexString() {
+        double actual;
+        double expected;
+
+        actual = Double.parseDouble("0x0.0p0D");
+        assertEquals("Returned incorrect value", 0.0d, actual, 0.0D);
+
+        actual = Double.parseDouble("0xa.ap+9d");
+        assertEquals("Returned incorrect value", 5440.0d, actual, 0.0D);
+
+        actual = Double.parseDouble("+0Xb.10ap8");
+        assertEquals("Returned incorrect value", 2832.625d, actual, 0.0D);
+
+        actual = Double.parseDouble("-0X.a0P2D");
+        assertEquals("Returned incorrect value", -2.5d, actual, 0.0D);
+
+        actual = Double.parseDouble("\r 0x22.1p2d \t");
+        assertEquals("Returned incorrect value", 136.25d, actual, 0.0D);
+
+        actual = Double.parseDouble("0x1.0p-1");
+        assertEquals("Returned incorrect value", 0.5, actual, 0.0D);
+
+        actual = Double
+                .parseDouble("0x00000000000000000000000000000000001.0p-1");
+        assertEquals("Returned incorrect value", 0.5, actual, 0.0D);
+
+        actual = Double.parseDouble("0x1.0p-00000000000000000000000000001");
+        assertEquals("Returned incorrect value", 0.5, actual, 0.0D);
+
+        actual = Double.parseDouble("0x.100000000000000000000000000000000p1");
+        assertEquals("Returned incorrect value", 0.125, actual, 0.0D);
+
+        actual = Double.parseDouble("0x0.0p999999999999999999999999999999999999999999999999999999999999999");
+        assertEquals("Returned incorrect value", 0.0, actual, 0.0D);
+
+        actual = Double.parseDouble("0xf1.0p9999999999999999999999999999999999999999999999999999999999999999");
+        assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY, actual, 0.0D);
+
+        actual = Double.parseDouble("0xffffffffffffffffffffffffffffffffffff.ffffffffffffffffffffffffffffffffffffffffffffffp1");
+        expected = Double.longBitsToDouble(0x4900000000000000L);
+        assertEquals("Returned incorrect value", expected, actual, 0.0D);
+
+        actual = Double.parseDouble("0x0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001p1600");
+        expected = Double.longBitsToDouble(0x7f30000000000000L);
+        assertEquals("Returned incorrect value", expected, actual, 0.0D);
+
+        actual = Double.parseDouble("0x0.0p-999999999999999999999999999999999999999999999999999999");
+        assertEquals("Returned incorrect value", 0.0, actual, 0.0D);
+
+        actual = Double.parseDouble("0xf1.0p-9999999999999999999999999999999999999999999999999999999999999999");
+        assertEquals("Returned incorrect value", 0.0, actual, 0.0D);
+
+        actual = Double.parseDouble("0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000p-1600");
+        expected = Double.longBitsToDouble(0xf0000000000000L);
+        assertEquals("Returned incorrect value", expected, actual, 0.0D);
+
+        actual = Double.parseDouble("0x1.p9223372036854775807");
+        assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY, actual, 0.0D);
+
+        actual = Double.parseDouble("0x1.p9223372036854775808");
+        assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY, actual, 0.0D);
+
+        actual = Double.parseDouble("0x10.p9223372036854775808");
+        assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY, actual, 0.0D);
+
+        actual = Double.parseDouble("0xabcd.ffffffffp+2000");
+        assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY, actual, 0.0D);
+
+        actual = Double.parseDouble("0x1.p-9223372036854775808");
+        assertEquals("Returned incorrect value", 0.0, actual, 0.0D);
+
+        actual = Double.parseDouble("0x1.p-9223372036854775809");
+        assertEquals("Returned incorrect value", 0.0, actual, 0.0D);
+
+        actual = Double.parseDouble("0x.1p-9223372036854775809");
+        assertEquals("Returned incorrect value", 0.0, actual, 0.0D);
+
+        actual = Double.parseDouble("0xabcd.ffffffffffffffp-2000");
+        assertEquals("Returned incorrect value", 0.0, actual, 0.0D);
+    }
+
+    /**
+     * java.lang.Double#parseDouble(java.lang.String)
+     */
+    public void test_parseDouble_LString_NormalPositiveExponent() {
+        long[] expecteds = {
+                0x3f323456789abcdfL, 0x40e111012345678aL, 0x41a1110091a2b3c5L,
+                0x4259998091a2b3c5L, 0x4311110048d159e2L, 0x43c5554048d159e2L,
+                0x4479998048d159e2L, 0x452dddc048d159e2L, 0x45e111002468acf1L,
+                0x469333202468acf1L, 0x4751011001234568L, 0x4802112101234568L,
+                0x48b3213201234568L, 0x4964314301234568L, 0x4a15415401234568L,
+                0x4ac6516501234568L, 0x4b77617601234568L, 0x4c28718701234568L,
+                0x4cd9819801234568L, 0x4d9049048091a2b4L, 0x4e4101100091a2b4L,
+                0x4ef189188091a2b4L, 0x4fa211210091a2b4L, 0x505299298091a2b4L,
+                0x510321320091a2b4L, 0x51b3a93a8091a2b4L, 0x526431430091a2b4L,
+                0x5314b94b8091a2b4L, 0x53c841840091a2b4L, 0x5478c98c8091a2b4L,
+                0x552981980091a2b4L, 0x55da09a08091a2b4L, 0x568a91a90091a2b4L,
+                0x573b19b18091a2b4L, 0x57eba1ba0091a2b4L, 0x589c29c28091a2b4L,
+                0x594cb1cb0091a2b4L, 0x5a001d01c048d15aL, 0x5ab061060048d15aL,
+                0x5b60a50a4048d15aL, 0x5c1101100048d15aL, 0x5cc145144048d15aL,
+                0x5d7189188048d15aL, 0x5e21cd1cc048d15aL, 0x5ed211210048d15aL,
+                0x5f8255254048d15aL, 0x603419418048d15aL, 0x60e45d45c048d15aL,
+                0x6194a14a0048d15aL, 0x6244e54e4048d15aL, 0x62f541540048d15aL,
+                0x63a585584048d15aL, 0x6455c95c8048d15aL, 0x65060d60c048d15aL,
+                0x65b651650048d15aL, 0x666815814048d15aL, 0x671859858048d15aL,
+                0x67c89d89c048d15aL, 0x6878e18e0048d15aL, 0x692925924048d15aL,
+                0x69d981980048d15aL, 0x6a89c59c4048d15aL, 0x6b3a09a08048d15aL,
+                0x6bea4da4c048d15aL, 0x6c9c11c10048d15aL, 0x6d4c55c54048d15aL,
+                0x6dfc99c98048d15aL, 0x6eacddcdc048d15aL, 0x6f5d21d20048d15aL,
+                0x700d65d64048d15aL, 0x70bdc1dc0048d15aL, 0x716e05e04048d15aL,
+                0x721e49e48048d15aL, 0x72d00700602468adL, 0x73802902802468adL,
+                0x74304b04a02468adL, 0x74e06d06c02468adL, 0x75908f08e02468adL,
+                0x7640b10b002468adL, 0x76f0d30d202468adL, 0x77a10110002468adL,
+                0x78512312202468adL, 0x79020520402468adL, 0x79b22722602468adL,
+                0x7a624924802468adL, 0x7b126b26a02468adL, 0x7bc28d28c02468adL,
+                0x7c72af2ae02468adL, 0x7d22d12d002468adL, 0x7dd2f32f202468adL,
+                0x7e832132002468adL, 0x7f40011001012345L, 0x7ff0000000000000L,
+                0x7ff0000000000000L, 0x7ff0000000000000L, 0x7ff0000000000000L,
+                0x7ff0000000000000L, 0x7ff0000000000000L, 0x7ff0000000000000L,
+                0x7ff0000000000000L, 0x7ff0000000000000L, 0x7ff0000000000000L,
+                0x7ff0000000000000L, 0x7ff0000000000000L, 0x7ff0000000000000L,
+                0x7ff0000000000000L, 0x7ff0000000000000L, 0x7ff0000000000000L,
+                0x7ff0000000000000L, 0x7ff0000000000000L, 0x7ff0000000000000L,
+                0x7ff0000000000000L, 0x7ff0000000000000L };
+
+        for (int i = 0; i < expecteds.length; i++) {
+            int part = i * 11;
+            String inputString = "0x" + part + "." + part + "0123456789abcdefp" + part;
+
+            double actual = Double.parseDouble(inputString);
+            double expected = Double.longBitsToDouble(expecteds[i]);
+
+            String expectedString = "0x" + Long.toHexString(Double.doubleToLongBits(expected));
+            String actualString = "0x" + Long.toHexString(Double.doubleToLongBits(actual));
+            String errorMsg = i + "th input string is:<" + inputString
+                    + ">.The expected result should be:<" + expectedString
+                    + ">, but was: <" + actualString + ">. ";
+
+            assertEquals(errorMsg, expected, actual, 0.0D);
+        }
+    }
+
+    /**
+     * java.lang.Double#parseDouble(java.lang.String)
+     */
+    public void test_parseDouble_LString_NormalNegativeExponent() {
+        long[] expecteds = {
+                0x3f323456789abcdfL, 0x3f8111012345678aL, 0x3ee1110091a2b3c5L,
+                0x3e39998091a2b3c5L, 0x3d91110048d159e2L, 0x3ce5554048d159e2L,
+                0x3c39998048d159e2L, 0x3b8dddc048d159e2L, 0x3ae111002468acf1L,
+                0x3a3333202468acf1L, 0x3991011001234568L, 0x38e2112101234568L,
+                0x3833213201234568L, 0x3784314301234568L, 0x36d5415401234568L,
+                0x3626516501234568L, 0x3577617601234568L, 0x34c8718701234568L,
+                0x3419819801234568L, 0x337049048091a2b4L, 0x32c101100091a2b4L,
+                0x321189188091a2b4L, 0x316211210091a2b4L, 0x30b299298091a2b4L,
+                0x300321320091a2b4L, 0x2f53a93a8091a2b4L, 0x2ea431430091a2b4L,
+                0x2df4b94b8091a2b4L, 0x2d4841840091a2b4L, 0x2c98c98c8091a2b4L,
+                0x2be981980091a2b4L, 0x2b3a09a08091a2b4L, 0x2a8a91a90091a2b4L,
+                0x29db19b18091a2b4L, 0x292ba1ba0091a2b4L, 0x287c29c28091a2b4L,
+                0x27ccb1cb0091a2b4L, 0x27201d01c048d15aL, 0x267061060048d15aL,
+                0x25c0a50a4048d15aL, 0x251101100048d15aL, 0x246145144048d15aL,
+                0x23b189188048d15aL, 0x2301cd1cc048d15aL, 0x225211210048d15aL,
+                0x21a255254048d15aL, 0x20f419418048d15aL, 0x20445d45c048d15aL,
+                0x1f94a14a0048d15aL, 0x1ee4e54e4048d15aL, 0x1e3541540048d15aL,
+                0x1d8585584048d15aL, 0x1cd5c95c8048d15aL, 0x1c260d60c048d15aL,
+                0x1b7651650048d15aL, 0x1ac815814048d15aL, 0x1a1859858048d15aL,
+                0x19689d89c048d15aL, 0x18b8e18e0048d15aL, 0x180925924048d15aL,
+                0x175981980048d15aL, 0x16a9c59c4048d15aL, 0x15fa09a08048d15aL,
+                0x154a4da4c048d15aL, 0x149c11c10048d15aL, 0x13ec55c54048d15aL,
+                0x133c99c98048d15aL, 0x128cddcdc048d15aL, 0x11dd21d20048d15aL,
+                0x112d65d64048d15aL, 0x107dc1dc0048d15aL, 0xfce05e04048d15aL,
+                0xf1e49e48048d15aL, 0xe700700602468adL, 0xdc02902802468adL,
+                0xd104b04a02468adL, 0xc606d06c02468adL, 0xbb08f08e02468adL,
+                0xb00b10b002468adL, 0xa50d30d202468adL, 0x9a10110002468adL,
+                0x8f12312202468adL, 0x8420520402468adL, 0x7922722602468adL,
+                0x6e24924802468adL, 0x6326b26a02468adL, 0x5828d28c02468adL,
+                0x4d2af2ae02468adL, 0x422d12d002468adL, 0x372f32f202468adL,
+                0x2c32132002468adL, 0x220011001012345L, 0x170121012012345L,
+                0xc0231023012345L, 0x10341034012345L, 0x208a208a024L,
+                0x41584158L, 0x83388L, 0x108L,
+                0x0L, 0x0L, 0x0L,
+                0x0L, 0x0L, 0x0L,
+                0x0L, 0x0L, 0x0L,
+                0x0L, 0x0L, 0x0L,
+                0x0L, 0x0L };
+
+        for (int i = 0; i < expecteds.length; i++) {
+            int part = i * 11;
+            String inputString = "0x" + part + "." + part + "0123456789abcdefp-" + part;
+
+            double actual = Double.parseDouble(inputString);
+            double expected = Double.longBitsToDouble(expecteds[i]);
+
+            String expectedString = "0x" + Long.toHexString(Double.doubleToLongBits(expected));
+            String actualString = "0x" + Long.toHexString(Double.doubleToLongBits(actual));
+            String errorMsg = i + "th input string is:<" + inputString
+                    + ">.The expected result should be:<" + expectedString
+                    + ">, but was: <" + actualString + ">. ";
+
+            assertEquals(errorMsg, expected, actual, 0.0D);
+        }
+    }
+
+    /**
+     * java.lang.Double#parseDouble(java.lang.String)
+     */
+    public void test_parseDouble_LString_MaxNormalBoundary() {
+        long[] expecteds = {
+                0x7fefffffffffffffL, 0x7fefffffffffffffL, 0x7fefffffffffffffL,
+                0x7fefffffffffffffL, 0x7fefffffffffffffL, 0x7fefffffffffffffL,
+                0x7fefffffffffffffL, 0x7ff0000000000000L, 0x7ff0000000000000L,
+                0x7ff0000000000000L, 0x7ff0000000000000L, 0x7ff0000000000000L,
+                0x7ff0000000000000L, 0x7ff0000000000000L, 0x7ff0000000000000L,
+
+                0xffefffffffffffffL, 0xffefffffffffffffL, 0xffefffffffffffffL,
+                0xffefffffffffffffL, 0xffefffffffffffffL, 0xffefffffffffffffL,
+                0xffefffffffffffffL, 0xfff0000000000000L, 0xfff0000000000000L,
+                0xfff0000000000000L, 0xfff0000000000000L, 0xfff0000000000000L,
+                0xfff0000000000000L, 0xfff0000000000000L, 0xfff0000000000000L };
+
+        String[] inputs = {
+                "0x1.fffffffffffffp1023",
+                "0x1.fffffffffffff000000000000000000000000001p1023",
+                "0x1.fffffffffffff1p1023",
+                "0x1.fffffffffffff100000000000000000000000001p1023",
+                "0x1.fffffffffffff1fffffffffffffffffffffffffffffffffffffffffffffp1023",
+                "0x1.fffffffffffff7p1023",
+                "0x1.fffffffffffff700000000000000000000000001p1023",
+                "0x1.fffffffffffff8p1023",
+                "0x1.fffffffffffff800000000000000000000000001p1023",
+                "0x1.fffffffffffff8fffffffffffffffffffffffffffffffffffffffffffffp1023",
+                "0x1.fffffffffffff9p1023",
+                "0x1.fffffffffffff900000000000000000000000001p1023",
+                "0x1.ffffffffffffffp1023",
+                "0x1.ffffffffffffff00000000000000000000000001p1023",
+                "0x1.fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp1023",
+
+                "-0x1.fffffffffffffp1023",
+                "-0x1.fffffffffffff000000000000000000000000001p1023",
+                "-0x1.fffffffffffff1p1023",
+                "-0x1.fffffffffffff100000000000000000000000001p1023",
+                "-0x1.fffffffffffff1fffffffffffffffffffffffffffffffffffffffffffffp1023",
+                "-0x1.fffffffffffff7p1023",
+                "-0x1.fffffffffffff700000000000000000000000001p1023",
+                "-0x1.fffffffffffff8p1023",
+                "-0x1.fffffffffffff800000000000000000000000001p1023",
+                "-0x1.fffffffffffff8fffffffffffffffffffffffffffffffffffffffffffffp1023",
+                "-0x1.fffffffffffff9p1023",
+                "-0x1.fffffffffffff900000000000000000000000001p1023",
+                "-0x1.ffffffffffffffp1023",
+                "-0x1.ffffffffffffff00000000000000000000000001p1023",
+                "-0x1.fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp1023" };
+
+        for (int i = 0; i < inputs.length; i++) {
+            double actual = Double.parseDouble(inputs[i]);
+            double expected = Double.longBitsToDouble(expecteds[i]);
+
+            String expectedString = "0x" + Long.toHexString(Double.doubleToLongBits(expected));
+            String actualString = "0x" + Long.toHexString(Double.doubleToLongBits(actual));
+            String errorMsg = i + "th input string is:<" + inputs[i]
+                    + ">.The expected result should be:<" + expectedString
+                    + ">, but was: <" + actualString + ">. ";
+
+            assertEquals(errorMsg, expected, actual, 0.0D);
+        }
+    }
+
+    /**
+     * java.lang.Double#parseDouble(java.lang.String)
+     */
+    public void test_parseDouble_LString_MinNormalBoundary() {
+        long[] expecteds = {
+                0x10000000000000L, 0x10000000000000L, 0x10000000000000L,
+                0x10000000000000L, 0x10000000000000L, 0x10000000000000L,
+                0x10000000000000L, 0x10000000000000L, 0x10000000000001L,
+                0x10000000000001L, 0x10000000000001L, 0x10000000000001L,
+                0x10000000000001L, 0x10000000000001L, 0x10000000000001L,
+
+                0x8010000000000000L, 0x8010000000000000L, 0x8010000000000000L,
+                0x8010000000000000L, 0x8010000000000000L, 0x8010000000000000L,
+                0x8010000000000000L, 0x8010000000000000L, 0x8010000000000001L,
+                0x8010000000000001L, 0x8010000000000001L, 0x8010000000000001L,
+                0x8010000000000001L, 0x8010000000000001L, 0x8010000000000001L };
+
+        String[] inputs = {
+                "0x1.0p-1022",
+                "0x1.00000000000001p-1022",
+                "0x1.000000000000010000000000000000001p-1022",
+                "0x1.00000000000001fffffffffffffffffffffffffffffffffp-1022",
+                "0x1.00000000000007p-1022",
+                "0x1.000000000000070000000000000000001p-1022",
+                "0x1.00000000000007fffffffffffffffffffffffffffffffffp-1022",
+                "0x1.00000000000008p-1022",
+                "0x1.000000000000080000000000000000001p-1022",
+                "0x1.00000000000008fffffffffffffffffffffffffffffffffp-1022",
+                "0x1.00000000000009p-1022",
+                "0x1.000000000000090000000000000000001p-1022",
+                "0x1.00000000000009fffffffffffffffffffffffffffffffffp-1022",
+                "0x1.0000000000000fp-1022",
+                "0x1.0000000000000ffffffffffffffffffffffffffffffffffp-1022",
+
+                "-0x1.0p-1022",
+                "-0x1.00000000000001p-1022",
+                "-0x1.000000000000010000000000000000001p-1022",
+                "-0x1.00000000000001fffffffffffffffffffffffffffffffffp-1022",
+                "-0x1.00000000000007p-1022",
+                "-0x1.000000000000070000000000000000001p-1022",
+                "-0x1.00000000000007fffffffffffffffffffffffffffffffffp-1022",
+                "-0x1.00000000000008p-1022",
+                "-0x1.000000000000080000000000000000001p-1022",
+                "-0x1.00000000000008fffffffffffffffffffffffffffffffffp-1022",
+                "-0x1.00000000000009p-1022",
+                "-0x1.000000000000090000000000000000001p-1022",
+                "-0x1.00000000000009fffffffffffffffffffffffffffffffffp-1022",
+                "-0x1.0000000000000fp-1022",
+                "-0x1.0000000000000ffffffffffffffffffffffffffffffffffp-1022" };
+
+        for (int i = 0; i < inputs.length; i++) {
+            double actual = Double.parseDouble(inputs[i]);
+            double expected = Double.longBitsToDouble(expecteds[i]);
+
+            String expectedString = "0x" + Long.toHexString(Double.doubleToLongBits(expected));
+            String actualString = "0x" + Long.toHexString(Double.doubleToLongBits(actual));
+            String errorMsg = i + "th input string is:<" + inputs[i]
+                    + ">.The expected result should be:<" + expectedString
+                    + ">, but was: <" + actualString + ">. ";
+
+            assertEquals(errorMsg, expected, actual, 0.0D);
+        }
+    }
+
+    /**
+     * java.lang.Double#parseDouble(java.lang.String)
+     */
+    public void test_parseDouble_LString_MaxSubNormalBoundary() {
+        long[] expecteds = {
+                0xfffffffffffffL, 0xfffffffffffffL, 0xfffffffffffffL,
+                0xfffffffffffffL, 0xfffffffffffffL, 0xfffffffffffffL,
+                0xfffffffffffffL, 0x10000000000000L, 0x10000000000000L,
+                0x10000000000000L, 0x10000000000000L, 0x10000000000000L,
+                0x10000000000000L, 0x10000000000000L, 0x10000000000000L,
+
+                0x800fffffffffffffL, 0x800fffffffffffffL, 0x800fffffffffffffL,
+                0x800fffffffffffffL, 0x800fffffffffffffL, 0x800fffffffffffffL,
+                0x800fffffffffffffL, 0x8010000000000000L, 0x8010000000000000L,
+                0x8010000000000000L, 0x8010000000000000L, 0x8010000000000000L,
+                0x8010000000000000L, 0x8010000000000000L, 0x8010000000000000L };
+
+        String[] inputs = {
+                "0x0.fffffffffffffp-1022",
+                "0x0.fffffffffffff00000000000000000000000000000000001p-1022",
+                "0x0.fffffffffffff1p-1022",
+                "0x0.fffffffffffff10000000000000000000000000000000001p-1022",
+                "0x0.fffffffffffff1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-1022",
+                "0x0.fffffffffffff7p-1022",
+                "0x0.fffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-1022",
+                "0x0.fffffffffffff8p-1022",
+                "0x0.fffffffffffff80000000000000000000000000000000001p-1022",
+                "0x0.fffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-1022",
+                "0x0.fffffffffffff9p-1022",
+                "0x0.fffffffffffff9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-1022",
+                "0x0.ffffffffffffffp-1022",
+                "0x0.ffffffffffffff0000000000000000000000000000000001p-1022",
+                "0x0.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-1022",
+
+                "-0x0.fffffffffffffp-1022",
+                "-0x0.fffffffffffff00000000000000000000000000000000001p-1022",
+                "-0x0.fffffffffffff1p-1022",
+                "-0x0.fffffffffffff10000000000000000000000000000000001p-1022",
+                "-0x0.fffffffffffff1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-1022",
+                "-0x0.fffffffffffff7p-1022",
+                "-0x0.fffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-1022",
+                "-0x0.fffffffffffff8p-1022",
+                "-0x0.fffffffffffff80000000000000000000000000000000001p-1022",
+                "-0x0.fffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-1022",
+                "-0x0.fffffffffffff9p-1022",
+                "-0x0.fffffffffffff9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-1022",
+                "-0x0.ffffffffffffffp-1022",
+                "-0x0.ffffffffffffff0000000000000000000000000000000001p-1022",
+                "-0x0.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-1022" };
+
+        for (int i = 0; i < inputs.length; i++) {
+            double actual = Double.parseDouble(inputs[i]);
+            double expected = Double.longBitsToDouble(expecteds[i]);
+
+            String expectedString = "0x" + Long.toHexString(Double.doubleToLongBits(expected));
+            String actualString = "0x" + Long.toHexString(Double.doubleToLongBits(actual));
+            String errorMsg = i + "th input string is:<" + inputs[i]
+                    + ">.The expected result should be:<" + expectedString
+                    + ">, but was: <" + actualString + ">. ";
+
+            assertEquals(errorMsg, expected, actual, 0.0D);
+        }
+    }
+
+    /**
+     * java.lang.Double#parseDouble(java.lang.String)
+     */
+    public void test_parseDouble_LString_MinSubNormalBoundary() {
+        long[] expecteds = {
+                0x1L, 0x1L, 0x2L,
+                0x1L, 0x1L, 0x1L,
+                0x2L, 0x2L, 0x2L,
+                0x2L, 0x2L, 0x2L,
+                0x2L, 0x2L, 0x2L,
+
+                0x8000000000000001L, 0x8000000000000001L, 0x8000000000000002L,
+                0x8000000000000001L, 0x8000000000000001L, 0x8000000000000001L,
+                0x8000000000000002L, 0x8000000000000002L, 0x8000000000000002L,
+                0x8000000000000002L, 0x8000000000000002L, 0x8000000000000002L,
+                0x8000000000000002L, 0x8000000000000002L, 0x8000000000000002L };
+
+        String[] inputs = {
+                "0x0.0000000000001p-1022",
+                "0x0.00000000000010000000000000000001p-1022",
+                "0x0.0000000000001fffffffffffffffffffffffffffffffffp-1022",
+                "0x0.00000000000017p-1022",
+                "0x0.000000000000170000000000000000001p-1022",
+                "0x0.00000000000017fffffffffffffffffffffffffffffffffp-1022",
+                "0x0.00000000000018p-1022",
+                "0x0.000000000000180000000000000000001p-1022",
+                "0x0.00000000000018fffffffffffffffffffffffffffffffffp-1022",
+                "0x0.00000000000019p-1022",
+                "0x0.000000000000190000000000000000001p-1022",
+                "0x0.00000000000019fffffffffffffffffffffffffffffffffp-1022",
+                "0x0.0000000000001fp-1022",
+                "0x0.0000000000001f0000000000000000001p-1022",
+                "0x0.0000000000001ffffffffffffffffffffffffffffffffffp-1022",
+
+                "-0x0.0000000000001p-1022",
+                "-0x0.00000000000010000000000000000001p-1022",
+                "-0x0.0000000000001fffffffffffffffffffffffffffffffffp-1022",
+                "-0x0.00000000000017p-1022",
+                "-0x0.000000000000170000000000000000001p-1022",
+                "-0x0.00000000000017fffffffffffffffffffffffffffffffffp-1022",
+                "-0x0.00000000000018p-1022",
+                "-0x0.000000000000180000000000000000001p-1022",
+                "-0x0.00000000000018fffffffffffffffffffffffffffffffffp-1022",
+                "-0x0.00000000000019p-1022",
+                "-0x0.000000000000190000000000000000001p-1022",
+                "-0x0.00000000000019fffffffffffffffffffffffffffffffffp-1022",
+                "-0x0.0000000000001fp-1022",
+                "-0x0.0000000000001f0000000000000000001p-1022",
+                "-0x0.0000000000001ffffffffffffffffffffffffffffffffffp-1022" };
+
+        for (int i = 0; i < inputs.length; i++) {
+            double actual = Double.parseDouble(inputs[i]);
+            double expected = Double.longBitsToDouble(expecteds[i]);
+
+            String expectedString = "0x" + Long.toHexString(Double.doubleToLongBits(expected));
+            String actualString = "0x" + Long.toHexString(Double.doubleToLongBits(actual));
+            String errorMsg = i + "th input string is:<" + inputs[i]
+                    + ">.The expected result should be:<" + expectedString
+                    + ">, but was: <" + actualString + ">. ";
+
+            assertEquals(errorMsg, expected, actual, 0.0D);
+        }
+    }
+
+    /**
+     * java.lang.Double#parseDouble(java.lang.String)
+     */
+    public void test_parseDouble_LString_ZeroBoundary() {
+        long[] expecteds = {
+                0x0L, 0x0L, 0x0L,
+                0x1L, 0x1L, 0x1L,
+                0x1L, 0x1L, 0x1L,
+                0x8000000000000000L, 0x8000000000000000L, 0x8000000000000000L,
+                0x8000000000000001L, 0x8000000000000001L, 0x8000000000000001L,
+                0x8000000000000001L, 0x8000000000000001L, 0x8000000000000001L };
+
+        String[] inputs = {
+                "0x0.00000000000004p-1022",
+                "0x0.00000000000007ffffffffffffffffffffffp-1022",
+                "0x0.00000000000008p-1022",
+                "0x0.000000000000080000000000000000001p-1022",
+                "0x0.00000000000008fffffffffffffffffffffffffffffffp-1022",
+                "0x0.00000000000009p-1022",
+                "0x0.000000000000090000000000000000001p-1022",
+                "0x0.00000000000009fffffffffffffffffffffffffffffffffp-1022",
+                "0x0.0000000000000fffffffffffffffffffffffffffffffffffp-1022",
+
+                "-0x0.00000000000004p-1022",
+                "-0x0.00000000000007ffffffffffffffffffffffp-1022",
+                "-0x0.00000000000008p-1022",
+                "-0x0.000000000000080000000000000000001p-1022",
+                "-0x0.00000000000008fffffffffffffffffffffffffffffffp-1022",
+                "-0x0.00000000000009p-1022",
+                "-0x0.000000000000090000000000000000001p-1022",
+                "-0x0.00000000000009fffffffffffffffffffffffffffffffffp-1022",
+                "-0x0.0000000000000fffffffffffffffffffffffffffffffffffp-1022" };
+
+        for (int i = 0; i < inputs.length; i++) {
+            double actual = Double.parseDouble(inputs[i]);
+            double expected = Double.longBitsToDouble(expecteds[i]);
+
+            String expectedString = "0x" + Long.toHexString(Double.doubleToLongBits(expected));
+            String actualString = "0x" + Long.toHexString(Double.doubleToLongBits(actual));
+            String errorMsg = i + "th input string is:<" + inputs[i]
+                    + ">.The expected result should be:<" + expectedString
+                    + ">, but was: <" + actualString + ">. ";
+
+            assertEquals(errorMsg, expected, actual, 0.0D);
+        }
+    }
+
+    /**
+     * java.lang.Double#shortValue()
+     */
+    public void test_shortValue() {
+        // Test for method short java.lang.Double.shortValue()
+        Double d = new Double(1923311.47712);
+        assertEquals("Returned incorrect short value", 22767, d.shortValue());
+    }
+
+    /**
+     * java.lang.Double#toString()
+     */
+    public void test_toString() {
+        // Test for method java.lang.String java.lang.Double.toString()
+        test_toString(1.7976931348623157E308, "1.7976931348623157E308");
+        test_toString(5.0E-4, "5.0E-4");
+    }
+
+    /**
+     * java.lang.Double#toString(double)
+     */
+    public void test_toStringD() {
+        // Test for method java.lang.String java.lang.Double.toString(double)
+        test_toString(1.7976931348623157E308, "1.7976931348623157E308");
+        test_toString(1.0 / 0.0, "Infinity");
+        test_toString(0.0 / 0.0, "NaN");
+        test_toString(-1.0 / 0.0, "-Infinity");
+
+        double d;
+        d = Double.longBitsToDouble(0x470fffffffffffffL);
+        test_toString(d, "2.0769187434139308E34");
+        d = Double.longBitsToDouble(0x4710000000000000L);
+        test_toString(d, "2.076918743413931E34");
+
+        d = Double.longBitsToDouble(0x470000000000000aL);
+        test_toString(d, "1.0384593717069678E34");
+        d = Double.longBitsToDouble(0x470000000000000bL);
+        test_toString(d, "1.038459371706968E34");
+
+        d = Double.longBitsToDouble(0x4700000000000017L);
+        test_toString(d, "1.0384593717069708E34");
+        d = Double.longBitsToDouble(0x4700000000000018L);
+        test_toString(d, "1.038459371706971E34");
+
+        d = Double.longBitsToDouble(0x4700000000000024L);
+        test_toString(d, "1.0384593717069738E34");
+        d = Double.longBitsToDouble(0x4700000000000025L);
+        test_toString(d, "1.038459371706974E34");
+
+        d = Double.longBitsToDouble(0x4700000000000031L);
+        test_toString(d, "1.0384593717069768E34");
+        d = Double.longBitsToDouble(0x4700000000000032L);
+        test_toString(d, "1.038459371706977E34");
+
+        d = Double.longBitsToDouble(0x470000000000003eL);
+        test_toString(d, "1.0384593717069798E34");
+        d = Double.longBitsToDouble(0x470000000000003fL);
+        test_toString(d, "1.03845937170698E34");
+
+        d = Double.longBitsToDouble(0x7e00000000000003L);
+        test_toString(d, "8.371160993642719E298");
+        d = Double.longBitsToDouble(0x7e00000000000004L);
+        test_toString(d, "8.37116099364272E298");
+
+        d = Double.longBitsToDouble(0x7e00000000000008L);
+        test_toString(d, "8.371160993642728E298");
+        d = Double.longBitsToDouble(0x7e00000000000009L);
+        test_toString(d, "8.37116099364273E298");
+
+        d = Double.longBitsToDouble(0x7e00000000000013L);
+        test_toString(d, "8.371160993642749E298");
+        d = Double.longBitsToDouble(0x7e00000000000014L);
+        test_toString(d, "8.37116099364275E298");
+
+        d = Double.longBitsToDouble(0x7e00000000000023L);
+        test_toString(d, "8.371160993642779E298");
+        d = Double.longBitsToDouble(0x7e00000000000024L);
+        test_toString(d, "8.37116099364278E298");
+
+        d = Double.longBitsToDouble(0x7e0000000000002eL);
+        test_toString(d, "8.371160993642799E298");
+        d = Double.longBitsToDouble(0x7e0000000000002fL);
+        test_toString(d, "8.3711609936428E298");
+
+        d = Double.longBitsToDouble(0xda00000000000001L);
+        test_toString(d, "-3.3846065602060736E125");
+        d = Double.longBitsToDouble(0xda00000000000002L);
+        test_toString(d, "-3.384606560206074E125");
+
+        d = Double.longBitsToDouble(0xda00000000000005L);
+        test_toString(d, "-3.3846065602060766E125");
+        d = Double.longBitsToDouble(0xda00000000000006L);
+        test_toString(d, "-3.384606560206077E125");
+
+        d = Double.longBitsToDouble(0xda00000000000009L);
+        test_toString(d, "-3.3846065602060796E125");
+        d = Double.longBitsToDouble(0xda0000000000000aL);
+        test_toString(d, "-3.38460656020608E125");
+
+        d = Double.longBitsToDouble(0xda0000000000000dL);
+        test_toString(d, "-3.3846065602060826E125");
+        d = Double.longBitsToDouble(0xda0000000000000eL);
+        test_toString(d, "-3.384606560206083E125");
+    }
+
+    /**
+     * java.lang.Double#valueOf(java.lang.String)
+     */
+    public void test_valueOfLjava_lang_String() {
+        // Test for method java.lang.Double
+        // java.lang.Double.valueOf(java.lang.String)
+        assertTrue("Incorrect double returned", Math.abs(Double.valueOf("999999999999.999")
+                .doubleValue() - 999999999999.999d) < 1);
+
+        try {
+            Double.valueOf(null);
+            fail("Expected Double.valueOf(null) to throw NPE.");
+        } catch (NullPointerException ex) {
+            // expected
+        }
+
+        try {
+            Double.valueOf("");
+            fail("Expected Double.valueOf(\"\") to throw NFE");
+        } catch (NumberFormatException e) {
+            // expected
+        }
+
+        Double pi = Double.valueOf("3.141592654");
+        assertEquals(3.141592654, pi.doubleValue(), 0D);
+
+        Double posZero = Double.valueOf("+0.0");
+        Double negZero = Double.valueOf("-0.0");
+        assertFalse("Doubletest0", posZero.equals(negZero));
+
+        // Tests for double values by name.
+        Double expectedNaN = new Double(Double.NaN);
+
+        Double posNaN = Double.valueOf("NaN");
+        assertTrue("Doubletest1", posNaN.equals(expectedNaN));
+
+        Double posNaNSigned = Double.valueOf("+NaN");
+        assertTrue("Doubletest2", posNaNSigned.equals(expectedNaN));
+
+        Double negNaNSigned = Double.valueOf("-NaN");
+        assertTrue("Doubletest3", negNaNSigned.equals(expectedNaN));
+
+        Double posInfinite = Double.valueOf("Infinity");
+        assertTrue("Doubletest4", posInfinite.equals(new Double(Double.POSITIVE_INFINITY)));
+
+        Double posInfiniteSigned = Double.valueOf("+Infinity");
+        assertTrue("Doubletest5", posInfiniteSigned
+                .equals(new Double(Double.POSITIVE_INFINITY)));
+
+        Double negInfiniteSigned = Double.valueOf("-Infinity");
+        assertTrue("Doubletest6", negInfiniteSigned
+                .equals(new Double(Double.NEGATIVE_INFINITY)));
+    }
+
+    /**
+     * java.lang.Double#compareTo(java.lang.Double)
+     * java.lang.Double#compare(double, double)
+     */
+    public void test_compareToLjava_lang_Double() {
+        // A selection of double values in ascending order.
+        double[] values = 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 < values.length; i++) {
+            double d1 = values[i];
+
+            // Test that each value compares equal to itself; and each object is
+            // equal to another object like itself.
+            assertTrue("Assert 0: compare() should be equal: " + d1,
+                    Double.compare(d1, d1) == 0);
+            Double objDouble = new Double(d1);
+            assertTrue("Assert 1: compareTo() should be equal: " + d1, objDouble
+                    .compareTo(objDouble) == 0);
+
+            // Test that the Double-defined order is respected
+            for (int j = i + 1; j < values.length; j++) {
+                double d2 = values[j];
+                assertTrue("Assert 2: compare() " + d1 + " should be less " + d2, Double
+                        .compare(d1, d2) == -1);
+                assertTrue("Assert 3: compare() " + d2 + " should be greater " + d1, Double
+                        .compare(d2, d1) == 1);
+                Double D2 = new Double(d2);
+                assertTrue("Assert 4: compareTo() " + d1 + " should be less " + d2, objDouble
+                        .compareTo(D2) == -1);
+                assertTrue("Assert 5: compareTo() " + d2 + " should be greater " + d1, D2
+                        .compareTo(objDouble) == 1);
+            }
+        }
+
+        try {
+            new Double(0.0D).compareTo(null);
+            fail("No NPE");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    /**
+     * java.lang.Double#equals(java.lang.Object)
+     */
+    public void test_equalsLjava_lang_Object() {
+        Double d1 = new Double(87654321.12345d);
+        Double d2 = new Double(87654321.12345d);
+        Double d3 = new Double(0.0002f);
+        assertTrue("Assert 0: Equality test failed", d1.equals(d2) && !(d1.equals(d3)));
+
+        assertTrue("Assert 2: NaN should not be == Nan", Double.NaN != Double.NaN);
+        assertTrue("Assert 3: NaN should not be == Nan", new Double(Double.NaN)
+                .equals(new Double(Double.NaN)));
+        assertTrue("Assert 4: -0d should be == 0d", 0d == -0d);
+        assertTrue("Assert 5: -0d should not be equals() 0d", !new Double(0d)
+                .equals(new Double(-0d)));
+
+        Double dmax = new Double(Double.MAX_VALUE);
+        Double dmax1 = new Double(Double.MAX_VALUE);
+
+        assertTrue("Equality test failed", dmax.equals(dmax1) && !(dmax.equals(new Object())));
+    }
+
+    /**
+     * java.lang.Double#toHexString(double)
+     */
+    public void test_toHexStringF() {
+        // the follow values come from the Double Javadoc/Spec
+        assertEquals("0x0.0p0", Double.toHexString(0.0D));
+        assertEquals("-0x0.0p0", Double.toHexString(-0.0D));
+        assertEquals("0x1.0p0", Double.toHexString(1.0D));
+        assertEquals("-0x1.0p0", Double.toHexString(-1.0D));
+        assertEquals("0x1.0p1", Double.toHexString(2.0D));
+        assertEquals("0x1.8p1", Double.toHexString(3.0D));
+        assertEquals("0x1.0p-1", Double.toHexString(0.5D));
+        assertEquals("0x1.0p-2", Double.toHexString(0.25D));
+        assertEquals("0x1.fffffffffffffp1023", Double.toHexString(Double.MAX_VALUE));
+        assertEquals("0x0.0000000000001p-1022", Double.toHexString(Double.MIN_VALUE));
+
+        // test edge cases
+        assertEquals("NaN", Double.toHexString(Double.NaN));
+        assertEquals("-Infinity", Double.toHexString(Double.NEGATIVE_INFINITY));
+        assertEquals("Infinity", Double.toHexString(Double.POSITIVE_INFINITY));
+
+        // test various numbers
+        assertEquals("-0x1.da8p6", Double.toHexString(-118.625D));
+        assertEquals("0x1.2957874cccccdp23", Double.toHexString(9743299.65D));
+        assertEquals("0x1.2957874cccccdp23", Double.toHexString(9743299.65000D));
+        assertEquals("0x1.2957874cccf63p23", Double.toHexString(9743299.650001234D));
+        assertEquals("0x1.700d1061d3333p33", Double.toHexString(12349743299.65000D));
+
+        // test HARMONY-2132
+        assertEquals("0x1.01p10", Double.toHexString(0x1.01p10));
+    }
+
+    /**
+     * java.lang.Double#valueOf(double)
+     */
+    public void test_valueOfD() {
+        assertEquals(new Double(Double.MIN_VALUE), Double.valueOf(Double.MIN_VALUE));
+        assertEquals(new Double(Double.MAX_VALUE), Double.valueOf(Double.MAX_VALUE));
+        assertEquals(new Double(0), Double.valueOf(0));
+
+        int s = -128;
+        while (s < 128) {
+            assertEquals(new Double(s), Double.valueOf(s));
+            assertEquals(new Double(s + 0.1D), Double.valueOf(s + 0.1D));
+            s++;
+        }
+    }
+
+    /**
+     * {@link java.lang.Double#MAX_EXPONENT}
+     * @since 1.6
+     */
+    public void test_MAX_EXPONENT() {
+        assertTrue("Wrong value of java.lang.Double.MAX_EXPONENT",
+                Double.MAX_EXPONENT == 1023);
+        assertTrue("Wrong value of java.lang.Double.MAX_EXPONENT",
+                Double.MAX_EXPONENT == Math.getExponent(Double.MAX_VALUE));
+    }
+
+    /**
+     * {@link java.lang.Double#MIN_EXPONENT}
+     * @since 1.6
+     */
+    public void test_MIN_EXPONENT() {
+        assertTrue("Wrong value of java.lang.Double.MIN_EXPONENT",
+                Double.MIN_EXPONENT == -1022);
+        assertTrue("Wrong value of java.lang.Double.MIN_EXPONENT",
+                Double.MIN_EXPONENT == Math.getExponent(Double.MIN_NORMAL));
+    }
+
+    /**
+     * {@link java.lang.Double#MIN_NORMAL}
+     * @since 1.6
+     */
+    public void test_MIN_NORMAL() {
+        assertTrue("Wrong value of java.lang.Double.MIN_NORMAL",
+                Double.MIN_NORMAL == 0x1.0p-1022);
+        assertTrue("Wrong value of java.lang.Double.MIN_NORMAL",
+                Double.MIN_NORMAL == Double
+                        .longBitsToDouble(0x0010000000000000L));
+        assertTrue("Wrong value of java.lang.Double.MIN_NORMAL",
+                Double.MIN_NORMAL == 2.2250738585072014E-308);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/EnumConstantNotPresentExceptionTest.java b/luni/src/test/java/tests/api/java/lang/EnumConstantNotPresentExceptionTest.java
new file mode 100644
index 0000000..86a589e
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/EnumConstantNotPresentExceptionTest.java
@@ -0,0 +1,45 @@
+/* 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.lang;
+
+import junit.framework.TestCase;
+
+public class EnumConstantNotPresentExceptionTest extends TestCase {
+
+    public enum Fixture {
+        ONE, TWO, THREE
+    }
+
+    public void test_ConstructorLjava_lang_ClassLjava_lang_String() {
+        try {
+            new EnumConstantNotPresentException(null, "");
+            fail("No NPE");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    public void test_enumType() {
+        EnumConstantNotPresentException e = new EnumConstantNotPresentException(Fixture.class, "FOUR");
+        assertEquals(Fixture.class, e.enumType());
+    }
+
+    public void test_constantName() {
+        EnumConstantNotPresentException e = new EnumConstantNotPresentException(Fixture.class, "FOUR");
+        assertEquals("FOUR", e.constantName());
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/lang/EnumTest.java b/luni/src/test/java/tests/api/java/lang/EnumTest.java
new file mode 100644
index 0000000..a044afe
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/EnumTest.java
@@ -0,0 +1,261 @@
+/* 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.lang;
+
+import java.util.HashMap;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+import tests.util.SerializationTester;
+
+public class EnumTest extends TestCase {
+
+    enum Sample {
+        LARRY, MOE, CURLY
+    }
+
+    Sample larry = Sample.LARRY;
+
+    Sample moe = Sample.MOE;
+
+    enum Empty {
+    }
+
+    enum Bogus {
+        UNUSED
+    }
+
+    enum Color {
+        Red, Green, Blue {};
+    }
+
+    enum MockCloneEnum {
+        ONE;
+
+        public void callClone() throws CloneNotSupportedException {
+            super.clone();
+        }
+    }
+
+    /**
+     * java.lang.Enum#compareTo(java.lang.Enum)
+     */
+    public void test_compareToLjava_lang_Enum() {
+        assertTrue(0 < Sample.MOE.compareTo(Sample.LARRY));
+        assertEquals(0, Sample.MOE.compareTo(Sample.MOE));
+        assertTrue(0 > Sample.MOE.compareTo(Sample.CURLY));
+        try {
+            Sample.MOE.compareTo((Sample) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.lang.Enum#equals(Object)
+     */
+    public void test_equalsLjava_lang_Object() {
+        assertFalse(moe.equals("bob"));
+        assertTrue(moe.equals(Sample.MOE));
+        assertFalse(Sample.LARRY.equals(Sample.CURLY));
+        assertTrue(Sample.LARRY.equals(larry));
+        assertFalse(Sample.CURLY.equals(null));
+    }
+
+    /**
+     * java.lang.Enum#getDeclaringClass()
+     */
+    public void test_getDeclaringClass() {
+        assertEquals(Sample.class, moe.getDeclaringClass());
+    }
+
+    /**
+     * java.lang.Enum#hashCode()
+     */
+    public void test_hashCode() {
+        assertEquals(moe.hashCode(), moe.hashCode());
+    }
+
+    /**
+     * java.lang.Enum#name()
+     */
+    public void test_name() {
+        assertEquals("MOE", moe.name());
+    }
+
+    /**
+     * java.lang.Enum#ordinal()
+     */
+    public void test_ordinal() {
+        assertEquals(0, larry.ordinal());
+        assertEquals(1, moe.ordinal());
+        assertEquals(2, Sample.CURLY.ordinal());
+    }
+
+    /**
+     * java.lang.Enum#toString()
+     */
+    public void test_toString() {
+        assertTrue(moe.toString().equals("MOE"));
+    }
+
+    /**
+     * java.lang.Enum#valueOf(Class, String)
+     */
+    public void test_valueOfLjava_lang_String() {
+        assertSame(Sample.CURLY, Sample.valueOf("CURLY"));
+        assertSame(Sample.LARRY, Sample.valueOf("LARRY"));
+        assertSame(moe, Sample.valueOf("MOE"));
+        try {
+            Sample.valueOf("non-existant");
+            fail("Expected an exception");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            Sample.valueOf(null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // May be caused by some compilers' code
+        } catch (IllegalArgumentException e) {
+            // other compilers will throw this
+        }
+
+
+        Sample s = Enum.valueOf(Sample.class, "CURLY");
+        assertSame(s, Sample.CURLY);
+        s = Enum.valueOf(Sample.class, "LARRY");
+        assertSame(larry, s);
+        s = Enum.valueOf(Sample.class, "MOE");
+        assertSame(s, moe);
+        try {
+            Enum.valueOf(Bogus.class, "MOE");
+            fail("Expected IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            Enum.valueOf((Class<Sample>) null, "a string");
+            fail("Expected an exception");
+        } catch (NullPointerException e) {
+            // May be caused by some compilers' code
+        } catch (IllegalArgumentException e) {
+            // other compilers will throw this
+        }
+        try {
+            Enum.valueOf(Sample.class, null);
+            fail("Expected an exception");
+        } catch (NullPointerException e) {
+            // May be caused by some compilers' code
+        } catch (IllegalArgumentException e) {
+            // other compilers will throw this
+        }
+        try {
+            Enum.valueOf((Class<Sample>) null, (String) null);
+            fail("Expected an exception");
+        } catch (NullPointerException e) {
+            // May be caused by some compilers' code
+        } catch (IllegalArgumentException e) {
+            // other compilers will throw this
+        }
+    }
+
+    /**
+     * java.lang.Enum#values
+     */
+    public void test_values() {
+        Sample[] myValues = Sample.values();
+        assertEquals(3, myValues.length);
+
+        assertEquals(Sample.LARRY, myValues[0]);
+        assertEquals(Sample.MOE, myValues[1]);
+        assertEquals(Sample.CURLY, myValues[2]);
+
+        assertEquals(0, Empty.values().length);
+    }
+
+    /**
+     * java.lang.Enum#clone()
+     */
+    public void test_clone() {
+        try {
+            MockCloneEnum.ONE.callClone();
+            fail("Should throw CloneNotSupprotedException");
+        } catch (CloneNotSupportedException e1) {
+            // expected
+        }
+
+    }
+
+    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/deserialization compatibility.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        // test a map class that has enums.
+        // regression test for Harmony-1163
+        HashMap<Color, Integer> enumColorMap = new HashMap<Color, Integer>();
+        enumColorMap.put(Color.Red, 1);
+        enumColorMap.put(Color.Blue, 3);
+
+        Object[] testCases = { enumColorMap, Sample.CURLY };
+
+        SerializationTest.verifySelf(testCases);
+
+        // test a class that has enums as its fields.
+        MockEnum mock = new MockEnum();
+        MockEnum test = (MockEnum) SerializationTest.copySerializable(mock);
+        assertEquals(mock.i, test.i);
+        assertEquals(mock.str, test.str);
+        assertEquals(mock.samEnum, test.samEnum);
+
+        // test a class that has enums and a string of same name as its fields.
+        MockEnum2 mock2 = new MockEnum2();
+        MockEnum2 test2 = (MockEnum2) SerializationTest.copySerializable(mock2);
+        assertEquals(mock2.i, test2.i);
+        assertEquals(mock2.str, test2.str);
+        assertEquals(mock2.samEnum, test2.samEnum);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        // regression test for Harmony-1163
+        HashMap<Color, Integer> enumColorMap = new HashMap<Color, Integer>();
+        enumColorMap.put(Color.Red, 1);
+        enumColorMap.put(Color.Blue, 3);
+
+        Object[] testCases = { Sample.CURLY, new MockEnum(),
+                // test a class that has enums and a string of same name as its fields.
+                new MockEnum2(),
+                // test a map class that has enums.
+                enumColorMap, };
+
+        SerializationTest.verifyGolden(this, testCases);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/ErrorTest.java b/luni/src/test/java/tests/api/java/lang/ErrorTest.java
new file mode 100644
index 0000000..ff44056
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/ErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class ErrorTest extends TestCase {
+
+    /**
+     * java.lang.Error#Error()
+     */
+    public void test_Constructor() {
+        Error e = new Error();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.Error#Error(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        Error e = new Error("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/ExceptionInInitializerErrorTest.java b/luni/src/test/java/tests/api/java/lang/ExceptionInInitializerErrorTest.java
new file mode 100644
index 0000000..4fa6e53
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/ExceptionInInitializerErrorTest.java
@@ -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.
+ */
+
+package tests.api.java.lang;
+
+public class ExceptionInInitializerErrorTest extends junit.framework.TestCase {
+
+    /**
+     * java.lang.ExceptionInInitializerError#ExceptionInInitializerError()
+     */
+    public void test_Constructor() {
+        ExceptionInInitializerError e = new ExceptionInInitializerError();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.ExceptionInInitializerError#ExceptionInInitializerError(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        ExceptionInInitializerError e = new ExceptionInInitializerError("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * 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/tests/api/java/lang/ExceptionTest.java b/luni/src/test/java/tests/api/java/lang/ExceptionTest.java
new file mode 100644
index 0000000..e66bb97
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/ExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class ExceptionTest extends TestCase {
+
+    /**
+     * java.lang.Exception#Exception()
+     */
+    public void test_Constructor() {
+        Exception e = new Exception();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.Exception#Exception(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        Exception e = new Exception("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/FloatTest.java b/luni/src/test/java/tests/api/java/lang/FloatTest.java
new file mode 100644
index 0000000..d703356
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/FloatTest.java
@@ -0,0 +1,1077 @@
+/* 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.lang;
+
+import junit.framework.TestCase;
+
+public class FloatTest extends TestCase {
+
+    private static final int rawBitsFor3_4eN38To38[] = { 0x1394470, 0x2e7958c, 0x490bd77, 0x634ecd5,
+            0x7e2280b, 0x98d5907, 0xb30af48, 0xcdcdb1a, 0xe8a08f0, 0x102c8b2d, 0x11d7adf8,
+            0x1386ccbb, 0x15287fe9, 0x16d29fe4, 0x1883a3ee, 0x1a248cea, 0x1bcdb025, 0x1d808e17,
+            0x1f20b19d, 0x20c8de04, 0x227b1585, 0x241ced73, 0x25c428d0, 0x27753303, 0x29193fe2,
+            0x2abf8fdb, 0x2c6f73d1, 0x2e15a863, 0x2fbb127c, 0x3169d71a, 0x33122671, 0x34b6b00d,
+            0x36645c10, 0x380eb98a, 0x39b267ec, 0x3b5f01e8, 0x3d0b6131, 0x3eae397d, 0x4059c7dc,
+            0x42081cea, 0x43aa2424, 0x4554ad2d, 0x4704ec3c, 0x48a6274b, 0x4a4fb11e, 0x4c01ceb3,
+            0x4da2425f, 0x4f4ad2f7, 0x50fd87b5, 0x529e74d1, 0x54461205, 0x55f79687, 0x579abe14,
+            0x59416d99, 0x5af1c900, 0x5c971da0, 0x5e3ce508, 0x5fec1e4a, 0x619392ee, 0x633877a9,
+            0x64e69594, 0x66901d7c, 0x683424dc, 0x69e12e12, 0x6b8cbccb, 0x6d2febfe, 0x6edbe6fe,
+            0x7089705f, 0x722bcc76, 0x73d6bf94, 0x758637bc, 0x7727c5ac, 0x78d1b717, 0x7a83126e,
+            0x7c23d70a, 0x7dcccccc, 0x7f7fffff };
+
+    private static final String expectedStringFor3_4eN38To38[] = { "3.4028235E-38", "3.4028235E-37",
+            "3.4028233E-36", "3.4028234E-35", "3.4028236E-34", "3.4028236E-33",
+            "3.4028234E-32", "3.4028234E-31", "3.4028233E-30", "3.4028236E-29",
+            "3.4028235E-28", "3.4028235E-27", "3.4028233E-26", "3.4028235E-25",
+            "3.4028233E-24", "3.4028235E-23", "3.4028236E-22", "3.4028235E-21",
+            "3.4028236E-20", "3.4028236E-19", "3.4028236E-18", "3.4028235E-17",
+            "3.4028236E-16", "3.4028234E-15", "3.4028234E-14", "3.4028235E-13",
+            "3.4028234E-12", "3.4028235E-11", "3.4028236E-10", "3.4028234E-9", "3.4028236E-8",
+            "3.4028236E-7", "3.4028235E-6", "3.4028235E-5", "3.4028233E-4", "0.0034028236",
+            "0.034028236", "0.34028235", "3.4028234", "34.028236", "340.28235", "3402.8235",
+            "34028.234", "340282.34", "3402823.5", "3.4028236E7", "3.40282336E8",
+            "3.40282342E9", "3.40282348E10", "3.40282343E11", "3.40282337E12", "3.40282353E13",
+            "3.4028234E14", "3.4028234E15", "3.40282356E16", "3.40282356E17", "3.40282356E18",
+            "3.4028236E19", "3.4028235E20", "3.4028233E21", "3.4028235E22", "3.4028233E23",
+            "3.4028236E24", "3.4028234E25", "3.4028233E26", "3.4028234E27", "3.4028235E28",
+            "3.4028236E29", "3.4028233E30", "3.4028235E31", "3.4028233E32", "3.4028236E33",
+            "3.4028236E34", "3.4028234E35", "3.4028236E36", "3.4028235E37", "3.4028235E38" };
+
+    private static final int rawBitsFor1_17eN38To38[] = { 0x80800000, 0x82200000, 0x83c80000,
+            0x857a0000, 0x871c4000, 0x88c35000, 0x8a742400, 0x8c189680, 0x8dbebc20, 0x8f6e6b28,
+            0x911502f9, 0x92ba43b7, 0x9468d4a5, 0x961184e7, 0x97b5e621, 0x99635fa9, 0x9b0e1bca,
+            0x9cb1a2bc, 0x9e5e0b6b, 0xa00ac723, 0xa1ad78ec, 0xa358d727, 0xa5078678, 0xa6a96816,
+            0xa853c21c, 0xaa045951, 0xaba56fa6, 0xad4ecb8f, 0xaf013f39, 0xb0a18f08, 0xb249f2ca,
+            0xb3fc6f7c, 0xb59dc5ae, 0xb7453719, 0xb8f684df, 0xba9a130c, 0xbc4097ce, 0xbdf0bdc2,
+            0xbf967699, 0xc13c1440, 0xc2eb1950, 0xc492efd2, 0xc637abc6, 0xc7e596b8, 0xc98f7e33,
+            0xcb335dc0, 0xcce0352f, 0xce8c213e, 0xd02f298d, 0xd1daf3f0, 0xd388d876, 0xd52b0e94,
+            0xd6d5d239, 0xd885a363, 0xda270c3c, 0xdbd0cf4b, 0xdd82818f, 0xdf2321f3, 0xe0cbea70,
+            0xe27ee50b, 0xe41f4f27, 0xe5c722f1, 0xe778ebad, 0xe91b934c, 0xeac2781f, 0xec731627,
+            0xee17edd8, 0xefbde94f, 0xf16d63a2, 0xf3145e45, 0xf4b975d7, 0xf667d34c, 0xf810e410,
+            0xf9b51d14, 0xfb626459, 0xfd0d7eb7, 0xfeb0de65 };
+
+    private static final String expectedStringFor1_17eN38To38[] = { "-1.17549435E-38",
+            "-1.1754944E-37", "-1.17549435E-36", "-1.17549435E-35", "-1.1754944E-34",
+            "-1.17549435E-33", "-1.17549435E-32", "-1.1754944E-31", "-1.17549435E-30",
+            "-1.17549435E-29", "-1.1754944E-28", "-1.1754943E-27", "-1.17549435E-26",
+            "-1.1754943E-25", "-1.1754944E-24", "-1.1754943E-23", "-1.1754944E-22",
+            "-1.1754943E-21", "-1.1754943E-20", "-1.1754943E-19", "-1.1754944E-18",
+            "-1.1754944E-17", "-1.1754943E-16", "-1.1754943E-15", "-1.1754944E-14",
+            "-1.1754943E-13", "-1.1754944E-12", "-1.1754943E-11", "-1.1754943E-10",
+            "-1.1754944E-9", "-1.1754944E-8", "-1.1754943E-7", "-1.1754944E-6",
+            "-1.1754943E-5", "-1.1754943E-4", "-0.0011754944", "-0.011754943", "-0.117549434",
+            "-1.1754943", "-11.754944", "-117.54944", "-1175.4944", "-11754.943", "-117549.44",
+            "-1175494.4", "-1.1754944E7", "-1.17549432E8", "-1.1754944E9", "-1.17549435E10",
+            "-1.17549433E11", "-1.17549433E12", "-1.17549438E13", "-1.17549438E14",
+            "-1.1754943E15", "-1.17549432E16", "-1.17549432E17", "-1.17549434E18",
+            "-1.1754944E19", "-1.1754944E20", "-1.1754943E21", "-1.1754943E22",
+            "-1.1754944E23", "-1.17549434E24", "-1.1754943E25", "-1.1754943E26",
+            "-1.17549434E27", "-1.1754943E28", "-1.1754944E29", "-1.1754943E30",
+            "-1.1754943E31", "-1.1754944E32", "-1.1754943E33", "-1.1754944E34",
+            "-1.1754944E35", "-1.1754944E36", "-1.1754943E37", "-1.1754943E38" };
+
+    private void doTestCompareRawBits(String originalFloatString, int expectedRawBits,
+            String expectedString) {
+        int rawBits;
+        float result = Float.parseFloat(originalFloatString);
+        rawBits = Float.floatToIntBits(result);
+        assertEquals("Original float(" + originalFloatString + ") Converted float(" + result
+                + ") Expecting:" + Integer.toHexString(expectedRawBits) + " Got: "
+                + Integer.toHexString(rawBits), expectedRawBits, rawBits);
+    }
+
+    /**
+     * java.lang.Float#Float(float)
+     */
+    public void test_ConstructorF() {
+        // Test for method java.lang.Float(float)
+
+        Float f = new Float(900.89f);
+        assertTrue("Created incorrect float", f.floatValue() == 900.89f);
+    }
+
+    /**
+     * java.lang.Float#Float(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        // Test for method java.lang.Float(java.lang.String)
+
+        Float f = new Float("900.89");
+        assertTrue("Created incorrect Float", f.floatValue() == 900.89f);
+    }
+
+    /**
+     * java.lang.Float#byteValue()
+     */
+    public void test_byteValue() {
+        // Test for method byte java.lang.Float.byteValue()
+        Float f = new Float(0.46874f);
+        Float f2 = new Float(90.8f);
+        assertTrue("Returned incorrect byte value", f.byteValue() == 0 && f2.byteValue() == 90);
+    }
+
+    /**
+     * java.lang.Float#compareTo(java.lang.Float)
+     * java.lang.Float#compare(float, float)
+     */
+    public void test_compare() {
+        float[] values = 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 < values.length; i++) {
+            float f1 = values[i];
+            assertTrue("compare() should be equal: " + f1, Float.compare(f1, f1) == 0);
+            Float F1 = new Float(f1);
+            assertTrue("compareTo() should be equal: " + f1, F1.compareTo(F1) == 0);
+            for (int j = i + 1; j < values.length; j++) {
+                float f2 = values[j];
+                assertTrue("compare() " + f1 + " should be less " + f2,
+                        Float.compare(f1, f2) == -1);
+                assertTrue("compare() " + f2 + " should be greater " + f1, Float
+                        .compare(f2, f1) == 1);
+                Float F2 = new Float(f2);
+                assertTrue("compareTo() " + f1 + " should be less " + f2,
+                        F1.compareTo(F2) == -1);
+                assertTrue("compareTo() " + f2 + " should be greater " + f1,
+                        F2.compareTo(F1) == 1);
+            }
+        }
+
+        try {
+            new Float(0.0F).compareTo(null);
+            fail("No NPE");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    /**
+     * java.lang.Float#doubleValue()
+     */
+    public void test_doubleValue() {
+        // Test for method double java.lang.Float.doubleValue()
+        assertTrue("Incorrect double value returned", Math.abs(new Float(999999.999f)
+                .doubleValue() - 999999.999d) < 1);
+    }
+
+    /**
+     * java.lang.Float#floatToIntBits(float)
+     */
+    public void test_floatToIntBitsF() {
+        float f = 9876.2345f;
+        int bits = Float.floatToIntBits(f);
+        float r = Float.intBitsToFloat(bits);
+        assertTrue("Incorrect intBits returned", f == r);
+    }
+
+    /**
+     * java.lang.Float#floatToRawIntBits(float)
+     */
+    public void test_floatToRawIntBitsF() {
+        int i = 0x7fc004d2;
+        float f = Float.intBitsToFloat(i);
+        assertTrue("Wrong raw bits", Float.floatToRawIntBits(f) == i);
+    }
+
+    /**
+     * java.lang.Float#floatValue()
+     */
+    public void test_floatValue() {
+        // Test for method float java.lang.Float.floatValue()
+        Float f = new Float(87.657f);
+        Float f2 = new Float(-0.876f);
+        assertTrue("Returned incorrect floatValue", f.floatValue() == 87.657f
+                && (f2.floatValue() == -0.876f));
+
+    }
+
+    /**
+     * java.lang.Float#hashCode()
+     */
+    public void test_hashCode() {
+        // Test for method int java.lang.Float.hashCode()
+        Float f = new Float(1908.8786f);
+        assertTrue("Returned invalid hash code for 1908.8786f", f.hashCode() == Float
+                .floatToIntBits(1908.8786f));
+
+        f = new Float(-1.112f);
+        assertTrue("Returned invalid hash code for -1.112", f.hashCode() == Float
+                .floatToIntBits(-1.112f));
+
+        f = new Float(0f);
+        assertTrue("Returned invalid hash code for 0", f.hashCode() == Float.floatToIntBits(0f));
+
+    }
+
+    /**
+     * java.lang.Float#intBitsToFloat(int)
+     */
+    public void test_intBitsToFloatI() {
+        float f = 9876.2345f;
+        int bits = Float.floatToIntBits(f);
+        float r = Float.intBitsToFloat(bits);
+        assertEquals("Incorrect intBits returned", f, r, 0F);
+    }
+
+    /**
+     * java.lang.Float#intValue()
+     */
+    public void test_intValue() {
+        // Test for method int java.lang.Float.intValue()
+        Float f = new Float(0.46874f);
+        Float f2 = new Float(90.8f);
+        assertTrue("Returned incorrect int value", f.intValue() == 0 && f2.intValue() == 90);
+    }
+
+    /**
+     * java.lang.Float#isInfinite()
+     */
+    public void test_isInfinite() {
+        // Test for method boolean java.lang.Float.isInfinite()
+        assertTrue("Infinity check failed",
+                (new Float(Float.POSITIVE_INFINITY).isInfinite() && new Float(
+                        Float.NEGATIVE_INFINITY).isInfinite())
+                        && !(new Float(0.13131414f).isInfinite()));
+    }
+
+    /**
+     * java.lang.Float#isInfinite(float)
+     */
+    public void test_isInfiniteF() {
+        // Test for method boolean java.lang.Float.isInfinite(float)
+
+        assertTrue("Infinity check failed", Float.isInfinite(Float.POSITIVE_INFINITY)
+                && (Float.isInfinite(Float.NEGATIVE_INFINITY)) && !(Float.isInfinite(1.0f)));
+    }
+
+    /**
+     * java.lang.Float#isNaN()
+     */
+    public void test_isNaN() {
+        // Test for method boolean java.lang.Float.isNaN()
+        assertTrue("NAN check failed", new Float(Float.NaN).isNaN()
+                && !(new Float(1.0f).isNaN()));
+    }
+
+    /**
+     * java.lang.Float#isNaN(float)
+     */
+    public void test_isNaNF() {
+        // Test for method boolean java.lang.Float.isNaN(float)
+        assertTrue("NaN check failed", Float.isNaN(Float.NaN) && !(Float.isNaN(12.09f)));
+    }
+
+    /**
+     * java.lang.Float#longValue()
+     */
+    public void test_longValue() {
+        // Test for method long java.lang.Float.longValue()
+        Float f = new Float(0.46874f);
+        Float f2 = new Float(90.8f);
+        assertTrue("Returned incorrect long value", f.longValue() == 0 && f2.longValue() == 90);
+    }
+
+    /**
+     * java.lang.Float#parseFloat(java.lang.String)
+     */
+    public void test_parseFloatLjava_lang_String() {
+        assertEquals("Incorrect float returned, expected zero.", 0.0, Float
+                .parseFloat("7.0064923216240853546186479164495e-46"), 0.0);
+        assertEquals("Incorrect float returned, expected minimum float.", Float.MIN_VALUE,
+                Float.parseFloat("7.0064923216240853546186479164496e-46"), 0.0);
+
+        doTestCompareRawBits(
+                "0.000000000000000000000000000000000000011754942807573642917278829910357665133228589927589904276829631184250030649651730385585324256680905818939208984375",
+                0x800000, "1.17549435E-38");
+        doTestCompareRawBits(
+                "0.00000000000000000000000000000000000001175494280757364291727882991035766513322858992758990427682963118425003064965173038558532425668090581893920898437499999f",
+                0x7fffff, "1.1754942E-38");
+
+        /* Test a set of regular floats with exponents from -38 to +38 */
+        for (int i = 38; i > 3; i--) {
+            String testString;
+            testString = "3.4028234663852886e-" + i;
+            doTestCompareRawBits(testString, rawBitsFor3_4eN38To38[38 - i],
+                    expectedStringFor3_4eN38To38[38 - i]);
+        }
+        doTestCompareRawBits("3.4028234663852886e-3", rawBitsFor3_4eN38To38[38 - 3],
+                expectedStringFor3_4eN38To38[38 - 3]);
+        doTestCompareRawBits("3.4028234663852886e-2", rawBitsFor3_4eN38To38[38 - 2],
+                expectedStringFor3_4eN38To38[38 - 2]);
+        doTestCompareRawBits("3.4028234663852886e-1", rawBitsFor3_4eN38To38[38 - 1],
+                expectedStringFor3_4eN38To38[38 - 1]);
+        doTestCompareRawBits("3.4028234663852886e-0", rawBitsFor3_4eN38To38[38 - 0],
+                expectedStringFor3_4eN38To38[38 - 0]);
+        doTestCompareRawBits("3.4028234663852886e+1", rawBitsFor3_4eN38To38[38 + 1],
+                expectedStringFor3_4eN38To38[38 + 1]);
+        doTestCompareRawBits("3.4028234663852886e+2", rawBitsFor3_4eN38To38[38 + 2],
+                expectedStringFor3_4eN38To38[38 + 2]);
+        doTestCompareRawBits("3.4028234663852886e+3", rawBitsFor3_4eN38To38[38 + 3],
+                expectedStringFor3_4eN38To38[38 + 3]);
+        doTestCompareRawBits("3.4028234663852886e+4", rawBitsFor3_4eN38To38[38 + 4],
+                expectedStringFor3_4eN38To38[38 + 4]);
+        doTestCompareRawBits("3.4028234663852886e+5", rawBitsFor3_4eN38To38[38 + 5],
+                expectedStringFor3_4eN38To38[38 + 5]);
+        doTestCompareRawBits("3.4028234663852886e+6", rawBitsFor3_4eN38To38[38 + 6],
+                expectedStringFor3_4eN38To38[38 + 6]);
+
+        for (int i = 7; i < 39; i++) {
+            String testString;
+            testString = "3.4028234663852886e+" + i;
+            doTestCompareRawBits(testString, rawBitsFor3_4eN38To38[38 + i],
+                    expectedStringFor3_4eN38To38[38 + i]);
+        }
+
+        /* Test another set of regular floats with exponents from -38 to +38 */
+        for (int i = 38; i > 3; i--) {
+            String testString;
+            testString = "-1.1754943508222875e-" + i;
+            doTestCompareRawBits(testString, rawBitsFor1_17eN38To38[38 - i],
+                    expectedStringFor1_17eN38To38[38 - i]);
+        }
+        doTestCompareRawBits("-1.1754943508222875e-3", rawBitsFor1_17eN38To38[38 - 3],
+                expectedStringFor1_17eN38To38[38 - 3]);
+        doTestCompareRawBits("-1.1754943508222875e-2", rawBitsFor1_17eN38To38[38 - 2],
+                expectedStringFor1_17eN38To38[38 - 2]);
+        doTestCompareRawBits("-1.1754943508222875e-1", rawBitsFor1_17eN38To38[38 - 1],
+                expectedStringFor1_17eN38To38[38 - 1]);
+        doTestCompareRawBits("-1.1754943508222875e-0", rawBitsFor1_17eN38To38[38 - 0],
+                expectedStringFor1_17eN38To38[38 - 0]);
+        doTestCompareRawBits("-1.1754943508222875e+1", rawBitsFor1_17eN38To38[38 + 1],
+                expectedStringFor1_17eN38To38[38 + 1]);
+        doTestCompareRawBits("-1.1754943508222875e+2", rawBitsFor1_17eN38To38[38 + 2],
+                expectedStringFor1_17eN38To38[38 + 2]);
+        doTestCompareRawBits("-1.1754943508222875e+3", rawBitsFor1_17eN38To38[38 + 3],
+                expectedStringFor1_17eN38To38[38 + 3]);
+        doTestCompareRawBits("-1.1754943508222875e+4", rawBitsFor1_17eN38To38[38 + 4],
+                expectedStringFor1_17eN38To38[38 + 4]);
+        doTestCompareRawBits("-1.1754943508222875e+5", rawBitsFor1_17eN38To38[38 + 5],
+                expectedStringFor1_17eN38To38[38 + 5]);
+        doTestCompareRawBits("-1.1754943508222875e+6", rawBitsFor1_17eN38To38[38 + 6],
+                expectedStringFor1_17eN38To38[38 + 6]);
+
+        for (int i = 7; i < 39; i++) {
+            String testString;
+            testString = "-1.1754943508222875e+" + i;
+            doTestCompareRawBits(testString, rawBitsFor1_17eN38To38[38 + i],
+                    expectedStringFor1_17eN38To38[38 + i]);
+        }
+
+        /* Test denormalized floats (floats with exponents <= -38 */
+        doTestCompareRawBits("1.1012984643248170E-45", 1, "1.4E-45");
+        doTestCompareRawBits("-1.1012984643248170E-45", 0x80000001, "-1.4E-45");
+        doTestCompareRawBits("1.0E-45", 1, "1.4E-45");
+        doTestCompareRawBits("-1.0E-45", 0x80000001, "-1.4E-45");
+        doTestCompareRawBits("0.9E-45", 1, "1.4E-45");
+        doTestCompareRawBits("-0.9E-45", 0x80000001, "-1.4E-45");
+        doTestCompareRawBits("4.203895392974451e-45", 3, "4.2E-45");
+        doTestCompareRawBits("-4.203895392974451e-45", 0x80000003, "-4.2E-45");
+        doTestCompareRawBits("0.004E-45", 0, "0.0");
+        doTestCompareRawBits("-0.004E-45", 0x80000000, "-0.0");
+
+        /*
+         * Test for large floats close to and greater than 3.4028235E38 and
+         * -3.4028235E38
+         */
+        doTestCompareRawBits("1.2E+38", 0x7eb48e52, "1.2E38");
+        doTestCompareRawBits("-1.2E+38", 0xfeb48e52, "-1.2E38");
+        doTestCompareRawBits("3.2E+38", 0x7f70bdc2, "3.2E38");
+        doTestCompareRawBits("-3.2E+38", 0xff70bdc2, "-3.2E38");
+        doTestCompareRawBits("3.4E+38", 0x7f7fc99e, "3.4E38");
+        doTestCompareRawBits("-3.4E+38", 0xff7fc99e, "-3.4E38");
+        doTestCompareRawBits("3.4028234663852886E+38", 0x7f7fffff, "3.4028235E38");
+        doTestCompareRawBits("-3.4028234663852886E+38", 0xff7fffff, "-3.4028235E38");
+        doTestCompareRawBits("3.405E+38", 0x7f800000, "Infinity");
+        doTestCompareRawBits("-3.405E+38", 0xff800000, "-Infinity");
+        doTestCompareRawBits("3.41E+38", 0x7f800000, "Infinity");
+        doTestCompareRawBits("-3.41E+38", 0xff800000, "-Infinity");
+        doTestCompareRawBits("3.42E+38", 0x7f800000, "Infinity");
+        doTestCompareRawBits("-3.42E+38", 0xff800000, "-Infinity");
+        doTestCompareRawBits("1.0E+39", 0x7f800000, "Infinity");
+        doTestCompareRawBits("-1.0E+39", 0xff800000, "-Infinity");
+    }
+
+    /**
+     * java.lang.Float#parseFloat(java.lang.String)
+     */
+    public void test_parseFloat_LString_Unusual() {
+        float actual;
+
+        actual = Float.parseFloat("0x00000000000000000000000000000000000000000.0000000000000000000000000000000000000p0000000000000000000000000000000000");
+        assertEquals("Returned incorrect value", 0.0f, actual, 0.0F);
+
+        actual = Float.parseFloat("+0Xfffff.fffffffffffffffffffffffffffffffp+99F");
+        assertEquals("Returned incorrect value", 6.64614E35f, actual, 0.0F);
+
+        actual = Float.parseFloat("-0X.123456789abcdefp+99f");
+        assertEquals("Returned incorrect value", -4.5072022E28f, actual, 0.0F);
+
+        actual = Float.parseFloat("-0X123456789abcdef.p+1f");
+        assertEquals("Returned incorrect value", -1.63971062E17f, actual, 0.0F);
+
+        actual = Float.parseFloat("-0X000000000000000000000000000001abcdef.0000000000000000000000000001abefp00000000000000000000000000000000000000000004f");
+        assertEquals("Returned incorrect value", -4.48585472E8f, actual, 0.0F);
+
+        actual = Float.parseFloat("0X0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001234p600f");
+        assertEquals("Returned incorrect value", 5.907252E33f, actual, 0.0F);
+
+        actual = Float.parseFloat("0x1.p9223372036854775807");
+        assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY, actual, 0.0F);
+
+        actual = Float.parseFloat("0x1.p9223372036854775808");
+        assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY, actual, 0.0F);
+
+        actual = Float.parseFloat("0x10.p9223372036854775808");
+        assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY, actual, 0.0F);
+
+        actual = Float.parseFloat("0xabcd.ffffffffp+2000");
+        assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY, actual, 0.0F);
+
+        actual = Float.parseFloat("0x1.p-9223372036854775808");
+        assertEquals("Returned incorrect value", 0.0f, actual, 0.0F);
+
+        actual = Float.parseFloat("0x1.p-9223372036854775809");
+        assertEquals("Returned incorrect value", 0.0f, actual, 0.0F);
+
+        actual = Float.parseFloat("0x.1p-9223372036854775809");
+        assertEquals("Returned incorrect value", 0.0f, actual, 0.0F);
+    }
+
+    /**
+     * java.lang.Float#parseFloat(java.lang.String)
+     */
+    public void test_parseFloat_LString_NormalPositiveExponent() {
+        int[] expecteds = {
+                0x3991a2b4, 0x43cc0247, 0x47909009,
+                0x4ac0c009, 0x4e109005, 0x5140c005,
+                0x5458d805, 0x57848402, 0x5a909002,
+                0x5da8a802, 0x60c0c002, 0x63cccc02,
+                0x66e4e402, 0x69f0f002, 0x6d048401,
+                0x70109001, 0x73169601, 0x76810810,
+                0x79840840, 0x7c8a08a0, 0x7f800000,
+                0x7f800000, 0x7f800000, 0x7f800000,
+                0x7f800000,
+        };
+
+        for (int i = 0; i < expecteds.length; i++) {
+            int part = i * 6;
+            String inputString = "0x" + part + "." + part + "0123456789abcdefp" + part;
+
+            float actual = Float.parseFloat(inputString);
+            float expected = Float.intBitsToFloat(expecteds[i]);
+
+            String expectedString = Integer.toHexString(Float.floatToIntBits(expected));
+            String actualString = Integer.toHexString(Float.floatToIntBits(actual));
+            String errorMsg = i + "th input string is:<" + inputString
+                    + ">.The expected result should be:<" + expectedString
+                    + ">, but was: <" + actualString + ">. ";
+
+            assertEquals(errorMsg, expected, actual, 0.0F);
+        }
+    }
+
+    /**
+     * java.lang.Float#parseFloat(java.lang.String)
+     */
+    public void test_parseFloat_LString_NormalNegativeExponent() {
+        int[] expecteds = {
+                0x3991a2b4,
+                0x3d6e0247,
+                0x3aa0a009,
+                0x37848405,
+                0x3420a005,
+                0x30d4d405,
+                0x2d848402,
+                0x2a129202,
+                0x26acac02,
+                0x2346c602,
+                0x1fe0e002,
+                0x1c6eee02,
+                0x19048401,
+                0x15919101,
+                0x12189801,
+                0xf028828,
+                0xb890890,
+                0x80c88c8,
+                0x4930930,
+                0x1198998,
+                0x28028,
+                0x51c,
+                0xb,
+                0x0,
+                0x0,
+        };
+
+        for (int i = 0; i < expecteds.length; i++) {
+            int part = i * 7;
+            String inputString = "0x" + part + "." + part + "0123456789abcdefp-" + part;
+
+            float actual = Float.parseFloat(inputString);
+            float expected = Float.intBitsToFloat(expecteds[i]);
+
+            String expectedString = Integer.toHexString(Float.floatToIntBits(expected));
+            String actualString = Integer.toHexString(Float.floatToIntBits(actual));
+            String errorMsg = i + "th input string is:<" + inputString
+                    + ">.The expected result should be:<" + expectedString
+                    + ">, but was: <" + actualString + ">. ";
+
+            assertEquals(errorMsg, expected, actual, 0.0F);
+        }
+    }
+
+    /**
+     * java.lang.Float#parseFloat(java.lang.String)
+     */
+    public void test_parseFloat_LString_MaxNormalBoundary() {
+        int[] expecteds = {
+                0x7f7fffff,
+                0x7f7fffff,
+                0x7f7fffff,
+                0x7f800000,
+                0x7f800000,
+                0x7f800000,
+
+                0xff7fffff,
+                0xff7fffff,
+                0xff7fffff,
+                0xff800000,
+                0xff800000,
+                0xff800000,
+        };
+
+        String[] inputs = {
+                "0x1.fffffep127",
+                "0x1.fffffe000000000000000000000000000000000000000000000001p127",
+                "0x1.fffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp127",
+                "0x1.ffffffp127",
+                "0x1.ffffff000000000000000000000000000000000000000000000001p127",
+                "0x1.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp127",
+
+                "-0x1.fffffep127",
+                "-0x1.fffffe000000000000000000000000000000000000000000000001p127",
+                "-0x1.fffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp127",
+                "-0x1.ffffffp127",
+                "-0x1.ffffff000000000000000000000000000000000000000000000001p127",
+                "-0x1.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp127",
+        };
+
+        for (int i = 0; i < inputs.length; i++) {
+            float actual = Float.parseFloat(inputs[i]);
+            float expected = Float.intBitsToFloat(expecteds[i]);
+
+            String expectedString = Integer.toHexString(Float.floatToIntBits(expected));
+            String actualString = Integer.toHexString(Float.floatToIntBits(actual));
+            String errorMsg = i + "th input string is:<" + inputs[i]
+                    + ">.The expected result should be:<" + expectedString
+                    + ">, but was: <" + actualString + ">. ";
+
+            assertEquals(errorMsg, expected, actual, 0.0F);
+        }
+    }
+
+    /**
+     * java.lang.Float#parseFloat(java.lang.String)
+     */
+    public void test_parseFloat_LString_MinNormalBoundary() {
+        int expecteds[] = {
+                0x800000,
+                0x800000,
+                0x800000,
+                0x800000,
+                0x800001,
+                0x800001,
+
+                0x80800000,
+                0x80800000,
+                0x80800000,
+                0x80800000,
+                0x80800001,
+                0x80800001,
+        };
+
+        String inputs[] = {
+                "0x1.0p-126",
+                "0x1.00000000000000000000000000000000000000000000001p-126",
+                "0x1.000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+                "0x1.000001p-126",
+                "0x1.000001000000000000000000000000000000000000000001p-126",
+                "0x1.000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+
+                "-0x1.0p-126",
+                "-0x1.00000000000000000000000000000000000000000000001p-126",
+                "-0x1.000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+                "-0x1.000001p-126",
+                "-0x1.000001000000000000000000000000000000000000000001p-126",
+                "-0x1.000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+        };
+
+        for (int i = 0; i < inputs.length; i++) {
+            float actual = Float.parseFloat(inputs[i]);
+            float expected = Float.intBitsToFloat(expecteds[i]);
+
+            String expectedString = Integer.toHexString(Float.floatToIntBits(expected));
+            String actualString = Integer.toHexString(Float.floatToIntBits(actual));
+            String errorMsg = i + "th input string is:<" + inputs[i]
+                    + ">.The expected result should be:<" + expectedString
+                    + ">, but was: <" + actualString + ">. ";
+
+            assertEquals(errorMsg, expected, actual, 0.0F);
+        }
+    }
+
+    /**
+     * java.lang.Float#parseFloat(java.lang.String)
+     */
+    public void test_parseFloat_LString_MaxSubNormalBoundary() {
+        int expecteds[] = {
+                0x7fffff,
+                0x7fffff,
+                0x7fffff,
+                0x800000,
+                0x800000,
+                0x800000,
+
+                0x807fffff,
+                0x807fffff,
+                0x807fffff,
+                0x80800000,
+                0x80800000,
+                0x80800000,
+        };
+
+        String inputs[] = {
+                "0x0.fffffep-126",
+                "0x0.fffffe000000000000000000000000000000000000000000000000000001p-126",
+                "0x0.fffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+                "0x0.ffffffp-126",
+                "0x0.ffffff0000000000000000000000000000000000000000000000000000001p-126",
+                "0x0.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+
+                "-0x0.fffffep-126",
+                "-0x0.fffffe000000000000000000000000000000000000000000000000000001p-126",
+                "-0x0.fffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+                "-0x0.ffffffp-126",
+                "-0x0.ffffff0000000000000000000000000000000000000000000000000000001p-126",
+                "-0x0.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+        };
+
+        for (int i = 0; i < inputs.length; i++) {
+            float actual = Float.parseFloat(inputs[i]);
+            float expected = Float.intBitsToFloat(expecteds[i]);
+
+            String expectedString = Integer.toHexString(Float.floatToIntBits(expected));
+            String actualString = Integer.toHexString(Float.floatToIntBits(actual));
+            String errorMsg = i + "th input string is:<" + inputs[i]
+                    + ">.The expected result should be:<" + expectedString
+                    + ">, but was: <" + actualString + ">. ";
+
+            assertEquals(errorMsg, expected, actual, 0.0F);
+        }
+    }
+
+    /**
+     * java.lang.Float#parseFloat(java.lang.String)
+     */
+    public void test_parseFloat_LString_MinSubNormalBoundary() {
+        int expecteds[] = {
+                0x1,
+                0x1,
+                0x1,
+                0x2,
+                0x2,
+                0x2,
+
+                0x80000001,
+                0x80000001,
+                0x80000001,
+                0x80000002,
+                0x80000002,
+                0x80000002,
+        };
+
+        String inputs[] = {
+                "0x0.000002p-126",
+                "0x0.00000200000000000000000000000000000000000001p-126",
+                "0x0.000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+                "0x0.000003p-126",
+                "0x0.000003000000000000000000000000000000000000001p-126",
+                "0x0.000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+
+                "-0x0.000002p-126",
+                "-0x0.00000200000000000000000000000000000000000001p-126",
+                "-0x0.000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+                "-0x0.000003p-126",
+                "-0x0.000003000000000000000000000000000000000000001p-126",
+                "-0x0.000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+        };
+
+        for (int i = 0; i < inputs.length; i++) {
+            float actual = Float.parseFloat(inputs[i]);
+            float expected = Float.intBitsToFloat(expecteds[i]);
+
+            String expectedString = Integer.toHexString(Float.floatToIntBits(expected));
+            String actualString = Integer.toHexString(Float.floatToIntBits(actual));
+            String errorMsg = i + "th input string is:<" + inputs[i]
+                    + ">.The expected result should be:<" + expectedString
+                    + ">, but was: <" + actualString + ">. ";
+
+            assertEquals(errorMsg, expected, actual, 0.0F);
+        }
+    }
+
+    /**
+     * java.lang.Float#parseFloat(java.lang.String)
+     */
+    public void test_parseFloat_LString_ZeroBoundary() {
+        int expecteds[] = {
+                0x0,
+                0x0,
+                0x0,
+                0x0,
+                0x1,
+                0x1,
+
+                0x80000000,
+                0x80000000,
+                0x80000000,
+                0x80000000,
+                0x80000001,
+                0x80000001,
+        };
+
+        String inputs[] = {
+                "0x0.000000000000000p-126",
+                "0x0.000000000000000000000000000000000000000000000001p-126",
+                "0x0.000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+                "0x0.000001p-126",
+                "0x0.000001000000000000000000000000000000000000000001p-126",
+                "0x0.000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+
+                "-0x0.000000000000000p-126",
+                "-0x0.000000000000000000000000000000000000000000000001p-126",
+                "-0x0.000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+                "-0x0.000001p-126",
+                "-0x0.000001000000000000000000000000000000000000000001p-126",
+                "-0x0.000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffp-126",
+        };
+
+        for (int i = 0; i < inputs.length; i++) {
+            float actual = Float.parseFloat(inputs[i]);
+            float expected = Float.intBitsToFloat(expecteds[i]);
+
+            String expectedString = Integer.toHexString(Float.floatToIntBits(expected));
+            String actualString = Integer.toHexString(Float.floatToIntBits(actual));
+            String errorMsg = i + "th input string is:<" + inputs[i]
+                    + ">.The expected result should be:<" + expectedString
+                    + ">, but was: <" + actualString + ">. ";
+
+            assertEquals(errorMsg, expected, actual, 0.0F);
+        }
+    }
+
+    /**
+     * java.lang.Float#parseFloat(java.lang.String)
+     */
+    public void test_parseFloat_LString_Harmony6261() {
+        // Regression test for HARMONY-6261
+        float f = new Float("2147483648");
+        assertEquals("2.1474836E9", Float.toString(f));
+
+        doTestCompareRawBits("123456790528.000000000000000f", 0x51e5f4c9, "1.2345679E11");
+        doTestCompareRawBits("8589934592", 0x50000000, "8.5899346E9");
+        doTestCompareRawBits("8606711808", 0x50004000, "8.606712E9");
+    }
+
+    /**
+     * java.lang.Float#shortValue()
+     */
+    public void test_shortValue() {
+        // Test for method short java.lang.Float.shortValue()
+        Float f = new Float(0.46874f);
+        Float f2 = new Float(90.8f);
+        assertTrue("Returned incorrect short value", f.shortValue() == 0
+                && f2.shortValue() == 90);
+    }
+
+    /**
+     * java.lang.Float#toString()
+     */
+    public void test_toString() {
+        // Test for method java.lang.String java.lang.Float.toString()
+
+        test_toString(12.90898f, "12.90898");
+
+        test_toString(1.7014118346046924e+38F, "1.7014118E38");
+
+        test_toString(1E19F, "1.0E19");
+
+        test_toString(1E-36F, "1.0E-36");
+
+        test_toString(1.0E-38F, "1.0E-38");
+    }
+
+    /**
+     * java.lang.Float#toString(float)
+     */
+    public void test_toStringF() {
+        // Test for method java.lang.String java.lang.Float.toString(float)
+
+        float ff;
+        String answer;
+
+        ff = 12.90898f;
+        answer = "12.90898";
+        assertTrue("Incorrect String representation want " + answer + ", got "
+                + Float.toString(ff), Float.toString(ff).equals(answer));
+
+        ff = Float.MAX_VALUE;
+        answer = "3.4028235E38";
+        assertTrue("Incorrect String representation want " + answer + ", got "
+                + Float.toString(ff), Float.toString(ff).equals(answer));
+    }
+
+    /**
+     * java.lang.Float#valueOf(java.lang.String)
+     */
+    public void test_valueOfLjava_lang_String() {
+        // Test for method java.lang.Float
+        // java.lang.Float.valueOf(java.lang.String)
+
+        Float wanted = new Float(432.1235f);
+        Float got = Float.valueOf("432.1235");
+        assertTrue("Incorrect float returned--wanted: " + wanted + " but got: " + got, got
+                .equals(wanted));
+
+        wanted = new Float(0f);
+        got = Float.valueOf("0");
+        assertTrue("Incorrect float returned--wanted: " + wanted + " but got: " + got, got
+                .equals(wanted));
+
+        wanted = new Float(-1212.3232f);
+        got = Float.valueOf("-1212.3232");
+        assertTrue("Incorrect float returned--wanted: " + wanted + " but got: " + got, got
+                .equals(wanted));
+
+        try {
+            Float.valueOf(null);
+            fail("Expected Float.valueOf(null) to throw NPE.");
+        } catch (NullPointerException ex) {
+            // expected
+        }
+
+        try {
+            Float.valueOf("");
+            fail("Expected Float.valueOf(\"\") to throw NFE");
+        } catch (NumberFormatException e) {
+            // expected
+        }
+
+        Float posZero = Float.valueOf("+0.0");
+        Float negZero = Float.valueOf("-0.0");
+        assertFalse("Floattest0", posZero.equals(negZero));
+        assertTrue("Floattest1", 0.0f == -0.0f);
+
+        // Tests for float values by name.
+        Float expectedNaN = new Float(Float.NaN);
+
+        Float posNaN = Float.valueOf("NaN");
+        assertTrue("Floattest2", posNaN.equals(expectedNaN));
+
+        Float posNaNSigned = Float.valueOf("+NaN");
+        assertTrue("Floattest3", posNaNSigned.equals(expectedNaN));
+
+        Float negNaNSigned = Float.valueOf("-NaN");
+        assertTrue("Floattest4", negNaNSigned.equals(expectedNaN));
+
+        Float posInfinite = Float.valueOf("Infinity");
+        assertTrue("Floattest5", posInfinite.equals(new Float(Float.POSITIVE_INFINITY)));
+
+        Float posInfiniteSigned = Float.valueOf("+Infinity");
+        assertTrue("Floattest6", posInfiniteSigned.equals(new Float(Float.POSITIVE_INFINITY)));
+
+        Float negInfiniteSigned = Float.valueOf("-Infinity");
+        assertTrue("Floattest7", negInfiniteSigned.equals(new Float(Float.NEGATIVE_INFINITY)));
+
+        // test HARMONY-6641
+        posInfinite = Float.valueOf("320.0E+2147483647");
+        assertEquals("Floattest8", Float.POSITIVE_INFINITY, posInfinite);
+
+        negZero = Float.valueOf("-1.4E-2147483314");
+        assertEquals("Floattest9", -0.0f, negZero);
+    }
+
+    private void test_toString(float ff, String answer) {
+        // Test for method java.lang.String java.lang.Double.toString(double)
+        assertTrue("Incorrect String representation want " + answer + ", got ("
+                + Float.toString(ff) + ")", Float.toString(ff).equals(answer));
+        Float f = new Float(ff);
+        assertTrue("Incorrect String representation want " + answer + ", got ("
+                + Float.toString(f.floatValue()) + ")", Float.toString(f.floatValue()).equals(
+                answer));
+        assertTrue("Incorrect String representation want " + answer + ", got (" + f.toString()
+                + ")", f.toString().equals(answer));
+    }
+
+    /**
+     * java.lang.Float#compareTo(java.lang.Float)
+     * java.lang.Float#compare(float, float)
+     */
+    public void test_compareToLjava_lang_Float() {
+        // A selection of float values in ascending order.
+        float[] values = 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 < values.length; i++) {
+            float f1 = values[i];
+
+            // Test that each value compares equal to itself; and each object is
+            // equal to another object
+            // like itself
+            assertTrue("Assert 0: compare() should be equal: " + f1, Float.compare(f1, f1) == 0);
+            Float objFloat = new Float(f1);
+            assertTrue("Assert 1: compareTo() should be equal: " + objFloat, objFloat
+                    .compareTo(objFloat) == 0);
+
+            // Test that the Float-defined order is respected
+            for (int j = i + 1; j < values.length; j++) {
+                float f2 = values[j];
+                assertTrue("Assert 2: compare() " + f1 + " should be less " + f2, Float
+                        .compare(f1, f2) == -1);
+                assertTrue("Assert 3: compare() " + f2 + " should be greater " + f1, Float
+                        .compare(f2, f1) == 1);
+
+                Float F2 = new Float(f2);
+                assertTrue("Assert 4: compareTo() " + f1 + " should be less " + f2, objFloat
+                        .compareTo(F2) == -1);
+                assertTrue("Assert 5: compareTo() " + f2 + " should be greater " + f1, F2
+                        .compareTo(objFloat) == 1);
+            }
+        }
+    }
+
+    /**
+     * java.lang.Float#equals(java.lang.Object)
+     */
+    public void test_equalsLjava_lang_Object() {
+        Float f1 = new Float(8765.4321f);
+        Float f2 = new Float(8765.4321f);
+        Float f3 = new Float(-1.0f);
+        assertTrue("Assert 0: Equality test failed", f1.equals(f2) && !(f1.equals(f3)));
+
+        assertTrue("Assert 1: NaN should not be == Nan", Float.NaN != Float.NaN);
+        assertTrue("Assert 2: NaN should not be == Nan", new Float(Float.NaN).equals(new Float(
+                Float.NaN)));
+        assertTrue("Assert 3: -0f should be == 0f", 0f == -0f);
+        assertTrue("Assert 4: -0f should not be equals() 0f", !new Float(0f).equals(new Float(
+                -0f)));
+
+        f1 = new Float(1098.576f);
+        f2 = new Float(1098.576f);
+        f3 = new Float(1.0f);
+        assertTrue("Equality test failed", f1.equals(f2) && !(f1.equals(f3)));
+
+        assertTrue("NaN should not be == Nan", Float.NaN != Float.NaN);
+        assertTrue("NaN should not be == Nan", new Float(Float.NaN)
+                .equals(new Float(Float.NaN)));
+        assertTrue("-0f should be == 0f", 0f == -0f);
+        assertTrue("-0f should not be equals() 0f", !new Float(0f).equals(new Float(-0f)));
+    }
+
+    /**
+     * java.lang.Float#toHexString(float)
+     */
+    public void test_toHexStringF() {
+        // the follow values comes from the Float Javadoc/Spec
+        assertEquals("0x0.0p0", Float.toHexString(0.0F));
+        assertEquals("-0x0.0p0", Float.toHexString(-0.0F));
+        assertEquals("0x1.0p0", Float.toHexString(1.0F));
+        assertEquals("-0x1.0p0", Float.toHexString(-1.0F));
+        assertEquals("0x1.0p1", Float.toHexString(2.0F));
+        assertEquals("0x1.8p1", Float.toHexString(3.0F));
+        assertEquals("0x1.0p-1", Float.toHexString(0.5F));
+        assertEquals("0x1.0p-2", Float.toHexString(0.25F));
+        assertEquals("0x1.fffffep127", Float.toHexString(Float.MAX_VALUE));
+        assertEquals("0x0.000002p-126", Float.toHexString(Float.MIN_VALUE));
+
+        // test edge cases
+        assertEquals("NaN", Float.toHexString(Float.NaN));
+        assertEquals("-Infinity", Float.toHexString(Float.NEGATIVE_INFINITY));
+        assertEquals("Infinity", Float.toHexString(Float.POSITIVE_INFINITY));
+
+        // test various numbers
+        assertEquals("-0x1.da8p6", Float.toHexString(-118.625F));
+        assertEquals("0x1.295788p23", Float.toHexString(9743299.65F));
+        assertEquals("0x1.295788p23", Float.toHexString(9743299.65000F));
+        assertEquals("0x1.295788p23", Float.toHexString(9743299.650001234F));
+        assertEquals("0x1.700d1p33", Float.toHexString(12349743299.65000F));
+
+        // test HARMONY-2132
+        assertEquals("0x1.01p10", Float.toHexString(0x1.01p10f));
+    }
+
+    /**
+     * java.lang.Float#valueOf(float)
+     */
+    public void test_valueOfF() {
+        assertEquals(new Float(Float.MIN_VALUE), Float.valueOf(Float.MIN_VALUE));
+        assertEquals(new Float(Float.MAX_VALUE), Float.valueOf(Float.MAX_VALUE));
+        assertEquals(new Float(0), Float.valueOf(0));
+
+        int s = -128;
+        while (s < 128) {
+            assertEquals(new Float(s), Float.valueOf(s));
+            assertEquals(new Float(s + 0.1F), Float.valueOf(s + 0.1F));
+            assertEquals(Float.valueOf(s + 0.1F), Float.valueOf(s + 0.1F));
+            s++;
+        }
+    }
+
+    /**
+     * {@link java.lang.Float#MAX_EXPONENT}
+     * @since 1.6
+     */
+    public void test_MAX_EXPONENT() {
+        assertTrue("Wrong value of java.lang.Float.MAX_EXPONENT",
+                Float.MAX_EXPONENT == 127);
+        assertTrue("Wrong value of java.lang.Float.MAX_EXPONENT",
+                Float.MAX_EXPONENT == Math.getExponent(Float.MAX_VALUE));
+    }
+
+    /**
+     * {@link java.lang.Float#MIN_EXPONENT}
+     * @since 1.6
+     */
+    public void test_MIN_EXPONENT() {
+        assertTrue("Wrong value of java.lang.Float.MIN_EXPONENT",
+                Float.MIN_EXPONENT == -126);
+        assertTrue("Wrong value of java.lang.Float.MIN_EXPONENT",
+                Float.MIN_EXPONENT == Math.getExponent(Float.MIN_NORMAL));
+    }
+
+    /**
+     * {@link java.lang.Float#MIN_NORMAL}
+     * @since 1.6
+     */
+    public void test_MIN_NORMAL() {
+        assertTrue("Wrong value of java.lang.Float.MIN_NORMAL",
+                Float.MIN_NORMAL == 0x1.0p-126f);
+        assertTrue("Wrong value of java.lang.Float.MIN_NORMAL",
+                Float.MIN_NORMAL == Float.intBitsToFloat(0x00800000));
+        assertTrue("Wrong value of java.lang.Float.MIN_NORMAL",
+                Float.MIN_NORMAL == 1.1754943508222875E-38f);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/IllegalAccessErrorTest.java b/luni/src/test/java/tests/api/java/lang/IllegalAccessErrorTest.java
new file mode 100644
index 0000000..94f912a
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/IllegalAccessErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class IllegalAccessErrorTest extends TestCase {
+
+    /**
+     * java.lang.IllegalAccessError#IllegalAccessError()
+     */
+    public void test_Constructor() {
+        IllegalAccessError e = new IllegalAccessError();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.IllegalAccessError#IllegalAccessError(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        IllegalAccessError e = new IllegalAccessError("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/IllegalAccessExceptionTest.java b/luni/src/test/java/tests/api/java/lang/IllegalAccessExceptionTest.java
new file mode 100644
index 0000000..61d6054
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/IllegalAccessExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class IllegalAccessExceptionTest extends TestCase {
+
+    /**
+     * java.lang.IllegalAccessException#IllegalAccessException()
+     */
+    public void test_Constructor() {
+        IllegalAccessException e = new IllegalAccessException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.IllegalAccessException#IllegalAccessException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        IllegalAccessException e = new IllegalAccessException("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/IllegalArgumentExceptionTest.java b/luni/src/test/java/tests/api/java/lang/IllegalArgumentExceptionTest.java
new file mode 100644
index 0000000..6003c9e
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/IllegalArgumentExceptionTest.java
@@ -0,0 +1,87 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class IllegalArgumentExceptionTest extends TestCase {
+
+    /**
+     * java.lang.IllegalArgumentException#IllegalArgumentException()
+     */
+    public void test_Constructor() {
+        IllegalArgumentException e = new IllegalArgumentException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * {@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());
+    }
+
+    /**
+     * java.lang.IllegalArgumentException#IllegalArgumentException(String, Throwable)
+     */
+    @SuppressWarnings("nls")
+    public void test_ConstructorLjava_lang_StringLjava_lang_Throwable() {
+        NullPointerException npe = new NullPointerException();
+        IllegalArgumentException e = new IllegalArgumentException("fixture",
+                npe);
+        assertSame("fixture", e.getMessage());
+        assertSame(npe, e.getCause());
+    }
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+        SerializationTest.verifySelf(new IllegalArgumentException());
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+        SerializationTest.verifyGolden(this, new IllegalArgumentException());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/IllegalMonitorStateExceptionTest.java b/luni/src/test/java/tests/api/java/lang/IllegalMonitorStateExceptionTest.java
new file mode 100644
index 0000000..994e591
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/IllegalMonitorStateExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class IllegalMonitorStateExceptionTest extends TestCase {
+
+    /**
+     * java.lang.IllegalMonitorStateException#IllegalMonitorStateException()
+     */
+    public void test_Constructor() {
+        IllegalMonitorStateException e = new IllegalMonitorStateException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.IllegalMonitorStateException#IllegalMonitorStateException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        IllegalMonitorStateException e = new IllegalMonitorStateException("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/IllegalStateExceptionTest.java b/luni/src/test/java/tests/api/java/lang/IllegalStateExceptionTest.java
new file mode 100644
index 0000000..02100c0
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/IllegalStateExceptionTest.java
@@ -0,0 +1,95 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class IllegalStateExceptionTest extends TestCase {
+
+    /**
+     * java.lang.IllegalStateException#IllegalStateException()
+     */
+    public void test_Constructor() {
+        IllegalStateException e = new IllegalStateException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.IllegalStateException#IllegalStateException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        IllegalStateException e = new IllegalStateException("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * {@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());
+    }
+
+    /**
+     * {@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());
+    }
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        SerializationTest.verifySelf(new IllegalStateException());
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        SerializationTest.verifyGolden(this, new IllegalStateException());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/IllegalThreadStateExceptionTest.java b/luni/src/test/java/tests/api/java/lang/IllegalThreadStateExceptionTest.java
new file mode 100644
index 0000000..4497471
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/IllegalThreadStateExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class IllegalThreadStateExceptionTest extends TestCase {
+
+    /**
+     * java.lang.IllegalThreadStateException#IllegalThreadStateException()
+     */
+    public void test_Constructor() {
+        IllegalThreadStateException e = new IllegalThreadStateException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.IllegalThreadStateException#IllegalThreadStateException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        IllegalThreadStateException e = new IllegalThreadStateException("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/IncompatibleClassChangeErrorTest.java b/luni/src/test/java/tests/api/java/lang/IncompatibleClassChangeErrorTest.java
new file mode 100644
index 0000000..5bd8789
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/IncompatibleClassChangeErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class IncompatibleClassChangeErrorTest extends TestCase {
+
+    /**
+     * java.lang.IncompatibleClassChangeError#IncompatibleClassChangeError()
+     */
+    public void test_Constructor() {
+        IncompatibleClassChangeError e = new IncompatibleClassChangeError();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.IncompatibleClassChangeError#IncompatibleClassChangeError(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        IncompatibleClassChangeError e = new IncompatibleClassChangeError("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/IndexOutOfBoundsExceptionTest.java b/luni/src/test/java/tests/api/java/lang/IndexOutOfBoundsExceptionTest.java
new file mode 100644
index 0000000..3414838
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/IndexOutOfBoundsExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class IndexOutOfBoundsExceptionTest extends TestCase {
+
+    /**
+     * java.lang.IndexOutOfBoundsException#IndexOutOfBoundsException()
+     */
+    public void test_Constructor() {
+        IndexOutOfBoundsException e = new IndexOutOfBoundsException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.IndexOutOfBoundsException#IndexOutOfBoundsException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        IndexOutOfBoundsException e = new IndexOutOfBoundsException("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/InheritableThreadLocalTest.java b/luni/src/test/java/tests/api/java/lang/InheritableThreadLocalTest.java
new file mode 100644
index 0000000..2ea8dea
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/InheritableThreadLocalTest.java
@@ -0,0 +1,41 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class InheritableThreadLocalTest extends TestCase {
+
+    /**
+     * java.lang.InheritableThreadLocal#InheritableThreadLocal()
+     */
+    public void test_Constructor() {
+        InheritableThreadLocal<String> itl = new InheritableThreadLocal<String>();
+        assertNull(itl.get());
+    }
+
+    public void test_initialValue() {
+        InheritableThreadLocal<String> itl = new InheritableThreadLocal<String>() {
+            @Override
+            protected String initialValue() {
+                return "initial";
+            }
+        };
+        assertEquals("initial", itl.get());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/InstantiationErrorTest.java b/luni/src/test/java/tests/api/java/lang/InstantiationErrorTest.java
new file mode 100644
index 0000000..8655dad
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/InstantiationErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class InstantiationErrorTest extends TestCase {
+
+    /**
+     * java.lang.InstantiationError#InstantiationError()
+     */
+    public void test_Constructor() {
+        InstantiationError e = new InstantiationError();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.InstantiationError#InstantiationError(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        InstantiationError e = new InstantiationError("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/InstantiationExceptionTest.java b/luni/src/test/java/tests/api/java/lang/InstantiationExceptionTest.java
new file mode 100644
index 0000000..1be39ab
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/InstantiationExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class InstantiationExceptionTest extends TestCase {
+
+    /**
+     * java.lang.InstantiationException#InstantiationException()
+     */
+    public void test_Constructor() {
+        InstantiationException e = new InstantiationException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.InstantiationException#InstantiationException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        InstantiationException e = new InstantiationException("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/IntegerTest.java b/luni/src/test/java/tests/api/java/lang/IntegerTest.java
new file mode 100644
index 0000000..f80107f
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/IntegerTest.java
@@ -0,0 +1,1231 @@
+/* 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.lang;
+
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+public class IntegerTest extends TestCase {
+    private Properties orgProps;
+
+    @Override
+    protected void setUp() {
+        orgProps = System.getProperties();
+    }
+
+    @Override
+    protected void tearDown() {
+        System.setProperties(orgProps);
+    }
+
+    /**
+     * java.lang.Integer#byteValue()
+     */
+    public void test_byteValue() {
+        // Test for method byte java.lang.Integer.byteValue()
+        assertEquals("Returned incorrect byte value", -1, new Integer(65535)
+                .byteValue());
+        assertEquals("Returned incorrect byte value", 127, new Integer(127)
+                .byteValue());
+    }
+
+    /**
+     * java.lang.Integer#compareTo(java.lang.Integer)
+     */
+    public void test_compareToLjava_lang_Integer() {
+        // Test for method int java.lang.Integer.compareTo(java.lang.Integer)
+        assertTrue("-2 compared to 1 gave non-negative answer", new Integer(-2)
+                .compareTo(new Integer(1)) < 0);
+        assertEquals("-2 compared to -2 gave non-zero answer", 0, new Integer(-2)
+                .compareTo(new Integer(-2)));
+        assertTrue("3 compared to 2 gave non-positive answer", new Integer(3)
+                .compareTo(new Integer(2)) > 0);
+
+        try {
+            new Integer(0).compareTo(null);
+            fail("No NPE");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    /**
+     * java.lang.Integer#decode(java.lang.String)
+     */
+    public void test_decodeLjava_lang_String2() {
+        // Test for method java.lang.Integer
+        // java.lang.Integer.decode(java.lang.String)
+        assertEquals("Failed for 132233",
+                132233, Integer.decode("132233").intValue());
+        assertEquals("Failed for 07654321",
+                07654321, Integer.decode("07654321").intValue());
+        assertTrue("Failed for #1234567",
+                Integer.decode("#1234567").intValue() == 0x1234567);
+        assertTrue("Failed for 0xdAd",
+                Integer.decode("0xdAd").intValue() == 0xdad);
+        assertEquals("Failed for -23", -23, Integer.decode("-23").intValue());
+        assertEquals("Returned incorrect value for 0 decimal", 0, Integer
+                .decode("0").intValue());
+        assertEquals("Returned incorrect value for 0 hex", 0, Integer.decode("0x0")
+                .intValue());
+        assertTrue("Returned incorrect value for most negative value decimal",
+                Integer.decode("-2147483648").intValue() == 0x80000000);
+        assertTrue("Returned incorrect value for most negative value hex",
+                Integer.decode("-0x80000000").intValue() == 0x80000000);
+        assertTrue("Returned incorrect value for most positive value decimal",
+                Integer.decode("2147483647").intValue() == 0x7fffffff);
+        assertTrue("Returned incorrect value for most positive value hex",
+                Integer.decode("0x7fffffff").intValue() == 0x7fffffff);
+
+        boolean exception = false;
+        try {
+            Integer.decode("0a");
+        } catch (NumberFormatException e) {
+            // correct
+            exception = true;
+        }
+        assertTrue("Failed to throw NumberFormatException for \"Oa\"",
+                exception);
+
+        exception = false;
+        try {
+            Integer.decode("2147483648");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for MAX_VALUE + 1", exception);
+
+        exception = false;
+        try {
+            Integer.decode("-2147483649");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for MIN_VALUE - 1", exception);
+
+        exception = false;
+        try {
+            Integer.decode("0x80000000");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for hex MAX_VALUE + 1", exception);
+
+        exception = false;
+        try {
+            Integer.decode("-0x80000001");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for hex MIN_VALUE - 1", exception);
+
+        exception = false;
+        try {
+            Integer.decode("9999999999");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for 9999999999", exception);
+
+        try {
+            Integer.decode("-");
+            fail("Expected exception for -");
+        } catch (NumberFormatException e) {
+            // Expected
+        }
+
+        try {
+            Integer.decode("0x");
+            fail("Expected exception for 0x");
+        } catch (NumberFormatException e) {
+            // Expected
+        }
+
+        try {
+            Integer.decode("#");
+            fail("Expected exception for #");
+        } catch (NumberFormatException e) {
+            // Expected
+        }
+
+        try {
+            Integer.decode("x123");
+            fail("Expected exception for x123");
+        } catch (NumberFormatException e) {
+            // Expected
+        }
+
+        try {
+            Integer.decode(null);
+            fail("Expected exception for null");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            Integer.decode("");
+            fail("Expected exception for empty string");
+        } catch (NumberFormatException ex) {
+            // Expected
+        }
+
+        try {
+            Integer.decode(" ");
+            fail("Expected exception for single space");
+        } catch (NumberFormatException ex) {
+            // Expected
+        }
+
+    }
+
+    /**
+     * java.lang.Integer#doubleValue()
+     */
+    public void test_doubleValue2() {
+        // Test for method double java.lang.Integer.doubleValue()
+        assertEquals("Returned incorrect double value", 2147483647.0, new Integer(2147483647)
+                .doubleValue(), 0.0D);
+        assertEquals("Returned incorrect double value", -2147483647.0, new Integer(-2147483647)
+                .doubleValue(), 0.0D);
+    }
+
+    /**
+     * java.lang.Integer#equals(java.lang.Object)
+     */
+    public void test_equalsLjava_lang_Object2() {
+        // Test for method boolean java.lang.Integer.equals(java.lang.Object)
+        Integer i1 = new Integer(1000);
+        Integer i2 = new Integer(1000);
+        Integer i3 = new Integer(-1000);
+        assertTrue("Equality test failed", i1.equals(i2) && !(i1.equals(i3)));
+    }
+
+    /**
+     * java.lang.Integer#floatValue()
+     */
+    public void test_floatValue2() {
+        // Test for method float java.lang.Integer.floatValue()
+        assertTrue("Returned incorrect float value", new Integer(65535)
+                .floatValue() == 65535.0f);
+        assertTrue("Returned incorrect float value", new Integer(-65535)
+                .floatValue() == -65535.0f);
+    }
+
+    /**
+     * java.lang.Integer#getInteger(java.lang.String)
+     */
+    public void test_getIntegerLjava_lang_String() {
+        // Test for method java.lang.Integer
+        // java.lang.Integer.getInteger(java.lang.String)
+        Properties tProps = new Properties();
+        tProps.put("testInt", "99");
+        System.setProperties(tProps);
+        assertTrue("returned incorrect Integer", Integer.getInteger("testInt")
+                .equals(new Integer(99)));
+        assertNull("returned incorrect default Integer", Integer
+                .getInteger("ff"));
+    }
+
+    /**
+     * java.lang.Integer#getInteger(java.lang.String, int)
+     */
+    public void test_getIntegerLjava_lang_StringI() {
+        // Test for method java.lang.Integer
+        // java.lang.Integer.getInteger(java.lang.String, int)
+        Properties tProps = new Properties();
+        tProps.put("testInt", "99");
+        System.setProperties(tProps);
+        assertTrue("returned incorrect Integer", Integer.getInteger("testInt",
+                4).equals(new Integer(99)));
+        assertTrue("returned incorrect default Integer", Integer.getInteger(
+                "ff", 4).equals(new Integer(4)));
+    }
+
+    /**
+     * java.lang.Integer#getInteger(java.lang.String, java.lang.Integer)
+     */
+    public void test_getIntegerLjava_lang_StringLjava_lang_Integer() {
+        // Test for method java.lang.Integer
+        // java.lang.Integer.getInteger(java.lang.String, java.lang.Integer)
+        Properties tProps = new Properties();
+        tProps.put("testInt", "99");
+        System.setProperties(tProps);
+        assertTrue("returned incorrect Integer", Integer.getInteger("testInt",
+                new Integer(4)).equals(new Integer(99)));
+        assertTrue("returned incorrect default Integer", Integer.getInteger(
+                "ff", new Integer(4)).equals(new Integer(4)));
+    }
+
+    /**
+     * java.lang.Integer#hashCode()
+     */
+    public void test_hashCode2() {
+        // Test for method int java.lang.Integer.hashCode()
+
+        Integer i1 = new Integer(1000);
+        Integer i2 = new Integer(-1000);
+        assertTrue("Returned incorrect hashcode", i1.hashCode() == 1000
+                && (i2.hashCode() == -1000));
+    }
+
+    /**
+     * java.lang.Integer#intValue()
+     */
+    public void test_intValue2() {
+        // Test for method int java.lang.Integer.intValue()
+
+        Integer i = new Integer(8900);
+        assertEquals("Returned incorrect int value", 8900, i.intValue());
+    }
+
+    /**
+     * java.lang.Integer#longValue()
+     */
+    public void test_longValue2() {
+        // Test for method long java.lang.Integer.longValue()
+        Integer i = new Integer(8900);
+        assertEquals("Returned incorrect long value", 8900L, i.longValue());
+    }
+
+    /**
+     * java.lang.Integer#parseInt(java.lang.String)
+     */
+    public void test_parseIntLjava_lang_String2() {
+        // Test for method int java.lang.Integer.parseInt(java.lang.String)
+
+        int i = Integer.parseInt("-8900");
+        assertEquals("Returned incorrect int", -8900, i);
+        assertEquals("Returned incorrect value for 0", 0, Integer.parseInt("0"));
+        assertTrue("Returned incorrect value for most negative value", Integer
+                .parseInt("-2147483648") == 0x80000000);
+        assertTrue("Returned incorrect value for most positive value", Integer
+                .parseInt("2147483647") == 0x7fffffff);
+
+        boolean exception = false;
+        try {
+            Integer.parseInt("999999999999");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for value > int", exception);
+
+        exception = false;
+        try {
+            Integer.parseInt("2147483648");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for MAX_VALUE + 1", exception);
+
+        exception = false;
+        try {
+            Integer.parseInt("-2147483649");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for MIN_VALUE - 1", exception);
+    }
+
+    /**
+     * java.lang.Integer#parseInt(java.lang.String, int)
+     */
+    public void test_parseIntLjava_lang_StringI2() {
+        // Test for method int java.lang.Integer.parseInt(java.lang.String, int)
+        assertEquals("Parsed dec val incorrectly",
+                -8000, Integer.parseInt("-8000", 10));
+        assertEquals("Parsed hex val incorrectly",
+                255, Integer.parseInt("FF", 16));
+        assertEquals("Parsed oct val incorrectly",
+                16, Integer.parseInt("20", 8));
+        assertEquals("Returned incorrect value for 0 hex", 0, Integer.parseInt("0",
+                16));
+        assertTrue("Returned incorrect value for most negative value hex",
+                Integer.parseInt("-80000000", 16) == 0x80000000);
+        assertTrue("Returned incorrect value for most positive value hex",
+                Integer.parseInt("7fffffff", 16) == 0x7fffffff);
+        assertEquals("Returned incorrect value for 0 decimal", 0, Integer.parseInt(
+                "0", 10));
+        assertTrue("Returned incorrect value for most negative value decimal",
+                Integer.parseInt("-2147483648", 10) == 0x80000000);
+        assertTrue("Returned incorrect value for most positive value decimal",
+                Integer.parseInt("2147483647", 10) == 0x7fffffff);
+
+        boolean exception = false;
+        try {
+            Integer.parseInt("FFFF", 10);
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue(
+                "Failed to throw exception when passes hex string and dec parm",
+                exception);
+
+        exception = false;
+        try {
+            Integer.parseInt("2147483648", 10);
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for MAX_VALUE + 1", exception);
+
+        exception = false;
+        try {
+            Integer.parseInt("-2147483649", 10);
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for MIN_VALUE - 1", exception);
+
+        exception = false;
+        try {
+            Integer.parseInt("80000000", 16);
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for hex MAX_VALUE + 1", exception);
+
+        exception = false;
+        try {
+            Integer.parseInt("-80000001", 16);
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for hex MIN_VALUE + 1", exception);
+
+        exception = false;
+        try {
+            Integer.parseInt("9999999999", 10);
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for 9999999999", exception);
+    }
+
+    /**
+     * java.lang.Integer#shortValue()
+     */
+    public void test_shortValue2() {
+        // Test for method short java.lang.Integer.shortValue()
+        Integer i = new Integer(2147450880);
+        assertEquals("Returned incorrect long value", -32768, i.shortValue());
+    }
+
+    /**
+     * java.lang.Integer#toBinaryString(int)
+     */
+    public void test_toBinaryStringI() {
+        // Test for method java.lang.String
+        // java.lang.Integer.toBinaryString(int)
+        assertEquals("Incorrect string returned", "1111111111111111111111111111111", Integer.toBinaryString(
+                Integer.MAX_VALUE));
+        assertEquals("Incorrect string returned", "10000000000000000000000000000000", Integer.toBinaryString(
+                Integer.MIN_VALUE));
+    }
+
+    /**
+     * java.lang.Integer#toHexString(int)
+     */
+    public void test_toHexStringI() {
+        // Test for method java.lang.String java.lang.Integer.toHexString(int)
+
+        String[] hexvals = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
+                "a", "b", "c", "d", "e", "f" };
+
+        for (int i = 0; i < 16; i++) {
+            assertTrue("Incorrect string returned " + hexvals[i], Integer
+                    .toHexString(i).equals(hexvals[i]));
+        }
+
+        assertTrue("Returned incorrect hex string: "
+                + Integer.toHexString(Integer.MAX_VALUE), Integer.toHexString(
+                Integer.MAX_VALUE).equals("7fffffff"));
+        assertTrue("Returned incorrect hex string: "
+                + Integer.toHexString(Integer.MIN_VALUE), Integer.toHexString(
+                Integer.MIN_VALUE).equals("80000000"));
+    }
+
+    /**
+     * java.lang.Integer#toOctalString(int)
+     */
+    public void test_toOctalStringI() {
+        // Test for method java.lang.String java.lang.Integer.toOctalString(int)
+        // Spec states that the int arg is treated as unsigned
+        assertEquals("Returned incorrect octal string", "17777777777", Integer.toOctalString(
+                Integer.MAX_VALUE));
+        assertEquals("Returned incorrect octal string", "20000000000", Integer.toOctalString(
+                Integer.MIN_VALUE));
+    }
+
+    /**
+     * java.lang.Integer#toString()
+     */
+    public void test_toString2() {
+        // Test for method java.lang.String java.lang.Integer.toString()
+
+        Integer i = new Integer(-80001);
+
+        assertEquals("Returned incorrect String", "-80001", i.toString());
+    }
+
+    /**
+     * java.lang.Integer#toString(int)
+     */
+    public void test_toStringI2() {
+        // Test for method java.lang.String java.lang.Integer.toString(int)
+
+        assertEquals("Returned incorrect String", "-80765", Integer.toString(-80765)
+        );
+        assertEquals("Returned incorrect octal string", "2147483647", Integer.toString(
+                Integer.MAX_VALUE));
+        assertEquals("Returned incorrect octal string", "-2147483647", Integer.toString(
+                -Integer.MAX_VALUE));
+        assertEquals("Returned incorrect octal string", "-2147483648", Integer.toString(
+                Integer.MIN_VALUE));
+
+        // Test for HARMONY-6068
+        assertEquals("Returned incorrect octal String", "-1000", Integer.toString(-1000));
+        assertEquals("Returned incorrect octal String", "1000", Integer.toString(1000));
+        assertEquals("Returned incorrect octal String", "0", Integer.toString(0));
+        assertEquals("Returned incorrect octal String", "708", Integer.toString(708));
+        assertEquals("Returned incorrect octal String", "-100", Integer.toString(-100));
+        assertEquals("Returned incorrect octal String", "-1000000008", Integer.toString(-1000000008));
+        assertEquals("Returned incorrect octal String", "2000000008", Integer.toString(2000000008));
+    }
+
+    /**
+     * java.lang.Integer#toString(int, int)
+     */
+    public void test_toStringII() {
+        // Test for method java.lang.String java.lang.Integer.toString(int, int)
+        assertEquals("Returned incorrect octal string", "17777777777", Integer.toString(
+                2147483647, 8));
+        assertTrue("Returned incorrect hex string--wanted 7fffffff but got: "
+                + Integer.toString(2147483647, 16), Integer.toString(
+                2147483647, 16).equals("7fffffff"));
+        assertEquals("Incorrect string returned", "1111111111111111111111111111111", Integer.toString(2147483647, 2)
+        );
+        assertEquals("Incorrect string returned", "2147483647", Integer
+                .toString(2147483647, 10));
+
+        assertEquals("Returned incorrect octal string", "-17777777777", Integer.toString(
+                -2147483647, 8));
+        assertTrue("Returned incorrect hex string--wanted -7fffffff but got: "
+                + Integer.toString(-2147483647, 16), Integer.toString(
+                -2147483647, 16).equals("-7fffffff"));
+        assertEquals("Incorrect string returned",
+                "-1111111111111111111111111111111", Integer
+                .toString(-2147483647, 2));
+        assertEquals("Incorrect string returned", "-2147483647", Integer.toString(-2147483647,
+                10));
+
+        assertEquals("Returned incorrect octal string", "-20000000000", Integer.toString(
+                -2147483648, 8));
+        assertTrue("Returned incorrect hex string--wanted -80000000 but got: "
+                + Integer.toString(-2147483648, 16), Integer.toString(
+                -2147483648, 16).equals("-80000000"));
+        assertEquals("Incorrect string returned",
+                "-10000000000000000000000000000000", Integer
+                .toString(-2147483648, 2));
+        assertEquals("Incorrect string returned", "-2147483648", Integer.toString(-2147483648,
+                10));
+    }
+
+    /**
+     * java.lang.Integer#valueOf(java.lang.String)
+     */
+    public void test_valueOfLjava_lang_String2() {
+        // Test for method java.lang.Integer
+        // java.lang.Integer.valueOf(java.lang.String)
+        assertEquals("Returned incorrect int", 8888888, Integer.valueOf("8888888")
+                .intValue());
+        assertTrue("Returned incorrect int", Integer.valueOf("2147483647")
+                .intValue() == Integer.MAX_VALUE);
+        assertTrue("Returned incorrect int", Integer.valueOf("-2147483648")
+                .intValue() == Integer.MIN_VALUE);
+
+        boolean exception = false;
+        try {
+            Integer.valueOf("2147483648");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception with MAX_VALUE + 1", exception);
+
+        exception = false;
+        try {
+            Integer.valueOf("-2147483649");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception with MIN_VALUE - 1", exception);
+    }
+
+    /**
+     * java.lang.Integer#valueOf(java.lang.String, int)
+     */
+    public void test_valueOfLjava_lang_StringI2() {
+        // Test for method java.lang.Integer
+        // java.lang.Integer.valueOf(java.lang.String, int)
+        assertEquals("Returned incorrect int for hex string", 255, Integer.valueOf(
+                "FF", 16).intValue());
+        assertEquals("Returned incorrect int for oct string", 16, Integer.valueOf(
+                "20", 8).intValue());
+        assertEquals("Returned incorrect int for bin string", 4, Integer.valueOf(
+                "100", 2).intValue());
+
+        assertEquals("Returned incorrect int for - hex string", -255, Integer.valueOf(
+                "-FF", 16).intValue());
+        assertEquals("Returned incorrect int for - oct string", -16, Integer.valueOf(
+                "-20", 8).intValue());
+        assertEquals("Returned incorrect int for - bin string", -4, Integer.valueOf(
+                "-100", 2).intValue());
+        assertTrue("Returned incorrect int", Integer.valueOf("2147483647", 10)
+                .intValue() == Integer.MAX_VALUE);
+        assertTrue("Returned incorrect int", Integer.valueOf("-2147483648", 10)
+                .intValue() == Integer.MIN_VALUE);
+        assertTrue("Returned incorrect int", Integer.valueOf("7fffffff", 16)
+                .intValue() == Integer.MAX_VALUE);
+        assertTrue("Returned incorrect int", Integer.valueOf("-80000000", 16)
+                .intValue() == Integer.MIN_VALUE);
+
+        boolean exception = false;
+        try {
+            Integer.valueOf("FF", 2);
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue(
+                "Failed to throw exception with hex string and base 2 radix",
+                exception);
+
+        exception = false;
+        try {
+            Integer.valueOf("2147483648", 10);
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception with MAX_VALUE + 1", exception);
+
+        exception = false;
+        try {
+            Integer.valueOf("-2147483649", 10);
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception with MIN_VALUE - 1", exception);
+
+        exception = false;
+        try {
+            Integer.valueOf("80000000", 16);
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception with hex MAX_VALUE + 1",
+                exception);
+
+        exception = false;
+        try {
+            Integer.valueOf("-80000001", 16);
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception with hex MIN_VALUE - 1",
+                exception);
+    }
+
+    /**
+     * java.lang.Integer#valueOf(byte)
+     */
+    public void test_valueOfI() {
+        assertEquals(new Integer(Integer.MIN_VALUE), Integer.valueOf(Integer.MIN_VALUE));
+        assertEquals(new Integer(Integer.MAX_VALUE), Integer.valueOf(Integer.MAX_VALUE));
+        assertEquals(new Integer(0), Integer.valueOf(0));
+
+        short s = -128;
+        while (s < 128) {
+            assertEquals(new Integer(s), Integer.valueOf(s));
+            assertSame(Integer.valueOf(s), Integer.valueOf(s));
+            s++;
+        }
+    }
+
+    /**
+     * java.lang.Integer#hashCode()
+     */
+    public void test_hashCode() {
+        assertEquals(1, new Integer(1).hashCode());
+        assertEquals(2, new Integer(2).hashCode());
+        assertEquals(0, new Integer(0).hashCode());
+        assertEquals(-1, new Integer(-1).hashCode());
+    }
+
+    /**
+     * java.lang.Integer#Integer(String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        assertEquals(new Integer(0), new Integer("0"));
+        assertEquals(new Integer(1), new Integer("1"));
+        assertEquals(new Integer(-1), new Integer("-1"));
+
+        try {
+            new Integer("0x1");
+            fail("Expected NumberFormatException with hex string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            new Integer("9.2");
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            new Integer("");
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            new Integer(null);
+            fail("Expected NumberFormatException with null string.");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Integer#Integer
+     */
+    public void test_ConstructorI() {
+        assertEquals(1, new Integer(1).intValue());
+        assertEquals(2, new Integer(2).intValue());
+        assertEquals(0, new Integer(0).intValue());
+        assertEquals(-1, new Integer(-1).intValue());
+
+        Integer i = new Integer(-89000);
+        assertEquals("Incorrect Integer created", -89000, i.intValue());
+    }
+
+    /**
+     * java.lang.Integer#byteValue()
+     */
+    public void test_booleanValue() {
+        assertEquals(1, new Integer(1).byteValue());
+        assertEquals(2, new Integer(2).byteValue());
+        assertEquals(0, new Integer(0).byteValue());
+        assertEquals(-1, new Integer(-1).byteValue());
+    }
+
+    /**
+     * java.lang.Integer#equals(Object)
+     */
+    public void test_equalsLjava_lang_Object() {
+        assertEquals(new Integer(0), Integer.valueOf(0));
+        assertEquals(new Integer(1), Integer.valueOf(1));
+        assertEquals(new Integer(-1), Integer.valueOf(-1));
+
+        Integer fixture = new Integer(25);
+        assertEquals(fixture, fixture);
+        assertFalse(fixture.equals(null));
+        assertFalse(fixture.equals("Not a Integer"));
+    }
+
+    /**
+     * java.lang.Integer#toString()
+     */
+    public void test_toString() {
+        assertEquals("-1", new Integer(-1).toString());
+        assertEquals("0", new Integer(0).toString());
+        assertEquals("1", new Integer(1).toString());
+        assertEquals("-1", new Integer(0xFFFFFFFF).toString());
+    }
+
+    /**
+     * java.lang.Integer#toString
+     */
+    public void test_toStringI() {
+        assertEquals("-1", Integer.toString(-1));
+        assertEquals("0", Integer.toString(0));
+        assertEquals("1", Integer.toString(1));
+        assertEquals("-1", Integer.toString(0xFFFFFFFF));
+    }
+
+    /**
+     * java.lang.Integer#valueOf(String)
+     */
+    public void test_valueOfLjava_lang_String() {
+        assertEquals(new Integer(0), Integer.valueOf("0"));
+        assertEquals(new Integer(1), Integer.valueOf("1"));
+        assertEquals(new Integer(-1), Integer.valueOf("-1"));
+
+        try {
+            Integer.valueOf("0x1");
+            fail("Expected NumberFormatException with hex string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Integer.valueOf("9.2");
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Integer.valueOf("");
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Integer.valueOf(null);
+            fail("Expected NumberFormatException with null string.");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Integer#valueOf(String, int)
+     */
+    public void test_valueOfLjava_lang_StringI() {
+        assertEquals(new Integer(0), Integer.valueOf("0", 10));
+        assertEquals(new Integer(1), Integer.valueOf("1", 10));
+        assertEquals(new Integer(-1), Integer.valueOf("-1", 10));
+
+        //must be consistent with Character.digit()
+        assertEquals(Character.digit('1', 2), Integer.valueOf("1", 2).byteValue());
+        assertEquals(Character.digit('F', 16), Integer.valueOf("F", 16).byteValue());
+
+        try {
+            Integer.valueOf("0x1", 10);
+            fail("Expected NumberFormatException with hex string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Integer.valueOf("9.2", 10);
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Integer.valueOf("", 10);
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Integer.valueOf(null, 10);
+            fail("Expected NumberFormatException with null string.");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Integer#parseInt(String)
+     */
+    public void test_parseIntLjava_lang_String() {
+        assertEquals(0, Integer.parseInt("0"));
+        assertEquals(1, Integer.parseInt("1"));
+        assertEquals(-1, Integer.parseInt("-1"));
+
+        try {
+            Integer.parseInt("0x1");
+            fail("Expected NumberFormatException with hex string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Integer.parseInt("9.2");
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Integer.parseInt("");
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Integer.parseInt(null);
+            fail("Expected NumberFormatException with null string.");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Integer#parseInt(String, int)
+     */
+    public void test_parseIntLjava_lang_StringI() {
+        assertEquals(0, Integer.parseInt("0", 10));
+        assertEquals(1, Integer.parseInt("1", 10));
+        assertEquals(-1, Integer.parseInt("-1", 10));
+
+        //must be consistent with Character.digit()
+        assertEquals(Character.digit('1', 2), Integer.parseInt("1", 2));
+        assertEquals(Character.digit('F', 16), Integer.parseInt("F", 16));
+
+        try {
+            Integer.parseInt("0x1", 10);
+            fail("Expected NumberFormatException with hex string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Integer.parseInt("9.2", 10);
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Integer.parseInt("", 10);
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Integer.parseInt(null, 10);
+            fail("Expected NumberFormatException with null string.");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Integer#decode(String)
+     */
+    public void test_decodeLjava_lang_String() {
+        assertEquals(new Integer(0), Integer.decode("0"));
+        assertEquals(new Integer(1), Integer.decode("1"));
+        assertEquals(new Integer(-1), Integer.decode("-1"));
+        assertEquals(new Integer(0xF), Integer.decode("0xF"));
+        assertEquals(new Integer(0xF), Integer.decode("#F"));
+        assertEquals(new Integer(0xF), Integer.decode("0XF"));
+        assertEquals(new Integer(07), Integer.decode("07"));
+
+        try {
+            Integer.decode("9.2");
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Integer.decode("");
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Integer.decode(null);
+            //undocumented NPE, but seems consistent across JREs
+            fail("Expected NullPointerException with null string.");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    /**
+     * java.lang.Integer#doubleValue()
+     */
+    public void test_doubleValue() {
+        assertEquals(-1D, new Integer(-1).doubleValue(), 0D);
+        assertEquals(0D, new Integer(0).doubleValue(), 0D);
+        assertEquals(1D, new Integer(1).doubleValue(), 0D);
+    }
+
+    /**
+     * java.lang.Integer#floatValue()
+     */
+    public void test_floatValue() {
+        assertEquals(-1F, new Integer(-1).floatValue(), 0F);
+        assertEquals(0F, new Integer(0).floatValue(), 0F);
+        assertEquals(1F, new Integer(1).floatValue(), 0F);
+    }
+
+    /**
+     * java.lang.Integer#intValue()
+     */
+    public void test_intValue() {
+        assertEquals(-1, new Integer(-1).intValue());
+        assertEquals(0, new Integer(0).intValue());
+        assertEquals(1, new Integer(1).intValue());
+    }
+
+    /**
+     * java.lang.Integer#longValue()
+     */
+    public void test_longValue() {
+        assertEquals(-1L, new Integer(-1).longValue());
+        assertEquals(0L, new Integer(0).longValue());
+        assertEquals(1L, new Integer(1).longValue());
+    }
+
+    /**
+     * java.lang.Integer#shortValue()
+     */
+    public void test_shortValue() {
+        assertEquals(-1, new Integer(-1).shortValue());
+        assertEquals(0, new Integer(0).shortValue());
+        assertEquals(1, new Integer(1).shortValue());
+    }
+
+    /**
+     * java.lang.Integer#highestOneBit(int)
+     */
+    public void test_highestOneBitI() {
+        assertEquals(0x08, Integer.highestOneBit(0x0A));
+        assertEquals(0x08, Integer.highestOneBit(0x0B));
+        assertEquals(0x08, Integer.highestOneBit(0x0C));
+        assertEquals(0x08, Integer.highestOneBit(0x0F));
+        assertEquals(0x80, Integer.highestOneBit(0xFF));
+
+        assertEquals(0x080000, Integer.highestOneBit(0x0F1234));
+        assertEquals(0x800000, Integer.highestOneBit(0xFF9977));
+
+        assertEquals(0x80000000, Integer.highestOneBit(0xFFFFFFFF));
+
+        assertEquals(0, Integer.highestOneBit(0));
+        assertEquals(1, Integer.highestOneBit(1));
+        assertEquals(0x80000000, Integer.highestOneBit(-1));
+    }
+
+    /**
+     * java.lang.Integer#lowestOneBit(int)
+     */
+    public void test_lowestOneBitI() {
+        assertEquals(0x10, Integer.lowestOneBit(0xF0));
+
+        assertEquals(0x10, Integer.lowestOneBit(0x90));
+        assertEquals(0x10, Integer.lowestOneBit(0xD0));
+
+        assertEquals(0x10, Integer.lowestOneBit(0x123490));
+        assertEquals(0x10, Integer.lowestOneBit(0x1234D0));
+
+        assertEquals(0x100000, Integer.lowestOneBit(0x900000));
+        assertEquals(0x100000, Integer.lowestOneBit(0xD00000));
+
+        assertEquals(0x40, Integer.lowestOneBit(0x40));
+        assertEquals(0x40, Integer.lowestOneBit(0xC0));
+
+        assertEquals(0x4000, Integer.lowestOneBit(0x4000));
+        assertEquals(0x4000, Integer.lowestOneBit(0xC000));
+
+        assertEquals(0x4000, Integer.lowestOneBit(0x99994000));
+        assertEquals(0x4000, Integer.lowestOneBit(0x9999C000));
+
+        assertEquals(0, Integer.lowestOneBit(0));
+        assertEquals(1, Integer.lowestOneBit(1));
+        assertEquals(1, Integer.lowestOneBit(-1));
+    }
+
+    /**
+     * java.lang.Integer#numberOfLeadingZeros(int)
+     */
+    public void test_numberOfLeadingZerosI() {
+        assertEquals(32, Integer.numberOfLeadingZeros(0x0));
+        assertEquals(31, Integer.numberOfLeadingZeros(0x1));
+        assertEquals(30, Integer.numberOfLeadingZeros(0x2));
+        assertEquals(30, Integer.numberOfLeadingZeros(0x3));
+        assertEquals(29, Integer.numberOfLeadingZeros(0x4));
+        assertEquals(29, Integer.numberOfLeadingZeros(0x5));
+        assertEquals(29, Integer.numberOfLeadingZeros(0x6));
+        assertEquals(29, Integer.numberOfLeadingZeros(0x7));
+        assertEquals(28, Integer.numberOfLeadingZeros(0x8));
+        assertEquals(28, Integer.numberOfLeadingZeros(0x9));
+        assertEquals(28, Integer.numberOfLeadingZeros(0xA));
+        assertEquals(28, Integer.numberOfLeadingZeros(0xB));
+        assertEquals(28, Integer.numberOfLeadingZeros(0xC));
+        assertEquals(28, Integer.numberOfLeadingZeros(0xD));
+        assertEquals(28, Integer.numberOfLeadingZeros(0xE));
+        assertEquals(28, Integer.numberOfLeadingZeros(0xF));
+        assertEquals(27, Integer.numberOfLeadingZeros(0x10));
+        assertEquals(24, Integer.numberOfLeadingZeros(0x80));
+        assertEquals(24, Integer.numberOfLeadingZeros(0xF0));
+        assertEquals(23, Integer.numberOfLeadingZeros(0x100));
+        assertEquals(20, Integer.numberOfLeadingZeros(0x800));
+        assertEquals(20, Integer.numberOfLeadingZeros(0xF00));
+        assertEquals(19, Integer.numberOfLeadingZeros(0x1000));
+        assertEquals(16, Integer.numberOfLeadingZeros(0x8000));
+        assertEquals(16, Integer.numberOfLeadingZeros(0xF000));
+        assertEquals(15, Integer.numberOfLeadingZeros(0x10000));
+        assertEquals(12, Integer.numberOfLeadingZeros(0x80000));
+        assertEquals(12, Integer.numberOfLeadingZeros(0xF0000));
+        assertEquals(11, Integer.numberOfLeadingZeros(0x100000));
+        assertEquals(8, Integer.numberOfLeadingZeros(0x800000));
+        assertEquals(8, Integer.numberOfLeadingZeros(0xF00000));
+        assertEquals(7, Integer.numberOfLeadingZeros(0x1000000));
+        assertEquals(4, Integer.numberOfLeadingZeros(0x8000000));
+        assertEquals(4, Integer.numberOfLeadingZeros(0xF000000));
+        assertEquals(3, Integer.numberOfLeadingZeros(0x10000000));
+        assertEquals(0, Integer.numberOfLeadingZeros(0x80000000));
+        assertEquals(0, Integer.numberOfLeadingZeros(0xF0000000));
+
+        assertEquals(1, Integer.numberOfLeadingZeros(Integer.MAX_VALUE));
+        assertEquals(0, Integer.numberOfLeadingZeros(Integer.MIN_VALUE));
+    }
+
+    /**
+     * java.lang.Integer#numberOfTrailingZeros(int)
+     */
+    public void test_numberOfTrailingZerosI() {
+        assertEquals(32, Integer.numberOfTrailingZeros(0x0));
+        assertEquals(31, Integer.numberOfTrailingZeros(Integer.MIN_VALUE));
+        assertEquals(0, Integer.numberOfTrailingZeros(Integer.MAX_VALUE));
+
+        assertEquals(0, Integer.numberOfTrailingZeros(0x1));
+        assertEquals(3, Integer.numberOfTrailingZeros(0x8));
+        assertEquals(0, Integer.numberOfTrailingZeros(0xF));
+
+        assertEquals(4, Integer.numberOfTrailingZeros(0x10));
+        assertEquals(7, Integer.numberOfTrailingZeros(0x80));
+        assertEquals(4, Integer.numberOfTrailingZeros(0xF0));
+
+        assertEquals(8, Integer.numberOfTrailingZeros(0x100));
+        assertEquals(11, Integer.numberOfTrailingZeros(0x800));
+        assertEquals(8, Integer.numberOfTrailingZeros(0xF00));
+
+        assertEquals(12, Integer.numberOfTrailingZeros(0x1000));
+        assertEquals(15, Integer.numberOfTrailingZeros(0x8000));
+        assertEquals(12, Integer.numberOfTrailingZeros(0xF000));
+
+        assertEquals(16, Integer.numberOfTrailingZeros(0x10000));
+        assertEquals(19, Integer.numberOfTrailingZeros(0x80000));
+        assertEquals(16, Integer.numberOfTrailingZeros(0xF0000));
+
+        assertEquals(20, Integer.numberOfTrailingZeros(0x100000));
+        assertEquals(23, Integer.numberOfTrailingZeros(0x800000));
+        assertEquals(20, Integer.numberOfTrailingZeros(0xF00000));
+
+        assertEquals(24, Integer.numberOfTrailingZeros(0x1000000));
+        assertEquals(27, Integer.numberOfTrailingZeros(0x8000000));
+        assertEquals(24, Integer.numberOfTrailingZeros(0xF000000));
+
+        assertEquals(28, Integer.numberOfTrailingZeros(0x10000000));
+        assertEquals(31, Integer.numberOfTrailingZeros(0x80000000));
+        assertEquals(28, Integer.numberOfTrailingZeros(0xF0000000));
+    }
+
+    /**
+     * java.lang.Integer#bitCount(int)
+     */
+    public void test_bitCountI() {
+        assertEquals(0, Integer.bitCount(0x0));
+        assertEquals(1, Integer.bitCount(0x1));
+        assertEquals(1, Integer.bitCount(0x2));
+        assertEquals(2, Integer.bitCount(0x3));
+        assertEquals(1, Integer.bitCount(0x4));
+        assertEquals(2, Integer.bitCount(0x5));
+        assertEquals(2, Integer.bitCount(0x6));
+        assertEquals(3, Integer.bitCount(0x7));
+        assertEquals(1, Integer.bitCount(0x8));
+        assertEquals(2, Integer.bitCount(0x9));
+        assertEquals(2, Integer.bitCount(0xA));
+        assertEquals(3, Integer.bitCount(0xB));
+        assertEquals(2, Integer.bitCount(0xC));
+        assertEquals(3, Integer.bitCount(0xD));
+        assertEquals(3, Integer.bitCount(0xE));
+        assertEquals(4, Integer.bitCount(0xF));
+
+        assertEquals(8, Integer.bitCount(0xFF));
+        assertEquals(12, Integer.bitCount(0xFFF));
+        assertEquals(16, Integer.bitCount(0xFFFF));
+        assertEquals(20, Integer.bitCount(0xFFFFF));
+        assertEquals(24, Integer.bitCount(0xFFFFFF));
+        assertEquals(28, Integer.bitCount(0xFFFFFFF));
+        assertEquals(32, Integer.bitCount(0xFFFFFFFF));
+    }
+
+    /**
+     * java.lang.Integer#rotateLeft(int, int)
+     */
+    public void test_rotateLeftII() {
+        assertEquals(0xF, Integer.rotateLeft(0xF, 0));
+        assertEquals(0xF0, Integer.rotateLeft(0xF, 4));
+        assertEquals(0xF00, Integer.rotateLeft(0xF, 8));
+        assertEquals(0xF000, Integer.rotateLeft(0xF, 12));
+        assertEquals(0xF0000, Integer.rotateLeft(0xF, 16));
+        assertEquals(0xF00000, Integer.rotateLeft(0xF, 20));
+        assertEquals(0xF000000, Integer.rotateLeft(0xF, 24));
+        assertEquals(0xF0000000, Integer.rotateLeft(0xF, 28));
+        assertEquals(0xF0000000, Integer.rotateLeft(0xF0000000, 32));
+    }
+
+    /**
+     * java.lang.Integer#rotateRight(int, int)
+     */
+    public void test_rotateRightII() {
+        assertEquals(0xF, Integer.rotateRight(0xF0, 4));
+        assertEquals(0xF, Integer.rotateRight(0xF00, 8));
+        assertEquals(0xF, Integer.rotateRight(0xF000, 12));
+        assertEquals(0xF, Integer.rotateRight(0xF0000, 16));
+        assertEquals(0xF, Integer.rotateRight(0xF00000, 20));
+        assertEquals(0xF, Integer.rotateRight(0xF000000, 24));
+        assertEquals(0xF, Integer.rotateRight(0xF0000000, 28));
+        assertEquals(0xF0000000, Integer.rotateRight(0xF0000000, 32));
+        assertEquals(0xF0000000, Integer.rotateRight(0xF0000000, 0));
+
+    }
+
+    /**
+     * java.lang.Integer#reverseBytes(int)
+     */
+    public void test_reverseBytesI() {
+        assertEquals(0xAABBCCDD, Integer.reverseBytes(0xDDCCBBAA));
+        assertEquals(0x11223344, Integer.reverseBytes(0x44332211));
+        assertEquals(0x00112233, Integer.reverseBytes(0x33221100));
+        assertEquals(0x20000002, Integer.reverseBytes(0x02000020));
+    }
+
+    /**
+     * java.lang.Integer#reverse(int)
+     */
+    public void test_reverseI() {
+        assertEquals(-1, Integer.reverse(-1));
+        assertEquals(0x80000000, Integer.reverse(1));
+    }
+
+    /**
+     * java.lang.Integer#signum(int)
+     */
+    public void test_signumI() {
+        for (int i = -128; i < 0; i++) {
+            assertEquals(-1, Integer.signum(i));
+        }
+        assertEquals(0, Integer.signum(0));
+        for (int i = 1; i <= 127; i++) {
+            assertEquals(1, Integer.signum(i));
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/InternalErrorTest.java b/luni/src/test/java/tests/api/java/lang/InternalErrorTest.java
new file mode 100644
index 0000000..fff163a
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/InternalErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class InternalErrorTest extends TestCase {
+
+    /**
+     * java.lang.InternalError#InternalError()
+     */
+    public void test_Constructor() {
+        InternalError e = new InternalError();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.InternalError#InternalError(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        InternalError e = new InternalError("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/InterruptedExceptionTest.java b/luni/src/test/java/tests/api/java/lang/InterruptedExceptionTest.java
new file mode 100644
index 0000000..47066b7
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/InterruptedExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class InterruptedExceptionTest extends TestCase {
+
+    /**
+     * java.lang.InterruptedException#InterruptedException()
+     */
+    public void test_Constructor() {
+        InterruptedException e = new InterruptedException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.InterruptedException#InterruptedException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        InterruptedException e = new InterruptedException("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/LinkageErrorTest.java b/luni/src/test/java/tests/api/java/lang/LinkageErrorTest.java
new file mode 100644
index 0000000..efd27f5
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/LinkageErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class LinkageErrorTest extends TestCase {
+
+    /**
+     * java.lang.LinkageError#LinkageError()
+     */
+    public void test_Constructor() {
+        LinkageError e = new LinkageError();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.LinkageError#LinkageError(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        LinkageError e = new LinkageError("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/LongTest.java b/luni/src/test/java/tests/api/java/lang/LongTest.java
new file mode 100644
index 0000000..2a1d082
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/LongTest.java
@@ -0,0 +1,1067 @@
+/* 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.lang;
+
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+public class LongTest extends TestCase {
+    private Properties orgProps;
+
+    @Override
+    protected void setUp() {
+        orgProps = System.getProperties();
+    }
+
+    @Override
+    protected void tearDown() {
+        System.setProperties(orgProps);
+    }
+
+    /**
+     * java.lang.Long#byteValue()
+     */
+    public void test_byteValue() {
+        // Test for method byte java.lang.Long.byteValue()
+        Long l = new Long(127);
+        assertEquals("Returned incorrect byte value", 127, l.byteValue());
+        assertEquals("Returned incorrect byte value", -1, new Long(Long.MAX_VALUE)
+                .byteValue());
+    }
+
+    /**
+     * java.lang.Long#compareTo(java.lang.Long)
+     */
+    public void test_compareToLjava_lang_Long() {
+        // Test for method int java.lang.Long.compareTo(java.lang.Long)
+        assertTrue("-2 compared to 1 gave non-negative answer", new Long(-2L)
+                .compareTo(new Long(1L)) < 0);
+        assertEquals("-2 compared to -2 gave non-zero answer", 0, new Long(-2L)
+                .compareTo(new Long(-2L)));
+        assertTrue("3 compared to 2 gave non-positive answer", new Long(3L)
+                .compareTo(new Long(2L)) > 0);
+
+        try {
+            new Long(0).compareTo(null);
+            fail("No NPE");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    /**
+     * java.lang.Long#decode(java.lang.String)
+     */
+    public void test_decodeLjava_lang_String2() {
+        // Test for method java.lang.Long
+        // java.lang.Long.decode(java.lang.String)
+        assertEquals("Returned incorrect value for hex string", 255L, Long.decode(
+                "0xFF").longValue());
+        assertEquals("Returned incorrect value for dec string", -89000L, Long.decode(
+                "-89000").longValue());
+        assertEquals("Returned incorrect value for 0 decimal", 0, Long.decode("0")
+                .longValue());
+        assertEquals("Returned incorrect value for 0 hex", 0, Long.decode("0x0")
+                .longValue());
+        assertTrue(
+                "Returned incorrect value for most negative value decimal",
+                Long.decode("-9223372036854775808").longValue() == 0x8000000000000000L);
+        assertTrue(
+                "Returned incorrect value for most negative value hex",
+                Long.decode("-0x8000000000000000").longValue() == 0x8000000000000000L);
+        assertTrue(
+                "Returned incorrect value for most positive value decimal",
+                Long.decode("9223372036854775807").longValue() == 0x7fffffffffffffffL);
+        assertTrue(
+                "Returned incorrect value for most positive value hex",
+                Long.decode("0x7fffffffffffffff").longValue() == 0x7fffffffffffffffL);
+        assertTrue("Failed for 07654321765432", Long.decode("07654321765432")
+                .longValue() == 07654321765432l);
+
+        boolean exception = false;
+        try {
+            Long
+                    .decode("999999999999999999999999999999999999999999999999999999");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for value > ilong", exception);
+
+        exception = false;
+        try {
+            Long.decode("9223372036854775808");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for MAX_VALUE + 1", exception);
+
+        exception = false;
+        try {
+            Long.decode("-9223372036854775809");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for MIN_VALUE - 1", exception);
+
+        exception = false;
+        try {
+            Long.decode("0x8000000000000000");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for hex MAX_VALUE + 1", exception);
+
+        exception = false;
+        try {
+            Long.decode("-0x8000000000000001");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for hex MIN_VALUE - 1", exception);
+
+        exception = false;
+        try {
+            Long.decode("42325917317067571199");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for 42325917317067571199",
+                exception);
+    }
+
+    /**
+     * java.lang.Long#getLong(java.lang.String)
+     */
+    public void test_getLongLjava_lang_String() {
+        // Test for method java.lang.Long
+        // java.lang.Long.getLong(java.lang.String)
+        Properties tProps = new Properties();
+        tProps.put("testLong", "99");
+        System.setProperties(tProps);
+        assertTrue("returned incorrect Long", Long.getLong("testLong").equals(
+                new Long(99)));
+        assertNull("returned incorrect default Long",
+                Long.getLong("ff"));
+    }
+
+    /**
+     * java.lang.Long#getLong(java.lang.String, long)
+     */
+    public void test_getLongLjava_lang_StringJ() {
+        // Test for method java.lang.Long
+        // java.lang.Long.getLong(java.lang.String, long)
+        Properties tProps = new Properties();
+        tProps.put("testLong", "99");
+        System.setProperties(tProps);
+        assertTrue("returned incorrect Long", Long.getLong("testLong", 4L)
+                .equals(new Long(99)));
+        assertTrue("returned incorrect default Long", Long.getLong("ff", 4L)
+                .equals(new Long(4)));
+    }
+
+    /**
+     * java.lang.Long#getLong(java.lang.String, java.lang.Long)
+     */
+    public void test_getLongLjava_lang_StringLjava_lang_Long() {
+        // Test for method java.lang.Long
+        // java.lang.Long.getLong(java.lang.String, java.lang.Long)
+        Properties tProps = new Properties();
+        tProps.put("testLong", "99");
+        System.setProperties(tProps);
+        assertTrue("returned incorrect Long", Long.getLong("testLong",
+                new Long(4)).equals(new Long(99)));
+        assertTrue("returned incorrect default Long", Long.getLong("ff",
+                new Long(4)).equals(new Long(4)));
+    }
+
+    /**
+     * java.lang.Long#parseLong(java.lang.String)
+     */
+    public void test_parseLongLjava_lang_String2() {
+        // Test for method long java.lang.Long.parseLong(java.lang.String)
+
+        long l = Long.parseLong("89000000005");
+        assertEquals("Parsed to incorrect long value", 89000000005L, l);
+        assertEquals("Returned incorrect value for 0", 0, Long.parseLong("0"));
+        assertTrue("Returned incorrect value for most negative value", Long
+                .parseLong("-9223372036854775808") == 0x8000000000000000L);
+        assertTrue("Returned incorrect value for most positive value", Long
+                .parseLong("9223372036854775807") == 0x7fffffffffffffffL);
+
+        boolean exception = false;
+        try {
+            Long.parseLong("9223372036854775808");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for MAX_VALUE + 1", exception);
+
+        exception = false;
+        try {
+            Long.parseLong("-9223372036854775809");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for MIN_VALUE - 1", exception);
+    }
+
+    /**
+     * java.lang.Long#parseLong(java.lang.String, int)
+     */
+    public void test_parseLongLjava_lang_StringI() {
+        // Test for method long java.lang.Long.parseLong(java.lang.String, int)
+        assertEquals("Returned incorrect value",
+                100000000L, Long.parseLong("100000000", 10));
+        assertEquals("Returned incorrect value from hex string", 68719476735L, Long.parseLong(
+                "FFFFFFFFF", 16));
+        assertTrue("Returned incorrect value from octal string: "
+                + Long.parseLong("77777777777"), Long.parseLong("77777777777",
+                8) == 8589934591L);
+        assertEquals("Returned incorrect value for 0 hex", 0, Long
+                .parseLong("0", 16));
+        assertTrue("Returned incorrect value for most negative value hex", Long
+                .parseLong("-8000000000000000", 16) == 0x8000000000000000L);
+        assertTrue("Returned incorrect value for most positive value hex", Long
+                .parseLong("7fffffffffffffff", 16) == 0x7fffffffffffffffL);
+        assertEquals("Returned incorrect value for 0 decimal", 0, Long.parseLong(
+                "0", 10));
+        assertTrue(
+                "Returned incorrect value for most negative value decimal",
+                Long.parseLong("-9223372036854775808", 10) == 0x8000000000000000L);
+        assertTrue(
+                "Returned incorrect value for most positive value decimal",
+                Long.parseLong("9223372036854775807", 10) == 0x7fffffffffffffffL);
+
+        boolean exception = false;
+        try {
+            Long.parseLong("999999999999", 8);
+        } catch (NumberFormatException e) {
+            // correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception when passed invalid string",
+                exception);
+
+        exception = false;
+        try {
+            Long.parseLong("9223372036854775808", 10);
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for MAX_VALUE + 1", exception);
+
+        exception = false;
+        try {
+            Long.parseLong("-9223372036854775809", 10);
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for MIN_VALUE - 1", exception);
+
+        exception = false;
+        try {
+            Long.parseLong("8000000000000000", 16);
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for hex MAX_VALUE + 1", exception);
+
+        exception = false;
+        try {
+            Long.parseLong("-8000000000000001", 16);
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for hex MIN_VALUE + 1", exception);
+
+        exception = false;
+        try {
+            Long.parseLong("42325917317067571199", 10);
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for 42325917317067571199",
+                exception);
+    }
+
+    /**
+     * java.lang.Long#toBinaryString(long)
+     */
+    public void test_toBinaryStringJ() {
+        // Test for method java.lang.String java.lang.Long.toBinaryString(long)
+        assertEquals("Incorrect binary string returned", "11011001010010010000", Long.toBinaryString(
+                890000L));
+        assertEquals("Incorrect binary string returned",
+
+                "1000000000000000000000000000000000000000000000000000000000000000", Long
+                .toBinaryString(Long.MIN_VALUE)
+        );
+        assertEquals("Incorrect binary string returned",
+
+                "111111111111111111111111111111111111111111111111111111111111111", Long
+                .toBinaryString(Long.MAX_VALUE)
+        );
+    }
+
+    /**
+     * java.lang.Long#toHexString(long)
+     */
+    public void test_toHexStringJ() {
+        // Test for method java.lang.String java.lang.Long.toHexString(long)
+        assertEquals("Incorrect hex string returned", "54e0845", Long.toHexString(89000005L)
+        );
+        assertEquals("Incorrect hex string returned", "8000000000000000", Long.toHexString(
+                Long.MIN_VALUE));
+        assertEquals("Incorrect hex string returned", "7fffffffffffffff", Long.toHexString(
+                Long.MAX_VALUE));
+    }
+
+    /**
+     * java.lang.Long#toOctalString(long)
+     */
+    public void test_toOctalStringJ() {
+        // Test for method java.lang.String java.lang.Long.toOctalString(long)
+        assertEquals("Returned incorrect oct string", "77777777777", Long.toOctalString(
+                8589934591L));
+        assertEquals("Returned incorrect oct string", "1000000000000000000000", Long.toOctalString(
+                Long.MIN_VALUE));
+        assertEquals("Returned incorrect oct string", "777777777777777777777", Long.toOctalString(
+                Long.MAX_VALUE));
+    }
+
+    /**
+     * java.lang.Long#toString()
+     */
+    public void test_toString2() {
+        // Test for method java.lang.String java.lang.Long.toString()
+        Long l = new Long(89000000005L);
+        assertEquals("Returned incorrect String",
+                "89000000005", l.toString());
+        assertEquals("Returned incorrect String", "-9223372036854775808", new Long(Long.MIN_VALUE)
+                .toString());
+        assertEquals("Returned incorrect String", "9223372036854775807", new Long(Long.MAX_VALUE)
+                .toString());
+    }
+
+    /**
+     * java.lang.Long#toString(long)
+     */
+    public void test_toStringJ2() {
+        // Test for method java.lang.String java.lang.Long.toString(long)
+
+        assertEquals("Returned incorrect String", "89000000005", Long.toString(89000000005L)
+        );
+        assertEquals("Returned incorrect String", "-9223372036854775808", Long.toString(Long.MIN_VALUE)
+        );
+        assertEquals("Returned incorrect String", "9223372036854775807", Long.toString(Long.MAX_VALUE)
+        );
+    }
+
+    /**
+     * java.lang.Long#toString(long, int)
+     */
+    public void test_toStringJI() {
+        // Test for method java.lang.String java.lang.Long.toString(long, int)
+        assertEquals("Returned incorrect dec string", "100000000", Long.toString(100000000L,
+                10));
+        assertEquals("Returned incorrect hex string", "fffffffff", Long.toString(68719476735L,
+                16));
+        assertEquals("Returned incorrect oct string", "77777777777", Long.toString(8589934591L,
+                8));
+        assertEquals("Returned incorrect bin string",
+                "1111111111111111111111111111111111111111111", Long.toString(
+                8796093022207L, 2));
+        assertEquals("Returned incorrect min string", "-9223372036854775808", Long.toString(
+                0x8000000000000000L, 10));
+        assertEquals("Returned incorrect max string", "9223372036854775807", Long.toString(
+                0x7fffffffffffffffL, 10));
+        assertEquals("Returned incorrect min string", "-8000000000000000", Long.toString(
+                0x8000000000000000L, 16));
+        assertEquals("Returned incorrect max string", "7fffffffffffffff", Long.toString(
+                0x7fffffffffffffffL, 16));
+    }
+
+    /**
+     * java.lang.Long#valueOf(java.lang.String)
+     */
+    public void test_valueOfLjava_lang_String2() {
+        // Test for method java.lang.Long
+        // java.lang.Long.valueOf(java.lang.String)
+        assertEquals("Returned incorrect value", 100000000L, Long.valueOf("100000000")
+                .longValue());
+        assertTrue("Returned incorrect value", Long.valueOf(
+                "9223372036854775807").longValue() == Long.MAX_VALUE);
+        assertTrue("Returned incorrect value", Long.valueOf(
+                "-9223372036854775808").longValue() == Long.MIN_VALUE);
+
+        boolean exception = false;
+        try {
+            Long
+                    .valueOf("999999999999999999999999999999999999999999999999999999999999");
+        } catch (NumberFormatException e) {
+            // correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception when passed invalid string",
+                exception);
+
+        exception = false;
+        try {
+            Long.valueOf("9223372036854775808");
+        } catch (NumberFormatException e) {
+            // correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception when passed invalid string",
+                exception);
+
+        exception = false;
+        try {
+            Long.valueOf("-9223372036854775809");
+        } catch (NumberFormatException e) {
+            // correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception when passed invalid string",
+                exception);
+    }
+
+    /**
+     * java.lang.Long#valueOf(java.lang.String, int)
+     */
+    public void test_valueOfLjava_lang_StringI() {
+        // Test for method java.lang.Long
+        // java.lang.Long.valueOf(java.lang.String, int)
+        assertEquals("Returned incorrect value", 100000000L, Long.valueOf("100000000", 10)
+                .longValue());
+        assertEquals("Returned incorrect value from hex string", 68719476735L, Long.valueOf(
+                "FFFFFFFFF", 16).longValue());
+        assertTrue("Returned incorrect value from octal string: "
+                + Long.valueOf("77777777777", 8).toString(), Long.valueOf(
+                "77777777777", 8).longValue() == 8589934591L);
+        assertTrue("Returned incorrect value", Long.valueOf(
+                "9223372036854775807", 10).longValue() == Long.MAX_VALUE);
+        assertTrue("Returned incorrect value", Long.valueOf(
+                "-9223372036854775808", 10).longValue() == Long.MIN_VALUE);
+        assertTrue("Returned incorrect value", Long.valueOf("7fffffffffffffff",
+                16).longValue() == Long.MAX_VALUE);
+        assertTrue("Returned incorrect value", Long.valueOf(
+                "-8000000000000000", 16).longValue() == Long.MIN_VALUE);
+
+        boolean exception = false;
+        try {
+            Long.valueOf("999999999999", 8);
+        } catch (NumberFormatException e) {
+            // correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception when passed invalid string",
+                exception);
+
+        exception = false;
+        try {
+            Long.valueOf("9223372036854775808", 10);
+        } catch (NumberFormatException e) {
+            // correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception when passed invalid string",
+                exception);
+
+        exception = false;
+        try {
+            Long.valueOf("-9223372036854775809", 10);
+        } catch (NumberFormatException e) {
+            // correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception when passed invalid string",
+                exception);
+    }
+
+    /**
+     * java.lang.Long#valueOf(long)
+     */
+    public void test_valueOfJ() {
+        assertEquals(new Long(Long.MIN_VALUE), Long.valueOf(Long.MIN_VALUE));
+        assertEquals(new Long(Long.MAX_VALUE), Long.valueOf(Long.MAX_VALUE));
+        assertEquals(new Long(0), Long.valueOf(0));
+
+        long lng = -128;
+        while (lng < 128) {
+            assertEquals(new Long(lng), Long.valueOf(lng));
+            assertSame(Long.valueOf(lng), Long.valueOf(lng));
+            lng++;
+        }
+    }
+
+    /**
+     * java.lang.Long#hashCode()
+     */
+    public void test_hashCode() {
+        assertEquals((int) (1L ^ (1L >>> 32)), new Long(1).hashCode());
+        assertEquals((int) (2L ^ (2L >>> 32)), new Long(2).hashCode());
+        assertEquals((int) (0L ^ (0L >>> 32)), new Long(0).hashCode());
+        assertEquals((int) (-1L ^ (-1L >>> 32)), new Long(-1).hashCode());
+    }
+
+    /**
+     * java.lang.Long#Long(String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        assertEquals(new Long(0), new Long("0"));
+        assertEquals(new Long(1), new Long("1"));
+        assertEquals(new Long(-1), new Long("-1"));
+
+        try {
+            new Long("0x1");
+            fail("Expected NumberFormatException with hex string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            new Long("9.2");
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            new Long("");
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            new Long(null);
+            fail("Expected NumberFormatException with null string.");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Long#Long
+     */
+    public void test_ConstructorJ() {
+        assertEquals(1, new Long(1).intValue());
+        assertEquals(2, new Long(2).intValue());
+        assertEquals(0, new Long(0).intValue());
+        assertEquals(-1, new Long(-1).intValue());
+    }
+
+    /**
+     * java.lang.Long#byteValue()
+     */
+    public void test_booleanValue() {
+        assertEquals(1, new Long(1).byteValue());
+        assertEquals(2, new Long(2).byteValue());
+        assertEquals(0, new Long(0).byteValue());
+        assertEquals(-1, new Long(-1).byteValue());
+    }
+
+    /**
+     * java.lang.Long#equals(Object)
+     */
+    public void test_equalsLjava_lang_Object() {
+        assertEquals(new Long(0), Long.valueOf(0));
+        assertEquals(new Long(1), Long.valueOf(1));
+        assertEquals(new Long(-1), Long.valueOf(-1));
+
+        Long fixture = new Long(25);
+        assertEquals(fixture, fixture);
+        assertFalse(fixture.equals(null));
+        assertFalse(fixture.equals("Not a Long"));
+    }
+
+    /**
+     * java.lang.Long#toString()
+     */
+    public void test_toString() {
+        assertEquals("-1", new Long(-1).toString());
+        assertEquals("0", new Long(0).toString());
+        assertEquals("1", new Long(1).toString());
+        assertEquals("-1", new Long(0xFFFFFFFF).toString());
+    }
+
+    /**
+     * java.lang.Long#toString
+     */
+    public void test_toStringJ() {
+        assertEquals("-1", Long.toString(-1));
+        assertEquals("0", Long.toString(0));
+        assertEquals("1", Long.toString(1));
+        assertEquals("-1", Long.toString(0xFFFFFFFF));
+    }
+
+    /**
+     * java.lang.Long#valueOf(String)
+     */
+    public void test_valueOfLjava_lang_String() {
+        assertEquals(new Long(0), Long.valueOf("0"));
+        assertEquals(new Long(1), Long.valueOf("1"));
+        assertEquals(new Long(-1), Long.valueOf("-1"));
+
+        try {
+            Long.valueOf("0x1");
+            fail("Expected NumberFormatException with hex string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Long.valueOf("9.2");
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Long.valueOf("");
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Long.valueOf(null);
+            fail("Expected NumberFormatException with null string.");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Long#valueOf(String, long)
+     */
+    public void test_valueOfLjava_lang_StringJ() {
+        assertEquals(new Long(0), Long.valueOf("0", 10));
+        assertEquals(new Long(1), Long.valueOf("1", 10));
+        assertEquals(new Long(-1), Long.valueOf("-1", 10));
+
+        //must be consistent with Character.digit()
+        assertEquals(Character.digit('1', 2), Long.valueOf("1", 2).byteValue());
+        assertEquals(Character.digit('F', 16), Long.valueOf("F", 16).byteValue());
+
+        try {
+            Long.valueOf("0x1", 10);
+            fail("Expected NumberFormatException with hex string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Long.valueOf("9.2", 10);
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Long.valueOf("", 10);
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Long.valueOf(null, 10);
+            fail("Expected NumberFormatException with null string.");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Long#parseLong(String)
+     */
+    public void test_parseLongLjava_lang_String() {
+        assertEquals(0, Long.parseLong("0"));
+        assertEquals(1, Long.parseLong("1"));
+        assertEquals(-1, Long.parseLong("-1"));
+
+        try {
+            Long.parseLong("0x1");
+            fail("Expected NumberFormatException with hex string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Long.parseLong("9.2");
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Long.parseLong("");
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Long.parseLong(null);
+            fail("Expected NumberFormatException with null string.");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Long#parseLong(String, long)
+     */
+    public void test_parseLongLjava_lang_StringJ() {
+        assertEquals(0, Long.parseLong("0", 10));
+        assertEquals(1, Long.parseLong("1", 10));
+        assertEquals(-1, Long.parseLong("-1", 10));
+
+        //must be consistent with Character.digit()
+        assertEquals(Character.digit('1', 2), Long.parseLong("1", 2));
+        assertEquals(Character.digit('F', 16), Long.parseLong("F", 16));
+
+        try {
+            Long.parseLong("0x1", 10);
+            fail("Expected NumberFormatException with hex string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Long.parseLong("9.2", 10);
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Long.parseLong("", 10);
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Long.parseLong(null, 10);
+            fail("Expected NumberFormatException with null string.");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Long#decode(String)
+     */
+    public void test_decodeLjava_lang_String() {
+        assertEquals(new Long(0), Long.decode("0"));
+        assertEquals(new Long(1), Long.decode("1"));
+        assertEquals(new Long(-1), Long.decode("-1"));
+        assertEquals(new Long(0xF), Long.decode("0xF"));
+        assertEquals(new Long(0xF), Long.decode("#F"));
+        assertEquals(new Long(0xF), Long.decode("0XF"));
+        assertEquals(new Long(07), Long.decode("07"));
+
+        try {
+            Long.decode("9.2");
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Long.decode("");
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Long.decode(null);
+            //undocumented NPE, but seems consistent across JREs
+            fail("Expected NullPointerException with null string.");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    /**
+     * java.lang.Long#doubleValue()
+     */
+    public void test_doubleValue() {
+        assertEquals(-1D, new Long(-1).doubleValue(), 0D);
+        assertEquals(0D, new Long(0).doubleValue(), 0D);
+        assertEquals(1D, new Long(1).doubleValue(), 0D);
+    }
+
+    /**
+     * java.lang.Long#floatValue()
+     */
+    public void test_floatValue() {
+        assertEquals(-1F, new Long(-1).floatValue(), 0F);
+        assertEquals(0F, new Long(0).floatValue(), 0F);
+        assertEquals(1F, new Long(1).floatValue(), 0F);
+    }
+
+    /**
+     * java.lang.Long#intValue()
+     */
+    public void test_intValue() {
+        assertEquals(-1, new Long(-1).intValue());
+        assertEquals(0, new Long(0).intValue());
+        assertEquals(1, new Long(1).intValue());
+    }
+
+    /**
+     * java.lang.Long#longValue()
+     */
+    public void test_longValue() {
+        assertEquals(-1L, new Long(-1).longValue());
+        assertEquals(0L, new Long(0).longValue());
+        assertEquals(1L, new Long(1).longValue());
+    }
+
+    /**
+     * java.lang.Long#shortValue()
+     */
+    public void test_shortValue() {
+        assertEquals(-1, new Long(-1).shortValue());
+        assertEquals(0, new Long(0).shortValue());
+        assertEquals(1, new Long(1).shortValue());
+    }
+
+    /**
+     * java.lang.Long#highestOneBit(long)
+     */
+    public void test_highestOneBitJ() {
+        assertEquals(0x08, Long.highestOneBit(0x0A));
+        assertEquals(0x08, Long.highestOneBit(0x0B));
+        assertEquals(0x08, Long.highestOneBit(0x0C));
+        assertEquals(0x08, Long.highestOneBit(0x0F));
+        assertEquals(0x80, Long.highestOneBit(0xFF));
+
+        assertEquals(0x080000, Long.highestOneBit(0x0F1234));
+        assertEquals(0x800000, Long.highestOneBit(0xFF9977));
+
+        assertEquals(0x8000000000000000L, Long.highestOneBit(0xFFFFFFFFFFFFFFFFL));
+
+        assertEquals(0, Long.highestOneBit(0));
+        assertEquals(1, Long.highestOneBit(1));
+        assertEquals(0x8000000000000000L, Long.highestOneBit(-1));
+    }
+
+    /**
+     * java.lang.Long#lowestOneBit(long)
+     */
+    public void test_lowestOneBitJ() {
+        assertEquals(0x10, Long.lowestOneBit(0xF0));
+
+        assertEquals(0x10, Long.lowestOneBit(0x90));
+        assertEquals(0x10, Long.lowestOneBit(0xD0));
+
+        assertEquals(0x10, Long.lowestOneBit(0x123490));
+        assertEquals(0x10, Long.lowestOneBit(0x1234D0));
+
+        assertEquals(0x100000, Long.lowestOneBit(0x900000));
+        assertEquals(0x100000, Long.lowestOneBit(0xD00000));
+
+        assertEquals(0x40, Long.lowestOneBit(0x40));
+        assertEquals(0x40, Long.lowestOneBit(0xC0));
+
+        assertEquals(0x4000, Long.lowestOneBit(0x4000));
+        assertEquals(0x4000, Long.lowestOneBit(0xC000));
+
+        assertEquals(0x4000, Long.lowestOneBit(0x99994000));
+        assertEquals(0x4000, Long.lowestOneBit(0x9999C000));
+
+        assertEquals(0, Long.lowestOneBit(0));
+        assertEquals(1, Long.lowestOneBit(1));
+        assertEquals(1, Long.lowestOneBit(-1));
+    }
+
+    /**
+     * java.lang.Long#numberOfLeadingZeros(long)
+     */
+    public void test_numberOfLeadingZerosJ() {
+        assertEquals(64, Long.numberOfLeadingZeros(0x0L));
+        assertEquals(63, Long.numberOfLeadingZeros(0x1));
+        assertEquals(62, Long.numberOfLeadingZeros(0x2));
+        assertEquals(62, Long.numberOfLeadingZeros(0x3));
+        assertEquals(61, Long.numberOfLeadingZeros(0x4));
+        assertEquals(61, Long.numberOfLeadingZeros(0x5));
+        assertEquals(61, Long.numberOfLeadingZeros(0x6));
+        assertEquals(61, Long.numberOfLeadingZeros(0x7));
+        assertEquals(60, Long.numberOfLeadingZeros(0x8));
+        assertEquals(60, Long.numberOfLeadingZeros(0x9));
+        assertEquals(60, Long.numberOfLeadingZeros(0xA));
+        assertEquals(60, Long.numberOfLeadingZeros(0xB));
+        assertEquals(60, Long.numberOfLeadingZeros(0xC));
+        assertEquals(60, Long.numberOfLeadingZeros(0xD));
+        assertEquals(60, Long.numberOfLeadingZeros(0xE));
+        assertEquals(60, Long.numberOfLeadingZeros(0xF));
+        assertEquals(59, Long.numberOfLeadingZeros(0x10));
+        assertEquals(56, Long.numberOfLeadingZeros(0x80));
+        assertEquals(56, Long.numberOfLeadingZeros(0xF0));
+        assertEquals(55, Long.numberOfLeadingZeros(0x100));
+        assertEquals(52, Long.numberOfLeadingZeros(0x800));
+        assertEquals(52, Long.numberOfLeadingZeros(0xF00));
+        assertEquals(51, Long.numberOfLeadingZeros(0x1000));
+        assertEquals(48, Long.numberOfLeadingZeros(0x8000));
+        assertEquals(48, Long.numberOfLeadingZeros(0xF000));
+        assertEquals(47, Long.numberOfLeadingZeros(0x10000));
+        assertEquals(44, Long.numberOfLeadingZeros(0x80000));
+        assertEquals(44, Long.numberOfLeadingZeros(0xF0000));
+        assertEquals(43, Long.numberOfLeadingZeros(0x100000));
+        assertEquals(40, Long.numberOfLeadingZeros(0x800000));
+        assertEquals(40, Long.numberOfLeadingZeros(0xF00000));
+        assertEquals(39, Long.numberOfLeadingZeros(0x1000000));
+        assertEquals(36, Long.numberOfLeadingZeros(0x8000000));
+        assertEquals(36, Long.numberOfLeadingZeros(0xF000000));
+        assertEquals(35, Long.numberOfLeadingZeros(0x10000000));
+        assertEquals(0, Long.numberOfLeadingZeros(0x80000000));
+        assertEquals(0, Long.numberOfLeadingZeros(0xF0000000));
+
+        assertEquals(1, Long.numberOfLeadingZeros(Long.MAX_VALUE));
+        assertEquals(0, Long.numberOfLeadingZeros(Long.MIN_VALUE));
+    }
+
+    /**
+     * java.lang.Long#numberOfTrailingZeros(long)
+     */
+    public void test_numberOfTrailingZerosJ() {
+        assertEquals(64, Long.numberOfTrailingZeros(0x0));
+        assertEquals(63, Long.numberOfTrailingZeros(Long.MIN_VALUE));
+        assertEquals(0, Long.numberOfTrailingZeros(Long.MAX_VALUE));
+
+        assertEquals(0, Long.numberOfTrailingZeros(0x1));
+        assertEquals(3, Long.numberOfTrailingZeros(0x8));
+        assertEquals(0, Long.numberOfTrailingZeros(0xF));
+
+        assertEquals(4, Long.numberOfTrailingZeros(0x10));
+        assertEquals(7, Long.numberOfTrailingZeros(0x80));
+        assertEquals(4, Long.numberOfTrailingZeros(0xF0));
+
+        assertEquals(8, Long.numberOfTrailingZeros(0x100));
+        assertEquals(11, Long.numberOfTrailingZeros(0x800));
+        assertEquals(8, Long.numberOfTrailingZeros(0xF00));
+
+        assertEquals(12, Long.numberOfTrailingZeros(0x1000));
+        assertEquals(15, Long.numberOfTrailingZeros(0x8000));
+        assertEquals(12, Long.numberOfTrailingZeros(0xF000));
+
+        assertEquals(16, Long.numberOfTrailingZeros(0x10000));
+        assertEquals(19, Long.numberOfTrailingZeros(0x80000));
+        assertEquals(16, Long.numberOfTrailingZeros(0xF0000));
+
+        assertEquals(20, Long.numberOfTrailingZeros(0x100000));
+        assertEquals(23, Long.numberOfTrailingZeros(0x800000));
+        assertEquals(20, Long.numberOfTrailingZeros(0xF00000));
+
+        assertEquals(24, Long.numberOfTrailingZeros(0x1000000));
+        assertEquals(27, Long.numberOfTrailingZeros(0x8000000));
+        assertEquals(24, Long.numberOfTrailingZeros(0xF000000));
+
+        assertEquals(28, Long.numberOfTrailingZeros(0x10000000));
+        assertEquals(31, Long.numberOfTrailingZeros(0x80000000));
+        assertEquals(28, Long.numberOfTrailingZeros(0xF0000000));
+    }
+
+    /**
+     * java.lang.Long#bitCount(long)
+     */
+    public void test_bitCountJ() {
+        assertEquals(0, Long.bitCount(0x0));
+        assertEquals(1, Long.bitCount(0x1));
+        assertEquals(1, Long.bitCount(0x2));
+        assertEquals(2, Long.bitCount(0x3));
+        assertEquals(1, Long.bitCount(0x4));
+        assertEquals(2, Long.bitCount(0x5));
+        assertEquals(2, Long.bitCount(0x6));
+        assertEquals(3, Long.bitCount(0x7));
+        assertEquals(1, Long.bitCount(0x8));
+        assertEquals(2, Long.bitCount(0x9));
+        assertEquals(2, Long.bitCount(0xA));
+        assertEquals(3, Long.bitCount(0xB));
+        assertEquals(2, Long.bitCount(0xC));
+        assertEquals(3, Long.bitCount(0xD));
+        assertEquals(3, Long.bitCount(0xE));
+        assertEquals(4, Long.bitCount(0xF));
+
+        assertEquals(8, Long.bitCount(0xFF));
+        assertEquals(12, Long.bitCount(0xFFF));
+        assertEquals(16, Long.bitCount(0xFFFF));
+        assertEquals(20, Long.bitCount(0xFFFFF));
+        assertEquals(24, Long.bitCount(0xFFFFFF));
+        assertEquals(28, Long.bitCount(0xFFFFFFF));
+        assertEquals(64, Long.bitCount(0xFFFFFFFFFFFFFFFFL));
+    }
+
+    /**
+     * java.lang.Long#rotateLeft(long, long)
+     */
+    public void test_rotateLeftJI() {
+        assertEquals(0xF, Long.rotateLeft(0xF, 0));
+        assertEquals(0xF0, Long.rotateLeft(0xF, 4));
+        assertEquals(0xF00, Long.rotateLeft(0xF, 8));
+        assertEquals(0xF000, Long.rotateLeft(0xF, 12));
+        assertEquals(0xF0000, Long.rotateLeft(0xF, 16));
+        assertEquals(0xF00000, Long.rotateLeft(0xF, 20));
+        assertEquals(0xF000000, Long.rotateLeft(0xF, 24));
+        assertEquals(0xF0000000L, Long.rotateLeft(0xF, 28));
+        assertEquals(0xF000000000000000L, Long.rotateLeft(0xF000000000000000L, 64));
+    }
+
+    /**
+     * java.lang.Long#rotateRight(long, long)
+     */
+    public void test_rotateRightJI() {
+        assertEquals(0xF, Long.rotateRight(0xF0, 4));
+        assertEquals(0xF, Long.rotateRight(0xF00, 8));
+        assertEquals(0xF, Long.rotateRight(0xF000, 12));
+        assertEquals(0xF, Long.rotateRight(0xF0000, 16));
+        assertEquals(0xF, Long.rotateRight(0xF00000, 20));
+        assertEquals(0xF, Long.rotateRight(0xF000000, 24));
+        assertEquals(0xF, Long.rotateRight(0xF0000000L, 28));
+        assertEquals(0xF000000000000000L, Long.rotateRight(0xF000000000000000L, 64));
+        assertEquals(0xF000000000000000L, Long.rotateRight(0xF000000000000000L, 0));
+
+    }
+
+    /**
+     * java.lang.Long#reverseBytes(long)
+     */
+    public void test_reverseBytesJ() {
+        assertEquals(0xAABBCCDD00112233L, Long.reverseBytes(0x33221100DDCCBBAAL));
+        assertEquals(0x1122334455667788L, Long.reverseBytes(0x8877665544332211L));
+        assertEquals(0x0011223344556677L, Long.reverseBytes(0x7766554433221100L));
+        assertEquals(0x2000000000000002L, Long.reverseBytes(0x0200000000000020L));
+    }
+
+    /**
+     * java.lang.Long#reverse(long)
+     */
+    public void test_reverseJ() {
+        assertEquals(0, Long.reverse(0));
+        assertEquals(-1, Long.reverse(-1));
+        assertEquals(0x8000000000000000L, Long.reverse(1));
+    }
+
+    /**
+     * java.lang.Long#signum(long)
+     */
+    public void test_signumJ() {
+        for (int i = -128; i < 0; i++) {
+            assertEquals(-1, Long.signum(i));
+        }
+        assertEquals(0, Long.signum(0));
+        for (int i = 1; i <= 127; i++) {
+            assertEquals(1, Long.signum(i));
+        }
+    }
+}
\ No newline at end of file
diff --git a/luni/src/test/java/tests/api/java/lang/MathTest.java b/luni/src/test/java/tests/api/java/lang/MathTest.java
new file mode 100644
index 0000000..1920080
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/MathTest.java
@@ -0,0 +1,1984 @@
+/*
+ *  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.lang;
+
+public class MathTest extends junit.framework.TestCase {
+
+    double HYP = Math.sqrt(2.0);
+
+    double OPP = 1.0;
+
+    double ADJ = 1.0;
+
+    /* Required to make previous preprocessor flags work - do not remove */
+    int unused = 0;
+
+    /**
+     * java.lang.Math#abs(double)
+     */
+    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));
+    }
+
+    /**
+     * 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));
+    }
+
+    /**
+     * 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));
+    }
+
+    /**
+     * 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));
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * java.lang.Math#cbrt(double)
+     */
+    public void test_cbrt_D() {
+        //Test for special situations
+        assertTrue("Should return Double.NaN", Double.isNaN(Math
+                .cbrt(Double.NaN)));
+        assertEquals("Should return Double.POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, Math
+                .cbrt(Double.POSITIVE_INFINITY), 0D);
+        assertEquals("Should return Double.NEGATIVE_INFINITY",
+                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)));
+
+        assertEquals("Should return 3.0", 3.0, Math.cbrt(27.0), 0D);
+        assertEquals("Should return 23.111993172558684", 23.111993172558684,
+                Math.cbrt(12345.6), 0D);
+        assertEquals("Should return 5.643803094122362E102",
+                5.643803094122362E102, Math.cbrt(Double.MAX_VALUE), 0D);
+        assertEquals("Should return 0.01", 0.01, Math.cbrt(0.000001), 0D);
+
+        assertEquals("Should return -3.0", -3.0, Math.cbrt(-27.0), 0D);
+        assertEquals("Should return -23.111993172558684", -23.111993172558684,
+                Math.cbrt(-12345.6), 0D);
+        assertEquals("Should return 1.7031839360032603E-108",
+                1.7031839360032603E-108, Math.cbrt(Double.MIN_VALUE), 0D);
+        assertEquals("Should return -0.01", -0.01, Math.cbrt(-0.000001), 0D);
+    }
+
+    /**
+     * 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",
+                -78, Math.ceil(-78.89), 0);
+    }
+
+    /**
+     * 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 };
+
+    /**
+     * {@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);
+                }
+            }
+        }
+
+        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
+        }
+    }
+
+    /**
+     * cases for test_copySign_FF in MathTest/StrictMathTest
+     */
+    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 };
+
+    /**
+     * {@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
+        }
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * java.lang.Math#cosh(double)
+     */
+    public void test_cosh_D() {
+        // Test for special situations
+        assertTrue(Double.isNaN(Math.cosh(Double.NaN)));
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, Math.cosh(Double.POSITIVE_INFINITY), 0D);
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, Math.cosh(Double.NEGATIVE_INFINITY), 0D);
+        assertEquals("Should return 1.0", 1.0, Math.cosh(+0.0), 0D);
+        assertEquals("Should return 1.0", 1.0, Math.cosh(-0.0), 0D);
+
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, Math.cosh(1234.56), 0D);
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, Math.cosh(-1234.56), 0D);
+        assertEquals("Should return 1.0000000000005", 1.0000000000005, Math
+                .cosh(0.000001), 0D);
+        assertEquals("Should return 1.0000000000005", 1.0000000000005, Math
+                .cosh(-0.000001), 0D);
+        assertEquals("Should return 5.212214351945598", 5.212214351945598, Math
+                .cosh(2.33482), 0D);
+
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, Math.cosh(Double.MAX_VALUE), 0D);
+        assertEquals("Should return 1.0", 1.0, Math.cosh(Double.MIN_VALUE), 0D);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * java.lang.Math#expm1(double)
+     */
+    public void test_expm1_D() {
+        // Test for special cases
+        assertTrue("Should return NaN", Double.isNaN(Math.expm1(Double.NaN)));
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, Math.expm1(Double.POSITIVE_INFINITY), 0D);
+        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)));
+
+        assertEquals("Should return -9.999950000166666E-6",
+                -9.999950000166666E-6, Math.expm1(-0.00001), 0D);
+        assertEquals("Should return 1.0145103074469635E60",
+                1.0145103074469635E60, Math.expm1(138.16951162), 0D);
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, Math
+                .expm1(123456789123456789123456789.4521584223), 0D);
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, Math.expm1(Double.MAX_VALUE), 0D);
+        assertEquals("Should return MIN_VALUE", Double.MIN_VALUE, Math
+                .expm1(Double.MIN_VALUE), 0D);
+    }
+
+    /**
+     * java.lang.Math#floor(double)
+     */
+    public void test_floorD() {
+        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 };
+
+    /**
+     * {@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 };
+
+    /**
+     * {@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
+        }
+    }
+
+    /**
+     * java.lang.Math#hypot(double, double)
+     */
+    public void test_hypot_DD() {
+        // Test for special cases
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, Math.hypot(Double.POSITIVE_INFINITY,
+                1.0), 0D);
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, Math.hypot(Double.NEGATIVE_INFINITY,
+                123.324), 0D);
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, Math.hypot(-758.2587,
+                Double.POSITIVE_INFINITY), 0D);
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, Math.hypot(5687.21,
+                Double.NEGATIVE_INFINITY), 0D);
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, Math.hypot(Double.POSITIVE_INFINITY,
+                Double.NEGATIVE_INFINITY), 0D);
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, Math.hypot(Double.NEGATIVE_INFINITY,
+                Double.POSITIVE_INFINITY), 0D);
+        assertTrue("Should be NaN", Double.isNaN(Math.hypot(Double.NaN,
+                2342301.89843)));
+        assertTrue("Should be NaN", Double.isNaN(Math.hypot(-345.2680,
+                Double.NaN)));
+
+        assertEquals("Should return 2396424.905416697", 2396424.905416697, Math
+                .hypot(12322.12, -2396393.2258), 0D);
+        assertEquals("Should return 138.16958070558556", 138.16958070558556,
+                Math.hypot(-138.16951162, 0.13817035864), 0D);
+        assertEquals("Should return 1.7976931348623157E308",
+                1.7976931348623157E308, Math.hypot(Double.MAX_VALUE, 211370.35), 0D);
+        assertEquals("Should return 5413.7185", 5413.7185, Math.hypot(
+                -5413.7185, Double.MIN_VALUE), 0D);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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));
+        }
+    }
+
+    /**
+     * java.lang.Math#log10(double)
+     */
+    @SuppressWarnings("boxing")
+    public void test_log10_D() {
+        // Test for special cases
+        assertTrue(Double.isNaN(Math.log10(Double.NaN)));
+        assertTrue(Double.isNaN(Math.log10(-2541.05745687234187532)));
+        assertTrue(Double.isNaN(Math.log10(-0.1)));
+        assertEquals(Double.POSITIVE_INFINITY, Math.log10(Double.POSITIVE_INFINITY));
+        assertEquals(Double.NEGATIVE_INFINITY, Math.log10(0.0));
+        assertEquals(Double.NEGATIVE_INFINITY, Math.log10(+0.0));
+        assertEquals(Double.NEGATIVE_INFINITY, Math.log10(-0.0));
+
+        assertEquals(3.0, Math.log10(1000.0));
+        assertEquals(14.0, Math.log10(Math.pow(10, 14)));
+        assertEquals(3.7389561269540406, Math.log10(5482.2158));
+        assertEquals(14.661551142893833, Math.log10(458723662312872.125782332587));
+        assertEquals(-0.9083828622192334, Math.log10(0.12348583358871));
+        assertEquals(308.25471555991675, Math.log10(Double.MAX_VALUE));
+        assertEquals(-323.3062153431158, Math.log10(Double.MIN_VALUE));
+    }
+
+    /**
+     * java.lang.Math#log1p(double)
+     */
+    public void test_log1p_D() {
+        // Test for special cases
+        assertTrue("Should return NaN", Double.isNaN(Math.log1p(Double.NaN)));
+        assertTrue("Should return NaN", Double.isNaN(Math.log1p(-32.0482175)));
+        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)));
+
+        assertEquals("Should return -0.2941782295312541", -0.2941782295312541,
+                Math.log1p(-0.254856327), 0D);
+        assertEquals("Should return 7.368050685564151", 7.368050685564151, Math
+                .log1p(1583.542), 0D);
+        assertEquals("Should return 0.4633708685409921", 0.4633708685409921,
+                Math.log1p(0.5894227), 0D);
+        assertEquals("Should return 709.782712893384", 709.782712893384, Math
+                .log1p(Double.MAX_VALUE), 0D);
+        assertEquals("Should return Double.MIN_VALUE", Double.MIN_VALUE, Math
+                .log1p(Double.MIN_VALUE), 0D);
+    }
+
+    /**
+     * 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);
+
+        // 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)));
+    }
+
+    /**
+     * 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)));
+    }
+
+    /**
+     * 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));
+    }
+
+    /**
+     * 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));
+    }
+
+    /**
+     * 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)));
+    }
+
+    /**
+     * 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)));
+    }
+
+    /**
+     * 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));
+
+    }
+
+    /**
+     * 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 };
+
+    /**
+     * {@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
+        }
+    }
+
+    /**
+     * 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
+     */
+    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 } };
+
+    /**
+     * {@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
+        }
+    }
+
+    /**
+     * {@link java.lang.Math#nextUp(double)}
+     * @since 1.6
+     */
+    @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
+        }
+    }
+
+    /**
+     * {@link java.lang.Math#nextUp(float)}
+     * @since 1.6
+     */
+    @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
+        }
+    }
+
+    /**
+     * 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 };
+
+        for (int x = 0; x < values.length; x++) {
+            double dval = values[x];
+            double nagateDval = negateDouble(dval);
+            if (nagateDval == Double.NaN) {
+                continue;
+            }
+
+            // 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));
+
+            // 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));
+
+            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(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;
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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));
+    }
+
+    /**
+     * 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));
+    }
+
+    /**
+     * {@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
+        }
+
+        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)));
+    }
+
+    /**
+     * {@link java.lang.Math#scalb(float, int)}
+     * @since 1.6
+     */
+    @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));
+
+        float normal = Math.scalb(0.2345f, -25);
+        assertEquals(6.98864459991455E-9f, normal);
+        // precision kept
+        assertEquals(0.2345f, Math.scalb(normal, 25));
+
+        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)));
+    }
+
+    /**
+     * java.lang.Math#signum(double)
+     */
+    public void test_signum_D() {
+        assertTrue(Double.isNaN(Math.signum(Double.NaN)));
+        assertTrue(Double.isNaN(Math.signum(Double.NaN)));
+        assertEquals(Double.doubleToLongBits(0.0), Double.doubleToLongBits(Math
+                .signum(0.0)));
+        assertEquals(Double.doubleToLongBits(+0.0), Double
+                .doubleToLongBits(Math.signum(+0.0)));
+        assertEquals(Double.doubleToLongBits(-0.0), Double
+                .doubleToLongBits(Math.signum(-0.0)));
+
+        assertEquals(1.0, Math.signum(253681.2187962), 0D);
+        assertEquals(-1.0, Math.signum(-125874693.56), 0D);
+        assertEquals(1.0, Math.signum(1.2587E-308), 0D);
+        assertEquals(-1.0, Math.signum(-1.2587E-308), 0D);
+
+        assertEquals(1.0, Math.signum(Double.MAX_VALUE), 0D);
+        assertEquals(1.0, Math.signum(Double.MIN_VALUE), 0D);
+        assertEquals(-1.0, Math.signum(-Double.MAX_VALUE), 0D);
+        assertEquals(-1.0, Math.signum(-Double.MIN_VALUE), 0D);
+        assertEquals(1.0, Math.signum(Double.POSITIVE_INFINITY), 0D);
+        assertEquals(-1.0, Math.signum(Double.NEGATIVE_INFINITY), 0D);
+    }
+
+    /**
+     * java.lang.Math#signum(float)
+     */
+    public void test_signum_F() {
+        assertTrue(Float.isNaN(Math.signum(Float.NaN)));
+        assertEquals(Float.floatToIntBits(0.0f), Float
+                .floatToIntBits(Math.signum(0.0f)));
+        assertEquals(Float.floatToIntBits(+0.0f), Float
+                .floatToIntBits(Math.signum(+0.0f)));
+        assertEquals(Float.floatToIntBits(-0.0f), Float
+                .floatToIntBits(Math.signum(-0.0f)));
+
+        assertEquals(1.0f, Math.signum(253681.2187962f), 0f);
+        assertEquals(-1.0f, Math.signum(-125874693.56f), 0f);
+        assertEquals(1.0f, Math.signum(1.2587E-11f), 0f);
+        assertEquals(-1.0f, Math.signum(-1.2587E-11f), 0f);
+
+        assertEquals(1.0f, Math.signum(Float.MAX_VALUE), 0f);
+        assertEquals(1.0f, Math.signum(Float.MIN_VALUE), 0f);
+        assertEquals(-1.0f, Math.signum(-Float.MAX_VALUE), 0f);
+        assertEquals(-1.0f, Math.signum(-Float.MIN_VALUE), 0f);
+        assertEquals(1.0f, Math.signum(Float.POSITIVE_INFINITY), 0f);
+        assertEquals(-1.0f, Math.signum(Float.NEGATIVE_INFINITY), 0f);
+    }
+
+    /**
+     * java.lang.Math#sin(double)
+     */
+    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);
+    }
+
+    /**
+     * java.lang.Math#sinh(double)
+     */
+    public void test_sinh_D() {
+        // Test for special situations
+        assertTrue("Should return NaN", Double.isNaN(Math.sinh(Double.NaN)));
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, Math.sinh(Double.POSITIVE_INFINITY), 0D);
+        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)));
+
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, Math.sinh(1234.56), 0D);
+        assertEquals("Should return NEGATIVE_INFINITY",
+                Double.NEGATIVE_INFINITY, Math.sinh(-1234.56), 0D);
+        assertEquals("Should return 1.0000000000001666E-6",
+                1.0000000000001666E-6, Math.sinh(0.000001), 0D);
+        assertEquals("Should return -1.0000000000001666E-6",
+                -1.0000000000001666E-6, Math.sinh(-0.000001), 0D);
+        assertEquals("Should return 5.115386441963859", 5.115386441963859, Math
+                .sinh(2.33482), 0D);
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, Math.sinh(Double.MAX_VALUE), 0D);
+        assertEquals("Should return 4.9E-324", 4.9E-324, Math
+                .sinh(Double.MIN_VALUE), 0D);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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);
+
+    }
+
+    /**
+     * java.lang.Math#tanh(double)
+     */
+    public void test_tanh_D() {
+        // Test for special situations
+        assertTrue("Should return NaN", Double.isNaN(Math.tanh(Double.NaN)));
+        assertEquals("Should return +1.0", +1.0, Math
+                .tanh(Double.POSITIVE_INFINITY), 0D);
+        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)));
+
+        assertEquals("Should return 1.0", 1.0, Math.tanh(1234.56), 0D);
+        assertEquals("Should return -1.0", -1.0, Math.tanh(-1234.56), 0D);
+        assertEquals("Should return 9.999999999996666E-7",
+                9.999999999996666E-7, Math.tanh(0.000001), 0D);
+        assertEquals("Should return 0.981422884124941", 0.981422884124941, Math
+                .tanh(2.33482), 0D);
+        assertEquals("Should return 1.0", 1.0, Math.tanh(Double.MAX_VALUE), 0D);
+        assertEquals("Should return 4.9E-324", 4.9E-324, Math
+                .tanh(Double.MIN_VALUE), 0D);
+    }
+
+    /**
+     * 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);
+        }
+    }
+
+    /**
+     * 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);
+        }
+    }
+
+    /**
+     * 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);
+        }
+    }
+
+    /**
+     * java.lang.Math#ulp(double)
+     */
+    @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);
+
+        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);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * {@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)));
+        }
+    }
+
+    /**
+     * {@link java.lang.Math#shiftLongBits(long, long)}
+     * <p/>
+     * Round result to nearest value on precision lost.
+     * @since 1.6
+     */
+    public void test_shiftLongBits_LL() {
+        class Tuple {
+            public long result;
+
+            public long value;
+
+            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/tests/api/java/lang/MockEnum.java b/luni/src/test/java/tests/api/java/lang/MockEnum.java
new file mode 100644
index 0000000..ed6c69b
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/MockEnum.java
@@ -0,0 +1,57 @@
+/* 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.lang;
+
+import java.io.Serializable;
+
+class MockEnum implements Serializable {
+    private static final long serialVersionUID = -1678507713086705252L;
+
+    enum Sample {
+        LARRY, MOE, CURLY
+    }
+
+    enum Sample2 {
+        RED, BLUE, YELLO
+    }
+
+    String str;
+
+    int i;
+
+    Sample2 samEnum;
+
+    Sample larry = Sample.LARRY;
+
+    MockEnum() {
+        str = "test";
+        i = 99;
+        samEnum = Sample2.BLUE;
+    }
+
+    public boolean equals(Object arg0) {
+        if (!(arg0 instanceof MockEnum)) {
+            return false;
+        }
+        MockEnum test = (MockEnum) arg0;
+        if (str.equals(test.str) && i == test.i && samEnum == test.samEnum) {
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/lang/MockEnum2.java b/luni/src/test/java/tests/api/java/lang/MockEnum2.java
new file mode 100644
index 0000000..229d106
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/MockEnum2.java
@@ -0,0 +1,61 @@
+/* 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.lang;
+
+import java.io.Serializable;
+
+class MockEnum2 implements Serializable {
+
+    private static final long serialVersionUID = -4812214670022262730L;
+
+    enum Sample {
+        LARRY, MOE, CURLY
+    }
+
+    enum Sample2 {
+        RED, BLUE, YELLO
+    }
+
+    String str;
+
+    int i;
+
+    Sample samEnum;
+
+    Sample larry = Sample.LARRY;
+
+    String myStr = "LARRY";
+
+    MockEnum2() {
+        str = "test";
+        i = 99;
+        samEnum = larry;
+    }
+
+    public boolean equals(Object arg0) {
+        if (!(arg0 instanceof MockEnum2)) {
+            return false;
+        }
+        MockEnum2 test = (MockEnum2) arg0;
+        if (str.equals(test.str) && i == test.i && samEnum == test.samEnum
+                && myStr.equals(test.myStr)) {
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/lang/NegativeArraySizeExceptionTest.java b/luni/src/test/java/tests/api/java/lang/NegativeArraySizeExceptionTest.java
new file mode 100644
index 0000000..3c5f124
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/NegativeArraySizeExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class NegativeArraySizeExceptionTest extends TestCase {
+
+    /**
+     * java.lang.NegativeArraySizeException#NegativeArraySizeException()
+     */
+    public void test_Constructor() {
+        NegativeArraySizeException e = new NegativeArraySizeException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.NegativeArraySizeException#NegativeArraySizeException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        NegativeArraySizeException e = new NegativeArraySizeException("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/NoClassDefFoundErrorTest.java b/luni/src/test/java/tests/api/java/lang/NoClassDefFoundErrorTest.java
new file mode 100644
index 0000000..98d66f2
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/NoClassDefFoundErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class NoClassDefFoundErrorTest extends TestCase {
+
+    /**
+     * java.lang.NoClassDefFoundError#NoClassDefFoundError()
+     */
+    public void test_Constructor() {
+        NoClassDefFoundError e = new NoClassDefFoundError();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.NoClassDefFoundError#NoClassDefFoundError(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        NoClassDefFoundError e = new NoClassDefFoundError("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/NoSuchFieldErrorTest.java b/luni/src/test/java/tests/api/java/lang/NoSuchFieldErrorTest.java
new file mode 100644
index 0000000..21d4ff1
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/NoSuchFieldErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class NoSuchFieldErrorTest extends TestCase {
+
+    /**
+     * java.lang.NoSuchFieldError#NoSuchFieldError()
+     */
+    public void test_Constructor() {
+        NoSuchFieldError e = new NoSuchFieldError();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.NoSuchFieldError#NoSuchFieldError(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        NoSuchFieldError e = new NoSuchFieldError("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/NoSuchFieldExceptionTest.java b/luni/src/test/java/tests/api/java/lang/NoSuchFieldExceptionTest.java
new file mode 100644
index 0000000..4d52601
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/NoSuchFieldExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class NoSuchFieldExceptionTest extends TestCase {
+
+    /**
+     * java.lang.NoSuchFieldException#NoSuchFieldException()
+     */
+    public void test_Constructor() {
+        NoSuchFieldException e = new NoSuchFieldException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.NoSuchFieldException#NoSuchFieldException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        NoSuchFieldException e = new NoSuchFieldException("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/NoSuchMethodErrorTest.java b/luni/src/test/java/tests/api/java/lang/NoSuchMethodErrorTest.java
new file mode 100644
index 0000000..e47349a
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/NoSuchMethodErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class NoSuchMethodErrorTest extends TestCase {
+
+    /**
+     * java.lang.NoSuchMethodError#NoSuchMethodError()
+     */
+    public void test_Constructor() {
+        NoSuchMethodError e = new NoSuchMethodError();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.NoSuchMethodError#NoSuchMethodError(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        NoSuchMethodError e = new NoSuchMethodError("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/NoSuchMethodExceptionTest.java b/luni/src/test/java/tests/api/java/lang/NoSuchMethodExceptionTest.java
new file mode 100644
index 0000000..e500909
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/NoSuchMethodExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class NoSuchMethodExceptionTest extends TestCase {
+
+    /**
+     * java.lang.NoSuchMethodException#NoSuchMethodException()
+     */
+    public void test_Constructor() {
+        NoSuchMethodException e = new NoSuchMethodException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.NoSuchMethodException#NoSuchMethodException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        NoSuchMethodException e = new NoSuchMethodException("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/NullPointerExceptionTest.java b/luni/src/test/java/tests/api/java/lang/NullPointerExceptionTest.java
new file mode 100644
index 0000000..7a0fb82
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/NullPointerExceptionTest.java
@@ -0,0 +1,41 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class NullPointerExceptionTest extends TestCase {
+
+    /**
+     * java.lang.NullPointerException#NullPointerException()
+     */
+    public void test_Constructor() {
+        NullPointerException e = new NullPointerException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.NullPointerException#NullPointerException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        NullPointerException e = new NullPointerException("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/NumberFormatExceptionTest.java b/luni/src/test/java/tests/api/java/lang/NumberFormatExceptionTest.java
new file mode 100644
index 0000000..329969b
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/NumberFormatExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class NumberFormatExceptionTest extends TestCase {
+
+    /**
+     * java.lang.NumberFormatException#NumberFormatException()
+     */
+    public void test_Constructor() {
+        NumberFormatException e = new NumberFormatException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.NumberFormatException#NumberFormatException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        NumberFormatException e = new NumberFormatException("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/NumberTest.java b/luni/src/test/java/tests/api/java/lang/NumberTest.java
new file mode 100644
index 0000000..7ecdda4
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/NumberTest.java
@@ -0,0 +1,66 @@
+/*
+ *  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.lang;
+
+public class NumberTest extends junit.framework.TestCase {
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/ObjectTest.java b/luni/src/test/java/tests/api/java/lang/ObjectTest.java
new file mode 100644
index 0000000..e3d0b19
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/ObjectTest.java
@@ -0,0 +1,388 @@
+/*
+ *  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.lang;
+
+public class ObjectTest extends junit.framework.TestCase {
+
+    /**
+     * Test objects.
+     */
+    Object obj1 = new Object();
+
+    Object obj2 = new Object();
+
+    /**
+     * Generic state indicator.
+     */
+    int status = 0;
+
+    int ready = 0;
+
+    /**
+     * java.lang.Object#Object()
+     */
+    public void test_Constructor() {
+        // Test for method java.lang.Object()
+        assertNotNull("Constructor failed !!!", new Object());
+    }
+
+    /**
+     * java.lang.Object#equals(java.lang.Object)
+     */
+    public void test_equalsLjava_lang_Object() {
+        // Test for method boolean java.lang.Object.equals(java.lang.Object)
+        assertTrue("Same object should be equal", obj1.equals(obj1));
+        assertTrue("Different objects should not be equal", !obj1.equals(obj2));
+    }
+
+    /**
+     * java.lang.Object#getClass()
+     */
+    public void test_getClass() throws Exception {
+        // Test for method java.lang.Class java.lang.Object.getClass()
+        String classNames[] = { "java.lang.Object", "java.lang.Throwable",
+                "java.lang.StringBuffer" };
+        Class<?> classToTest = null;
+        Object instanceToTest = null;
+
+        status = 0;
+        for (int i = 0; i < classNames.length; ++i) {
+            classToTest = Class.forName(classNames[i]);
+            instanceToTest = classToTest.newInstance();
+            assertTrue("Instance didn't match creator class.",
+                    instanceToTest.getClass() == classToTest);
+            assertTrue("Instance didn't match class with matching name.",
+                    instanceToTest.getClass() == Class
+                            .forName(classNames[i]));
+        }
+    }
+
+    /**
+     * java.lang.Object#hashCode()
+     */
+    public void test_hashCode() {
+        // Test for method int java.lang.Object.hashCode()
+        assertTrue("Same object should have same hash.",
+                obj1.hashCode() == obj1.hashCode());
+        assertTrue("Same object should have same hash.",
+                obj2.hashCode() == obj2.hashCode());
+    }
+
+    /**
+     * java.lang.Object#notify()
+     */
+    public void test_notify() {
+        // Test for method void java.lang.Object.notify()
+
+        // Inner class to run test thread.
+        class TestThread implements Runnable {
+            public void run() {
+                synchronized (obj1) {
+                    try {
+                        ready += 1;
+                        obj1.wait();// Wait for ever.
+                        status += 1;
+                    } catch (InterruptedException ex) {
+                        status = -1000;
+                    }
+                }
+            }
+        }
+        ;
+
+        // Start of test code.
+
+        // Warning:
+        // This code relies on each thread getting serviced within
+        // 200 mSec of when it is notified. Although this
+        // seems reasonable, it could lead to false-failures.
+
+        ready = 0;
+        status = 0;
+        final int readyWaitSecs = 3;
+
+        final int threadCount = 20;
+        for (int i = 0; i < threadCount; ++i) {
+            new Thread(new TestThread()).start();
+        }
+        synchronized (obj1) {
+            try {
+
+                // Wait up to readyWaitSeconds for all threads to be waiting on
+                // monitor
+                for (int i = 0; i < readyWaitSecs; i++) {
+                    obj1.wait(1000, 0);
+                    if (ready == threadCount) {
+                        break;
+                    }
+                }
+
+                // Check pre-conditions of testing notifyAll
+                assertTrue("Not all launched threads are waiting. (ready = "
+                        + ready + ")", ready == threadCount);
+                assertTrue("Thread woke too early. (status = " + status + ")",
+                        status == 0);
+
+                for (int i = 1; i <= threadCount; ++i) {
+                    obj1.notify();
+                    obj1.wait(200, 0);
+                    assertTrue("Out of sync. (expected " + i + " but got "
+                            + status + ")", status == i);
+                }
+
+            } catch (InterruptedException ex) {
+                fail(
+                        "Unexpectedly got an InterruptedException. (status = "
+                                + status + ")");
+            }
+        }
+    }
+
+    /**
+     * java.lang.Object#notifyAll()
+     */
+    public void test_notifyAll() {
+        // Test for method void java.lang.Object.notifyAll()
+
+        // Inner class to run test thread.
+        class TestThread implements Runnable {
+            public void run() {
+                synchronized (obj1) {
+                    try {
+                        ready += 1;
+                        obj1.wait();// Wait for ever.
+                        status += 1;
+                    } catch (InterruptedException ex) {
+                        status = -1000;
+                    }
+                }
+            }
+        }
+        ;
+
+        // Start of test code.
+
+        // Warning:
+        // This code relies on all threads getting serviced within
+        // 5 seconds of when they are notified. Although this
+        // seems reasonable, it could lead to false-failures.
+
+        status = 0;
+        ready = 0;
+        final int readyWaitSecs = 3;
+        final int threadCount = 20;
+        for (int i = 0; i < threadCount; ++i) {
+            new Thread(new TestThread()).start();
+        }
+
+        synchronized (obj1) {
+
+            try {
+
+                // Wait up to readyWaitSeconds for all threads to be waiting on
+                // monitor
+                for (int i = 0; i < readyWaitSecs; i++) {
+                    obj1.wait(1000, 0);
+                    if (ready == threadCount) {
+                        break;
+                    }
+                }
+
+                // Check pre-conditions of testing notifyAll
+                assertTrue("Not all launched threads are waiting. (ready = "
+                        + ready + ")", ready == threadCount);
+                assertTrue("At least one thread woke too early. (status = "
+                        + status + ")", status == 0);
+
+                obj1.notifyAll();
+
+                obj1.wait(5000, 0);
+
+                assertTrue(
+                        "At least one thread did not get notified. (status = "
+                                + status + ")", status == threadCount);
+
+            } catch (InterruptedException ex) {
+                fail(
+                        "Unexpectedly got an InterruptedException. (status = "
+                                + status + ")");
+            }
+
+        }
+    }
+
+    /**
+     * java.lang.Object#toString()
+     */
+    public void test_toString() {
+        // Test for method java.lang.String java.lang.Object.toString()
+        assertNotNull("Object toString returned null.", obj1.toString());
+    }
+
+    /**
+     * java.lang.Object#wait()
+     */
+    public void test_wait() {
+        // Test for method void java.lang.Object.wait()
+
+        // Inner class to run test thread.
+        class TestThread implements Runnable {
+            public void run() {
+                synchronized (obj1) {
+                    try {
+                        obj1.wait();// Wait for ever.
+                        status = 1;
+                    } catch (InterruptedException ex) {
+                        status = -1;
+                    }
+                }
+            }
+        }
+        ;
+
+        // Start of test code.
+
+        // Warning:
+        // This code relies on threads getting serviced within
+        // 1 second of when they are notified. Although this
+        // seems reasonable, it could lead to false-failures.
+
+        status = 0;
+        new Thread(new TestThread()).start();
+        synchronized (obj1) {
+            try {
+                obj1.wait(1000, 0);
+                assertTrue("Thread woke too early. (status = " + status + ")",
+                        status == 0);
+                obj1.notifyAll();
+                obj1.wait(1000, 0);
+                assertTrue("Thread did not get notified. (status = " + status
+                        + ")", status == 1);
+            } catch (InterruptedException ex) {
+                fail(
+                        "Unexpectedly got an InterruptedException. (status = "
+                                + status + ")");
+            }
+        }
+    }
+
+    /**
+     * java.lang.Object#wait(long)
+     */
+    public void test_waitJ() {
+        // Test for method void java.lang.Object.wait(long)
+
+        // Start of test code.
+
+        final int loopCount = 20;
+        final int allowableError = 100; // millesconds
+        final int delay = 200; // milliseconds
+        synchronized (obj1) {
+            try {
+                int count = 0;
+                long[][] toLong = new long[3][3];
+                for (int i = 0; i < loopCount; ++i) {
+                    long before = System.currentTimeMillis();
+                    obj1.wait(delay, 0);
+                    long after = System.currentTimeMillis();
+                    long error = (after - before - delay);
+                    if (error < 0)
+                        error = -error;
+                    if (i > 0 && error > allowableError) {
+                        // Allow jit to warm up before testing
+                        if (count < toLong.length) {
+                            toLong[count][0] = i;
+                            toLong[count][1] = before;
+                            toLong[count][2] = after;
+                            count++;
+                        }
+                        if (error > (1000 + delay) || count == toLong.length) {
+                            StringBuffer sb = new StringBuffer();
+                            for (int j = 0; j < count; j++) {
+                                sb
+                                        .append("wakeup time too inaccurate, iteration ");
+                                sb.append(toLong[j][0]);
+                                sb.append(", before: ");
+                                sb.append(toLong[j][1]);
+                                sb.append(" after: ");
+                                sb.append(toLong[j][2]);
+                                sb.append(" diff: ");
+                                sb.append(toLong[j][2] - toLong[j][1]);
+                                sb.append("\n");
+                            }
+                            fail(sb.toString());
+                        }
+                    }
+                }
+            } catch (InterruptedException ex) {
+                fail(
+                        "Unexpectedly got an InterruptedException. (status = "
+                                + status + ")");
+            }
+        }
+    }
+
+    /**
+     * java.lang.Object#wait(long, int)
+     */
+    public void test_waitJI() {
+        // Test for method void java.lang.Object.wait(long, int)
+
+        // Inner class to run test thread.
+        class TestThread implements Runnable {
+            public void run() {
+                synchronized (obj1) {
+                    try {
+                        obj1.wait(0, 1); // Don't wait very long.
+                        status = 1;
+                        obj1.wait(0, 0); // Wait for ever.
+                        status = 2;
+                    } catch (InterruptedException ex) {
+                        status = -1;
+                    }
+                }
+            }
+        }
+        ;
+
+        // Start of test code.
+
+        // Warning:
+        // This code relies on threads getting serviced within
+        // 1 second of when they are notified. Although this
+        // seems reasonable, it could lead to false-failures.
+
+        status = 0;
+        new Thread(new TestThread()).start();
+        synchronized (obj1) {
+            try {
+                obj1.wait(1000, 0);
+                assertTrue("Thread did not wake after 1 ms. (status = "
+                        + status + ")", status == 1);
+                obj1.notifyAll();
+                obj1.wait(1000, 0);
+                assertTrue("Thread did not get notified. (status = " + status
+                        + ")", status == 2);
+            } catch (InterruptedException ex) {
+                fail(
+                        "Unexpectedly got an InterruptedException. (status = "
+                                + status + ")");
+            }
+        }
+
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/OutOfMemoryErrorTest.java b/luni/src/test/java/tests/api/java/lang/OutOfMemoryErrorTest.java
new file mode 100644
index 0000000..3eb7562e
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/OutOfMemoryErrorTest.java
@@ -0,0 +1,46 @@
+/*
+ *  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.lang;
+
+public class OutOfMemoryErrorTest extends junit.framework.TestCase {
+
+    /**
+     * java.lang.OutOfMemoryError#OutOfMemoryError()
+     */
+    public void test_Constructor() {
+        // Test for method java.lang.OutOfMemoryError()
+        Error e = new OutOfMemoryError();
+        assertNull(e.getCause());
+        assertNull(e.getMessage());
+    }
+
+    /**
+     * 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/tests/api/java/lang/PackageTest.java b/luni/src/test/java/tests/api/java/lang/PackageTest.java
new file mode 100644
index 0000000..5ac1c1d
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/PackageTest.java
@@ -0,0 +1,396 @@
+/*
+ *  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.lang;
+
+import java.io.File;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+import tests.support.resource.Support_Resources;
+
+public class PackageTest extends junit.framework.TestCase {
+
+    private File resources;
+
+    private String resPath;
+
+    Package getTestPackage(String resourceJar, String className)
+            throws Exception {
+        Support_Resources.copyFile(resources, "Package", resourceJar);
+        URL resourceURL = new URL("file:/" + resPath + "/Package/"
+                + resourceJar);
+
+        URLClassLoader ucl = new URLClassLoader(new URL[] { resourceURL }, null);
+        return Class.forName(className, true, ucl).getPackage();
+    }
+
+    @Override
+    protected void setUp() {
+        resources = Support_Resources.createTempFolder();
+        resPath = resources.toString();
+        if (resPath.charAt(0) == '/' || resPath.charAt(0) == '\\')
+            resPath = resPath.substring(1);
+    }
+
+    /**
+     * There is a newer version of this class with some actual tests but since
+     * the class is not implemented they all fail. For now use the stub test
+     * methods.
+     */
+
+    /**
+     * java.lang.Package#getImplementationVendor()
+     * java.lang.Package#getImplementationVersion()
+     * java.lang.Package#getSpecificationTitle()
+     * java.lang.Package#getSpecificationVendor()
+     * java.lang.Package#getSpecificationVersion()
+     * java.lang.Package#getImplementationTitle()
+     */
+    public void test_helper_Attributes() throws Exception {
+
+        Package p = getTestPackage("hyts_all_attributes.jar", "p.C");
+        assertEquals(
+                "Package getImplementationTitle returns a wrong string (1)",
+                "p Implementation-Title", p.getImplementationTitle());
+        assertEquals(
+                "Package getImplementationVendor returns a wrong string (1)",
+                "p Implementation-Vendor", p.getImplementationVendor());
+        assertEquals(
+                "Package getImplementationVersion returns a wrong string (1)",
+                "2.2.2", p.getImplementationVersion());
+        assertEquals(
+                "Package getSpecificationTitle returns a wrong string (1)",
+                "p Specification-Title", p.getSpecificationTitle());
+        assertEquals(
+                "Package getSpecificationVendor returns a wrong string (1)",
+                "p Specification-Vendor", p.getSpecificationVendor());
+        assertEquals(
+                "Package getSpecificationVersion returns a wrong string (1)",
+                "2.2.2", p.getSpecificationVersion());
+
+        // No entry for the package
+        Package p2 = getTestPackage("hyts_no_entry.jar", "p.C");
+        assertEquals(
+                "Package getImplementationTitle returns a wrong string (2)",
+                "MF Implementation-Title", p2.getImplementationTitle());
+        assertEquals(
+                "Package getImplementationVendor returns a wrong string (2)",
+                "MF Implementation-Vendor", p2.getImplementationVendor());
+        assertEquals(
+                "Package getImplementationVersion returns a wrong string (2)",
+                "5.3.b1", p2.getImplementationVersion());
+        assertEquals(
+                "Package getSpecificationTitle returns a wrong string (2)",
+                "MF Specification-Title", p2.getSpecificationTitle());
+        assertEquals(
+                "Package getSpecificationVendor returns a wrong string (2)",
+                "MF Specification-Vendor", p2.getSpecificationVendor());
+        assertEquals(
+                "Package getSpecificationVersion returns a wrong string (2)",
+                "1.2.3", p2.getSpecificationVersion());
+
+        // No attributes in the package entry
+        Package p3 = getTestPackage("hyts_no_attributes.jar", "p.C");
+        assertEquals(
+                "Package getImplementationTitle returns a wrong string (3)",
+                "MF Implementation-Title", p3.getImplementationTitle());
+        assertEquals(
+                "Package getImplementationVendor returns a wrong string (3)",
+                "MF Implementation-Vendor", p3.getImplementationVendor());
+        assertEquals(
+                "Package getImplementationVersion returns a wrong string (3)",
+                "5.3.b1", p3.getImplementationVersion());
+        assertEquals(
+                "Package getSpecificationTitle returns a wrong string (3)",
+                "MF Specification-Title", p3.getSpecificationTitle());
+        assertEquals(
+                "Package getSpecificationVendor returns a wrong string (3)",
+                "MF Specification-Vendor", p3.getSpecificationVendor());
+        assertEquals(
+                "Package getSpecificationVersion returns a wrong string (3)",
+                "1.2.3", p3.getSpecificationVersion());
+
+        // Some attributes in the package entry
+        Package p4 = getTestPackage("hyts_some_attributes.jar", "p.C");
+        assertEquals(
+                "Package getImplementationTitle returns a wrong string (4)",
+                "p Implementation-Title", p4.getImplementationTitle());
+        assertEquals(
+                "Package getImplementationVendor returns a wrong string (4)",
+                "MF Implementation-Vendor", p4.getImplementationVendor());
+        assertEquals(
+                "Package getImplementationVersion returns a wrong string (4)",
+                "2.2.2", p4.getImplementationVersion());
+        assertEquals(
+                "Package getSpecificationTitle returns a wrong string (4)",
+                "MF Specification-Title", p4.getSpecificationTitle());
+        assertEquals(
+                "Package getSpecificationVendor returns a wrong string (4)",
+                "p Specification-Vendor", p4.getSpecificationVendor());
+        assertEquals(
+                "Package getSpecificationVersion returns a wrong string (4)",
+                "2.2.2", p4.getSpecificationVersion());
+
+        // subdirectory Package
+        Package p5 = getTestPackage("hyts_pq.jar", "p.q.C");
+        assertEquals(
+                "Package getImplementationTitle returns a wrong string (5)",
+                "p Implementation-Title", p5.getImplementationTitle());
+        assertEquals(
+                "Package getImplementationVendor returns a wrong string (5)",
+                "p Implementation-Vendor", p5.getImplementationVendor());
+        assertEquals(
+                "Package getImplementationVersion returns a wrong string (5)",
+                "1.1.3", p5.getImplementationVersion());
+        assertEquals(
+                "Package getSpecificationTitle returns a wrong string (5)",
+                "p Specification-Title", p5.getSpecificationTitle());
+        assertEquals(
+                "Package getSpecificationVendor returns a wrong string (5)",
+                "p Specification-Vendor", p5.getSpecificationVendor());
+        assertEquals(
+                "Package getSpecificationVersion returns a wrong string (5)",
+                "2.2.0.0.0.0.0.0.0.0.0", p5.getSpecificationVersion());
+    }
+
+    /**
+     * java.lang.Package#getName()
+     */
+    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
+                .getName());
+    }
+
+    /**
+     * java.lang.Package#getPackage(java.lang.String)
+     */
+    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());
+    }
+
+    /**
+     * java.lang.Package#getPackages()
+     */
+    public void test_getPackages() throws Exception {
+        Package[] pckgs = Package.getPackages();
+        boolean found = false;
+        for (int i = 0; i < pckgs.length; i++) {
+            if (pckgs[i].getName().equals("java.util")) {
+                found = true;
+                break;
+            }
+        }
+        assertTrue("Package getPackages failed to retrieve a package", found);
+    }
+
+    /**
+     * java.lang.Package#hashCode()
+     */
+    public void test_hashCode() {
+        Package p1 = Package.getPackage("java.lang");
+        if (p1 != null) {
+            assertEquals(p1.hashCode(), "java.lang".hashCode());
+        }
+    }
+
+    /**
+     * java.lang.Package#isCompatibleWith(java.lang.String)
+     */
+    public void test_isCompatibleWithLjava_lang_String() throws Exception {
+        Package p = getTestPackage("hyts_c.jar", "p.C");
+
+        assertTrue("Package isCompatibleWith fails with lower version", p
+                .isCompatibleWith("2.1.9.9"));
+        assertTrue("Package isCompatibleWith fails with same version (1)", p
+                .isCompatibleWith("2.2.0"));
+        assertTrue("Package isCompatibleWith fails with same version (2)", p
+                .isCompatibleWith("2.2"));
+        assertFalse("Package isCompatibleWith fails with higher version", p
+                .isCompatibleWith("2.2.0.0.1"));
+        try {
+            p.isCompatibleWith(null);
+            fail("Null version is illegal");
+        } catch (NumberFormatException ok) {
+        } catch (NullPointerException compatible) {
+            /*
+             * RI throws NPE instead of NFE...
+             */
+        }
+
+        try {
+            p.isCompatibleWith("");
+            fail("Empty version is illegal");
+        } catch (NumberFormatException ok) {
+        }
+        try {
+            p.isCompatibleWith(".");
+            fail("'.' version is illegal");
+        } catch (NumberFormatException ok) {
+        }
+        try {
+            p.isCompatibleWith("1.2.");
+            fail("'1.2.' version is illegal");
+        } catch (NumberFormatException ok) {
+        }
+        try {
+            p.isCompatibleWith(".9");
+            fail("'.9' version is illegal");
+        } catch (NumberFormatException ok) {
+        }
+        try {
+            p.isCompatibleWith("2.4..5");
+            fail("'2.4..5' version is illegal");
+        } catch (NumberFormatException ok) {
+        }
+        try {
+            p.isCompatibleWith("20.-4");
+            fail("'20.-4' version is illegal");
+        } catch (NumberFormatException ok) {
+        }
+    }
+
+    /**
+     * java.lang.Package#isSealed()
+     */
+    public void test_isSealed() throws Exception {
+        Package p = getTestPackage("hyts_pq.jar", "p.q.C");
+        assertTrue("Package isSealed returns wrong boolean", p.isSealed());
+    }
+
+    /**
+     * java.lang.Package#isSealed(java.net.URL)
+     */
+    public void test_isSealedLjava_net_URL() throws Exception {
+        Package p = getTestPackage("hyts_c.jar", "p.C");
+        assertFalse("Package isSealed returns wrong boolean (1)", p
+                .isSealed(new URL("file:/" + resPath + "/")));
+        assertTrue("Package isSealed returns wrong boolean (2)", p
+                .isSealed(new URL("file:/" + resPath + "/Package/hyts_c.jar")));
+    }
+
+    /**
+     * java.lang.Package#toString()
+     */
+    public void test_toString() throws Exception {
+        Package p = getTestPackage("hyts_c.jar", "p.C");
+        assertTrue("Package toString returns wrong string", p.toString()
+                .length() > 0);
+    }
+
+    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
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/ProcessBuilderTest.java b/luni/src/test/java/tests/api/java/lang/ProcessBuilderTest.java
new file mode 100644
index 0000000..9a9f178
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/ProcessBuilderTest.java
@@ -0,0 +1,174 @@
+/* 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.lang;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+public class ProcessBuilderTest extends TestCase {
+
+    public void testProcessBuilderStringArray() {
+
+    }
+
+    public void testProcessBuilderListOfString() {
+        try {
+            new ProcessBuilder((List<String>) null);
+            fail("no null pointer exception");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    public void testCommand() {
+        ProcessBuilder pb = new ProcessBuilder("command");
+        assertEquals(1, pb.command().size());
+        assertEquals("command", pb.command().get(0));
+
+        // Regression for HARMONY-2675
+        pb = new ProcessBuilder("AAA");
+        pb.command("BBB", "CCC");
+        List<String> list = pb.command();
+        list.add("DDD");
+        String[] command = new String[3];
+        list.toArray(command);
+        assertTrue(Arrays.equals(new String[] { "BBB", "CCC", "DDD" }, command));
+    }
+
+    public void testCommandStringArray() {
+        ProcessBuilder pb = new ProcessBuilder("command");
+        ProcessBuilder pbReturn = pb.command("cmd");
+        assertSame(pb, pbReturn);
+        assertEquals(1, pb.command().size());
+        assertEquals("cmd", pb.command().get(0));
+    }
+
+    public void testCommandListOfString() {
+        ProcessBuilder pb = new ProcessBuilder("command");
+        List<String> newCmd = new ArrayList<String>();
+        newCmd.add("cmd");
+        ProcessBuilder pbReturn = pb.command(newCmd);
+        assertSame(pb, pbReturn);
+        assertEquals(1, pb.command().size());
+        assertEquals("cmd", pb.command().get(0));
+
+        newCmd.add("arg");
+        assertEquals(2, pb.command().size());
+        assertEquals("cmd", pb.command().get(0));
+        assertEquals("arg", pb.command().get(1));
+    }
+
+    public void testDirectory() {
+        ProcessBuilder pb = new ProcessBuilder("command");
+        assertNull(pb.directory());
+    }
+
+    public void testDirectoryFile() {
+        ProcessBuilder pb = new ProcessBuilder("command");
+        File dir = new File(System.getProperty("java.io.tmpdir"));
+        ProcessBuilder pbReturn = pb.directory(dir);
+        assertSame(pb, pbReturn);
+        assertEquals(dir, pb.directory());
+
+        pbReturn = pb.directory(null);
+        assertSame(pb, pbReturn);
+        assertNull(pb.directory());
+    }
+
+    public void testEnvironment() {
+        ProcessBuilder pb = new ProcessBuilder("command");
+        Map<String, String> env = pb.environment();
+        assertEquals(System.getenv(), env);
+        env.clear();
+        env = pb.environment();
+        assertTrue(env.isEmpty());
+        try {
+            env.put(null, "");
+            fail("should throw NPE.");
+        } catch (NullPointerException e) {
+            // expected;
+        }
+        try {
+            env.put("", null);
+            fail("should throw NPE.");
+        } catch (NullPointerException e) {
+            // expected;
+        }
+        try {
+            env.get(null);
+            fail("should throw NPE.");
+        } catch (NullPointerException e) {
+            // expected;
+        }
+        try {
+            assertNull(env.get(new Object()));
+            // Android's get doesn't throw (because it's just a regular HashMap).
+            // fail("should throw ClassCastException.");
+        } catch (ClassCastException thrownByRi) {
+        }
+    }
+
+    public void testRedirectErrorStream() {
+        ProcessBuilder pb = new ProcessBuilder("command");
+        assertFalse(pb.redirectErrorStream());
+    }
+
+    public void testRedirectErrorStreamBoolean() {
+        ProcessBuilder pb = new ProcessBuilder("command");
+        ProcessBuilder pbReturn = pb.redirectErrorStream(true);
+        assertSame(pb, pbReturn);
+        assertTrue(pb.redirectErrorStream());
+    }
+
+    /**
+     * @throws IOException
+     * {@link java.lang.ProcessBuilder#start()}
+     */
+    @SuppressWarnings("nls")
+    public void testStart() throws IOException {
+        ProcessBuilder pb = new ProcessBuilder("java", "-version");
+        pb.directory(new File(System.getProperty("java.home") + File.separator
+                + "bin"));
+
+        // Call the test target
+        Process process = pb.start();
+        InputStream in = process.getInputStream();
+        InputStream err = process.getErrorStream();
+
+        while (true) {
+            try {
+                process.waitFor();
+                break;
+            } catch (InterruptedException e) {
+                // Ignored
+            }
+        }
+
+        byte[] buf = new byte[1024];
+        if (in.available() > 0) {
+            assertTrue(in.read(buf) > 0);
+        } else {
+            assertTrue(err.read(buf) > 0);
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/RuntimeExceptionTest.java b/luni/src/test/java/tests/api/java/lang/RuntimeExceptionTest.java
new file mode 100644
index 0000000..9d073e3
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/RuntimeExceptionTest.java
@@ -0,0 +1,59 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class RuntimeExceptionTest extends TestCase {
+
+    /**
+     * java.lang.RuntimeException#RuntimeException()
+     */
+    public void test_Constructor() {
+        RuntimeException e = new RuntimeException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.RuntimeException#RuntimeException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        RuntimeException e = new RuntimeException("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * {@link java.lang.RuntimeException#RuntimeException(Throwable)}
+     */
+    public void test_ConstructorLjava_lang_Throwable() {
+        Throwable emptyThrowable = new Exception();
+        RuntimeException emptyException = new RuntimeException(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");
+        RuntimeException exception = new RuntimeException(throwable);
+        assertEquals(throwable.getClass().getName() + ": " + "msg", exception.getMessage());
+        assertEquals(throwable.getClass().getName(), emptyException.getLocalizedMessage());
+        assertEquals(throwable.getClass().getName(), emptyException.getCause().toString());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/RuntimeTest.java b/luni/src/test/java/tests/api/java/lang/RuntimeTest.java
new file mode 100644
index 0000000..5a75c73
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/RuntimeTest.java
@@ -0,0 +1,159 @@
+/*
+ *  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.lang;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Vector;
+
+public class RuntimeTest extends junit.framework.TestCase {
+
+    Runtime r = Runtime.getRuntime();
+
+    InputStream is;
+
+    String s;
+
+    static boolean flag = false;
+
+    static boolean ranFinalize = false;
+
+    class HasFinalizer {
+        String internalString;
+
+        HasFinalizer(String s) {
+            internalString = s;
+        }
+
+        @Override
+        protected void finalize() {
+            internalString = "hit";
+        }
+    }
+
+    @Override
+    protected void finalize() {
+        if (flag)
+            ranFinalize = true;
+    }
+
+    protected RuntimeTest createInstance() {
+        return new RuntimeTest("FT");
+    }
+
+    /**
+     * java.lang.Runtime#exit(int)
+     */
+    public void test_exitI() {
+        // Test for method void java.lang.Runtime.exit(int)
+        assertTrue("Can't really test this", true);
+    }
+
+    /**
+     * java.lang.Runtime#exec(java.lang.String)
+     */
+    public void test_exec() {
+        boolean success = false;
+
+        /* successful exec's are tested by java.lang.Process */
+        try {
+            Runtime.getRuntime().exec("AnInexistentProgram");
+        } catch (IOException e) {
+            success = true;
+        }
+        assertTrue(
+                "failed to throw IOException when exec'ed inexistent program",
+                success);
+    }
+
+    /**
+     * java.lang.Runtime#freeMemory()
+     */
+    public void test_freeMemory() {
+        // Test for method long java.lang.Runtime.freeMemory()
+        assertTrue("freeMemory returned nonsense value", r.freeMemory() > 0);
+    }
+
+    /**
+     * java.lang.Runtime#gc()
+     */
+    public void test_gc() {
+        // Test for method void java.lang.Runtime.gc()
+        try {
+            r.gc(); // ensure all garbage objects have been collected
+            r.gc(); // two GCs force collection phase to complete
+            long firstRead = r.totalMemory() - r.freeMemory();
+            Vector<StringBuffer> v = new Vector<StringBuffer>();
+            for (int i = 1; i < 10; i++)
+                v.addElement(new StringBuffer(10000));
+            long secondRead = r.totalMemory() - r.freeMemory();
+            v = null;
+            r.gc();
+            r.gc();
+            assertTrue("object memory did not grow", secondRead > firstRead);
+            assertTrue("space was not reclaimed", (r.totalMemory() - r
+                    .freeMemory()) < secondRead);
+        } catch (OutOfMemoryError oome) {
+            System.out.println("Out of memory during freeMemory test");
+            r.gc();
+            r.gc();
+        }
+    }
+
+    /**
+     * java.lang.Runtime#getRuntime()
+     */
+    public void test_getRuntime() {
+        // Test for method java.lang.Runtime java.lang.Runtime.getRuntime()
+        assertTrue("Used to test", true);
+    }
+
+    /**
+     * java.lang.Runtime#runFinalization()
+     */
+    public void test_runFinalization() {
+        // Test for method void java.lang.Runtime.runFinalization()
+
+        flag = true;
+        createInstance();
+        int count = 10;
+        // the gc below likely bogosifies the test, but will have to do for
+        // the moment
+        while (!ranFinalize && count-- > 0) {
+            r.gc();
+            r.runFinalization();
+        }
+        assertTrue("Failed to run finalization", ranFinalize);
+    }
+
+    /**
+     * java.lang.Runtime#totalMemory()
+     */
+    public void test_totalMemory() {
+        // Test for method long java.lang.Runtime.totalMemory()
+        assertTrue("totalMemory returned nonsense value", r.totalMemory() >= r
+                .freeMemory());
+    }
+
+    public RuntimeTest() {
+    }
+
+    public RuntimeTest(String name) {
+        super(name);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/SecurityExceptionTest.java b/luni/src/test/java/tests/api/java/lang/SecurityExceptionTest.java
new file mode 100644
index 0000000..fb63ef8
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/SecurityExceptionTest.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 tests.api.java.lang;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class SecurityExceptionTest extends TestCase {
+
+    /**
+     * java.lang.SecurityException#SecurityException()
+     */
+    public void test_Constructor() {
+        SecurityException e = new SecurityException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.SecurityException#SecurityException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        SecurityException e = new SecurityException("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.SecurityException#SecurityException(String, Throwable)
+     */
+    @SuppressWarnings("nls")
+    public void test_ConstructorLjava_lang_StringLjava_lang_Throwable() {
+        NullPointerException npe = new NullPointerException();
+        SecurityException e = new SecurityException("fixture", npe);
+        assertSame("fixture", e.getMessage());
+        assertSame(npe, e.getCause());
+    }
+
+    /**
+     * java.lang.SecurityException#SecurityException(Throwable)
+     */
+    @SuppressWarnings("nls")
+    public void test_ConstructorLjava_lang_Throwable() {
+        NullPointerException npe = new NullPointerException();
+        SecurityException e = new SecurityException(npe);
+        assertSame(npe, e.getCause());
+    }
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        SerializationTest.verifySelf(new SecurityException());
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        SerializationTest.verifyGolden(this, new SecurityException());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/ShortTest.java b/luni/src/test/java/tests/api/java/lang/ShortTest.java
new file mode 100644
index 0000000..8cbe385
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/ShortTest.java
@@ -0,0 +1,684 @@
+/* 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.lang;
+
+import junit.framework.TestCase;
+
+public class ShortTest extends TestCase {
+    private Short sp = new Short((short) 18000);
+    private Short sn = new Short((short) -19000);
+
+    /**
+     * java.lang.Short#byteValue()
+     */
+    public void test_byteValue() {
+        // Test for method byte java.lang.Short.byteValue()
+        assertEquals("Returned incorrect byte value", 0, new Short(Short.MIN_VALUE)
+                .byteValue());
+        assertEquals("Returned incorrect byte value", -1, new Short(Short.MAX_VALUE)
+                .byteValue());
+    }
+
+    /**
+     * java.lang.Short#compareTo(java.lang.Short)
+     */
+    public void test_compareToLjava_lang_Short() {
+        // Test for method int java.lang.Short.compareTo(java.lang.Short)
+        Short s = new Short((short) 1);
+        Short x = new Short((short) 3);
+        assertTrue(
+                "Should have returned negative value when compared to greater short",
+                s.compareTo(x) < 0);
+        x = new Short((short) -1);
+        assertTrue(
+                "Should have returned positive value when compared to lesser short",
+                s.compareTo(x) > 0);
+        x = new Short((short) 1);
+        assertEquals("Should have returned zero when compared to equal short",
+                0, s.compareTo(x));
+
+        try {
+            new Short((short) 0).compareTo(null);
+            fail("No NPE");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    /**
+     * java.lang.Short#decode(java.lang.String)
+     */
+    public void test_decodeLjava_lang_String2() {
+        // Test for method java.lang.Short
+        // java.lang.Short.decode(java.lang.String)
+        assertTrue("Did not decode -1 correctly", Short.decode("-1")
+                .shortValue() == (short) -1);
+        assertTrue("Did not decode -100 correctly", Short.decode("-100")
+                .shortValue() == (short) -100);
+        assertTrue("Did not decode 23 correctly", Short.decode("23")
+                .shortValue() == (short) 23);
+        assertTrue("Did not decode 0x10 correctly", Short.decode("0x10")
+                .shortValue() == (short) 16);
+        assertTrue("Did not decode 32767 correctly", Short.decode("32767")
+                .shortValue() == (short) 32767);
+        assertTrue("Did not decode -32767 correctly", Short.decode("-32767")
+                .shortValue() == (short) -32767);
+        assertTrue("Did not decode -32768 correctly", Short.decode("-32768")
+                .shortValue() == (short) -32768);
+
+        boolean exception = false;
+        try {
+            Short.decode("123s");
+        } catch (NumberFormatException e) {
+            // correct
+            exception = true;
+        }
+        assertTrue("Did not throw NumberFormatException decoding 123s",
+                exception);
+
+        exception = false;
+        try {
+            Short.decode("32768");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for MAX_VALUE + 1", exception);
+
+        exception = false;
+        try {
+            Short.decode("-32769");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for MIN_VALUE - 1", exception);
+
+        exception = false;
+        try {
+            Short.decode("0x8000");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for hex MAX_VALUE + 1", exception);
+
+        exception = false;
+        try {
+            Short.decode("-0x8001");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for hex MIN_VALUE - 1", exception);
+    }
+
+    /**
+     * java.lang.Short#parseShort(java.lang.String)
+     */
+    public void test_parseShortLjava_lang_String2() {
+        // Test for method short java.lang.Short.parseShort(java.lang.String)
+        short sp = Short.parseShort("32746");
+        short sn = Short.parseShort("-32746");
+
+        assertTrue("Incorrect parse of short", sp == (short) 32746
+                && (sn == (short) -32746));
+        assertEquals("Returned incorrect value for 0", 0, Short.parseShort("0"));
+        assertTrue("Returned incorrect value for most negative value", Short
+                .parseShort("-32768") == (short) 0x8000);
+        assertTrue("Returned incorrect value for most positive value", Short
+                .parseShort("32767") == 0x7fff);
+
+        boolean exception = false;
+        try {
+            Short.parseShort("32768");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for MAX_VALUE + 1", exception);
+
+        exception = false;
+        try {
+            Short.parseShort("-32769");
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for MIN_VALUE - 1", exception);
+    }
+
+    /**
+     * java.lang.Short#parseShort(java.lang.String, int)
+     */
+    public void test_parseShortLjava_lang_StringI2() {
+        // Test for method short java.lang.Short.parseShort(java.lang.String,
+        // int)
+        boolean aThrow = true;
+        assertEquals("Incorrectly parsed hex string",
+                255, Short.parseShort("FF", 16));
+        assertEquals("Incorrectly parsed oct string",
+                16, Short.parseShort("20", 8));
+        assertEquals("Incorrectly parsed dec string",
+                20, Short.parseShort("20", 10));
+        assertEquals("Incorrectly parsed bin string",
+                4, Short.parseShort("100", 2));
+        assertEquals("Incorrectly parsed -hex string", -255, Short
+                .parseShort("-FF", 16));
+        assertEquals("Incorrectly parsed -oct string",
+                -16, Short.parseShort("-20", 8));
+        assertEquals("Incorrectly parsed -bin string", -4, Short
+                .parseShort("-100", 2));
+        assertEquals("Returned incorrect value for 0 hex", 0, Short.parseShort("0",
+                16));
+        assertTrue("Returned incorrect value for most negative value hex",
+                Short.parseShort("-8000", 16) == (short) 0x8000);
+        assertTrue("Returned incorrect value for most positive value hex",
+                Short.parseShort("7fff", 16) == 0x7fff);
+        assertEquals("Returned incorrect value for 0 decimal", 0, Short.parseShort(
+                "0", 10));
+        assertTrue("Returned incorrect value for most negative value decimal",
+                Short.parseShort("-32768", 10) == (short) 0x8000);
+        assertTrue("Returned incorrect value for most positive value decimal",
+                Short.parseShort("32767", 10) == 0x7fff);
+
+        try {
+            Short.parseShort("FF", 2);
+        } catch (NumberFormatException e) {
+            // Correct
+            aThrow = false;
+        }
+        if (aThrow) {
+            fail(
+                    "Failed to throw exception when passed hex string and base 2 radix");
+        }
+
+        boolean exception = false;
+        try {
+            Short.parseShort("10000000000", 10);
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue(
+                "Failed to throw exception when passed string larger than 16 bits",
+                exception);
+
+        exception = false;
+        try {
+            Short.parseShort("32768", 10);
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for MAX_VALUE + 1", exception);
+
+        exception = false;
+        try {
+            Short.parseShort("-32769", 10);
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for MIN_VALUE - 1", exception);
+
+        exception = false;
+        try {
+            Short.parseShort("8000", 16);
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for hex MAX_VALUE + 1", exception);
+
+        exception = false;
+        try {
+            Short.parseShort("-8001", 16);
+        } catch (NumberFormatException e) {
+            // Correct
+            exception = true;
+        }
+        assertTrue("Failed to throw exception for hex MIN_VALUE + 1", exception);
+    }
+
+    /**
+     * java.lang.Short#toString()
+     */
+    public void test_toString2() {
+        // Test for method java.lang.String java.lang.Short.toString()
+        assertTrue("Invalid string returned", sp.toString().equals("18000")
+                && (sn.toString().equals("-19000")));
+        assertEquals("Returned incorrect string", "32767", new Short((short) 32767)
+                .toString());
+        assertEquals("Returned incorrect string", "-32767", new Short((short) -32767)
+                .toString());
+        assertEquals("Returned incorrect string", "-32768", new Short((short) -32768)
+                .toString());
+    }
+
+    /**
+     * java.lang.Short#toString(short)
+     */
+    public void test_toStringS2() {
+        // Test for method java.lang.String java.lang.Short.toString(short)
+        assertEquals("Returned incorrect string", "32767", Short.toString((short) 32767)
+        );
+        assertEquals("Returned incorrect string", "-32767", Short.toString((short) -32767)
+        );
+        assertEquals("Returned incorrect string", "-32768", Short.toString((short) -32768)
+        );
+    }
+
+    /**
+     * java.lang.Short#valueOf(java.lang.String)
+     */
+    public void test_valueOfLjava_lang_String2() {
+        // Test for method java.lang.Short
+        // java.lang.Short.valueOf(java.lang.String)
+        assertEquals("Returned incorrect short", -32768, Short.valueOf("-32768")
+                .shortValue());
+        assertEquals("Returned incorrect short", 32767, Short.valueOf("32767")
+                .shortValue());
+    }
+
+    /**
+     * java.lang.Short#valueOf(java.lang.String, int)
+     */
+    public void test_valueOfLjava_lang_StringI2() {
+        // Test for method java.lang.Short
+        // java.lang.Short.valueOf(java.lang.String, int)
+        boolean aThrow = true;
+        assertEquals("Incorrectly parsed hex string", 255, Short.valueOf("FF", 16)
+                .shortValue());
+        assertEquals("Incorrectly parsed oct string", 16, Short.valueOf("20", 8)
+                .shortValue());
+        assertEquals("Incorrectly parsed dec string", 20, Short.valueOf("20", 10)
+                .shortValue());
+        assertEquals("Incorrectly parsed bin string", 4, Short.valueOf("100", 2)
+                .shortValue());
+        assertEquals("Incorrectly parsed -hex string", -255, Short.valueOf("-FF", 16)
+                .shortValue());
+        assertEquals("Incorrectly parsed -oct string", -16, Short.valueOf("-20", 8)
+                .shortValue());
+        assertEquals("Incorrectly parsed -bin string", -4, Short.valueOf("-100", 2)
+                .shortValue());
+        assertTrue("Did not decode 32767 correctly", Short.valueOf("32767", 10)
+                .shortValue() == (short) 32767);
+        assertTrue("Did not decode -32767 correctly", Short.valueOf("-32767",
+                10).shortValue() == (short) -32767);
+        assertTrue("Did not decode -32768 correctly", Short.valueOf("-32768",
+                10).shortValue() == (short) -32768);
+        try {
+            Short.valueOf("FF", 2);
+        } catch (NumberFormatException e) {
+            // Correct
+            aThrow = false;
+        }
+        if (aThrow) {
+            fail(
+                    "Failed to throw exception when passed hex string and base 2 radix");
+        }
+        try {
+            Short.valueOf("10000000000", 10);
+        } catch (NumberFormatException e) {
+            // Correct
+            return;
+        }
+        fail(
+                "Failed to throw exception when passed string larger than 16 bits");
+    }
+
+    /**
+     * 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++;
+        }
+    }
+
+    /**
+     * java.lang.Short#hashCode()
+     */
+    public void test_hashCode() {
+        assertEquals(1, new Short((short) 1).hashCode());
+        assertEquals(2, new Short((short) 2).hashCode());
+        assertEquals(0, new Short((short) 0).hashCode());
+        assertEquals(-1, new Short((short) -1).hashCode());
+    }
+
+    /**
+     * java.lang.Short#Short(String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        assertEquals(new Short((short) 0), new Short("0"));
+        assertEquals(new Short((short) 1), new Short("1"));
+        assertEquals(new Short((short) -1), new Short("-1"));
+
+        try {
+            new Short("0x1");
+            fail("Expected NumberFormatException with hex string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            new Short("9.2");
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            new Short("");
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            new Short(null);
+            fail("Expected NumberFormatException with null string.");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Short#Short(short)
+     */
+    public void test_ConstructorS() {
+        assertEquals(1, new Short((short) 1).shortValue());
+        assertEquals(2, new Short((short) 2).shortValue());
+        assertEquals(0, new Short((short) 0).shortValue());
+        assertEquals(-1, new Short((short) -1).shortValue());
+    }
+
+    /**
+     * java.lang.Short#byteValue()
+     */
+    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());
+        assertEquals(-1, new Short((short) -1).byteValue());
+    }
+
+    /**
+     * java.lang.Short#equals(Object)
+     */
+    public void test_equalsLjava_lang_Object() {
+        assertEquals(new Short((short) 0), Short.valueOf((short) 0));
+        assertEquals(new Short((short) 1), Short.valueOf((short) 1));
+        assertEquals(new Short((short) -1), Short.valueOf((short) -1));
+
+        Short fixture = new Short((short) 25);
+        assertEquals(fixture, fixture);
+        assertFalse(fixture.equals(null));
+        assertFalse(fixture.equals("Not a Short"));
+    }
+
+    /**
+     * java.lang.Short#toString()
+     */
+    public void test_toString() {
+        assertEquals("-1", new Short((short) -1).toString());
+        assertEquals("0", new Short((short) 0).toString());
+        assertEquals("1", new Short((short) 1).toString());
+        assertEquals("-1", new Short((short) 0xFFFF).toString());
+    }
+
+    /**
+     * java.lang.Short#toString(short)
+     */
+    public void test_toStringS() {
+        assertEquals("-1", Short.toString((short) -1));
+        assertEquals("0", Short.toString((short) 0));
+        assertEquals("1", Short.toString((short) 1));
+        assertEquals("-1", Short.toString((short) 0xFFFF));
+    }
+
+    /**
+     * java.lang.Short#valueOf(String)
+     */
+    public void test_valueOfLjava_lang_String() {
+        assertEquals(new Short((short) 0), Short.valueOf("0"));
+        assertEquals(new Short((short) 1), Short.valueOf("1"));
+        assertEquals(new Short((short) -1), Short.valueOf("-1"));
+
+        try {
+            Short.valueOf("0x1");
+            fail("Expected NumberFormatException with hex string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Short.valueOf("9.2");
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Short.valueOf("");
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Short.valueOf(null);
+            fail("Expected NumberFormatException with null string.");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Short#valueOf(String, int)
+     */
+    public void test_valueOfLjava_lang_StringI() {
+        assertEquals(new Short((short) 0), Short.valueOf("0", 10));
+        assertEquals(new Short((short) 1), Short.valueOf("1", 10));
+        assertEquals(new Short((short) -1), Short.valueOf("-1", 10));
+
+        //must be consistent with Character.digit()
+        assertEquals(Character.digit('1', 2), Short.valueOf("1", 2).byteValue());
+        assertEquals(Character.digit('F', 16), Short.valueOf("F", 16).byteValue());
+
+        try {
+            Short.valueOf("0x1", 10);
+            fail("Expected NumberFormatException with hex string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Short.valueOf("9.2", 10);
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Short.valueOf("", 10);
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Short.valueOf(null, 10);
+            fail("Expected NumberFormatException with null string.");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Short#parseShort(String)
+     */
+    public void test_parseShortLjava_lang_String() {
+        assertEquals(0, Short.parseShort("0"));
+        assertEquals(1, Short.parseShort("1"));
+        assertEquals(-1, Short.parseShort("-1"));
+
+        try {
+            Short.parseShort("0x1");
+            fail("Expected NumberFormatException with hex string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Short.parseShort("9.2");
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Short.parseShort("");
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Short.parseShort(null);
+            fail("Expected NumberFormatException with null string.");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Short#parseShort(String, int)
+     */
+    public void test_parseShortLjava_lang_StringI() {
+        assertEquals(0, Short.parseShort("0", 10));
+        assertEquals(1, Short.parseShort("1", 10));
+        assertEquals(-1, Short.parseShort("-1", 10));
+
+        //must be consistent with Character.digit()
+        assertEquals(Character.digit('1', 2), Short.parseShort("1", 2));
+        assertEquals(Character.digit('F', 16), Short.parseShort("F", 16));
+
+        try {
+            Short.parseShort("0x1", 10);
+            fail("Expected NumberFormatException with hex string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Short.parseShort("9.2", 10);
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Short.parseShort("", 10);
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Short.parseShort(null, 10);
+            fail("Expected NumberFormatException with null string.");
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    /**
+     * java.lang.Short#decode(String)
+     */
+    public void test_decodeLjava_lang_String() {
+        assertEquals(new Short((short) 0), Short.decode("0"));
+        assertEquals(new Short((short) 1), Short.decode("1"));
+        assertEquals(new Short((short) -1), Short.decode("-1"));
+        assertEquals(new Short((short) 0xF), Short.decode("0xF"));
+        assertEquals(new Short((short) 0xF), Short.decode("#F"));
+        assertEquals(new Short((short) 0xF), Short.decode("0XF"));
+        assertEquals(new Short((short) 07), Short.decode("07"));
+
+        try {
+            Short.decode("9.2");
+            fail("Expected NumberFormatException with floating point string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Short.decode("");
+            fail("Expected NumberFormatException with empty string.");
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            Short.decode(null);
+            //undocumented NPE, but seems consistent across JREs
+            fail("Expected NullPointerException with null string.");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    /**
+     * java.lang.Short#doubleValue()
+     */
+    public void test_doubleValue() {
+        assertEquals(-1D, new Short((short) -1).doubleValue(), 0D);
+        assertEquals(0D, new Short((short) 0).doubleValue(), 0D);
+        assertEquals(1D, new Short((short) 1).doubleValue(), 0D);
+    }
+
+    /**
+     * java.lang.Short#floatValue()
+     */
+    public void test_floatValue() {
+        assertEquals(-1F, new Short((short) -1).floatValue(), 0F);
+        assertEquals(0F, new Short((short) 0).floatValue(), 0F);
+        assertEquals(1F, new Short((short) 1).floatValue(), 0F);
+    }
+
+    /**
+     * java.lang.Short#intValue()
+     */
+    public void test_intValue() {
+        assertEquals(-1, new Short((short) -1).intValue());
+        assertEquals(0, new Short((short) 0).intValue());
+        assertEquals(1, new Short((short) 1).intValue());
+    }
+
+    /**
+     * java.lang.Short#longValue()
+     */
+    public void test_longValue() {
+        assertEquals(-1L, new Short((short) -1).longValue());
+        assertEquals(0L, new Short((short) 0).longValue());
+        assertEquals(1L, new Short((short) 1).longValue());
+    }
+
+    /**
+     * java.lang.Short#shortValue()
+     */
+    public void test_shortValue() {
+        assertEquals(-1, new Short((short) -1).shortValue());
+        assertEquals(0, new Short((short) 0).shortValue());
+        assertEquals(1, new Short((short) 1).shortValue());
+    }
+
+    /**
+     * java.lang.Short#reverseBytes(short)
+     */
+    public void test_reverseBytesS() {
+        assertEquals((short) 0xABCD, Short.reverseBytes((short) 0xCDAB));
+        assertEquals((short) 0x1234, Short.reverseBytes((short) 0x3412));
+        assertEquals((short) 0x0011, Short.reverseBytes((short) 0x1100));
+        assertEquals((short) 0x2002, Short.reverseBytes((short) 0x0220));
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/lang/StackOverflowErrorTest.java b/luni/src/test/java/tests/api/java/lang/StackOverflowErrorTest.java
new file mode 100644
index 0000000..1e81ab6
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/StackOverflowErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class StackOverflowErrorTest extends TestCase {
+
+    /**
+     * java.lang.StackOverflowError#StackOverflowError()
+     */
+    public void test_Constructor() {
+        StackOverflowError e = new StackOverflowError();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.StackOverflowError#StackOverflowError(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        StackOverflowError e = new StackOverflowError("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/StrictMathTest.java b/luni/src/test/java/tests/api/java/lang/StrictMathTest.java
new file mode 100644
index 0000000..8141b2c
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/StrictMathTest.java
@@ -0,0 +1,1490 @@
+/*
+ *  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.lang;
+
+import static tests.api.java.lang.MathTest.COPYSIGN_DD_CASES;
+import static tests.api.java.lang.MathTest.COPYSIGN_FF_CASES;
+import static tests.api.java.lang.MathTest.GETEXPONENT_D_CASES;
+import static tests.api.java.lang.MathTest.GETEXPONENT_D_RESULTS;
+import static tests.api.java.lang.MathTest.GETEXPONENT_F_CASES;
+import static tests.api.java.lang.MathTest.GETEXPONENT_F_RESULTS;
+import static tests.api.java.lang.MathTest.NEXTAFTER_DD_START_CASES;
+import static tests.api.java.lang.MathTest.NEXTAFTER_DD_FD_DIRECTION_CASES;
+import static tests.api.java.lang.MathTest.NEXTAFTER_FD_START_CASES;
+
+public class StrictMathTest extends junit.framework.TestCase {
+
+    private static final double HYP = StrictMath.sqrt(2.0);
+
+    private static final double OPP = 1.0;
+
+    private static final double ADJ = 1.0;
+
+    /* Required to make previous preprocessor flags work - do not remove */
+    int unused = 0;
+
+    /**
+     * java.lang.StrictMath#abs(double)
+     */
+    public void test_absD() {
+        // Test for method double java.lang.StrictMath.abs(double)
+
+        assertTrue("Incorrect double abs value",
+                (StrictMath.abs(-1908.8976) == 1908.8976));
+        assertTrue("Incorrect double abs value",
+                (StrictMath.abs(1908.8976) == 1908.8976));
+    }
+
+    /**
+     * 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));
+    }
+
+    /**
+     * 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));
+    }
+
+    /**
+     * 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));
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * java.lang.StrictMath#cbrt(double)
+     */
+    @SuppressWarnings("boxing")
+    public void test_cbrt_D() {
+        // Test for special situations
+        assertTrue("Should return Double.NaN", Double.isNaN(StrictMath
+                .cbrt(Double.NaN)));
+        assertEquals("Should return Double.POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, StrictMath
+                .cbrt(Double.POSITIVE_INFINITY));
+        assertEquals("Should return Double.NEGATIVE_INFINITY",
+                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)));
+
+        assertEquals("Should return 3.0", 3.0, StrictMath.cbrt(27.0));
+        assertEquals("Should return 23.111993172558684", 23.111993172558684,
+                StrictMath.cbrt(12345.6));
+        assertEquals("Should return 5.643803094122362E102",
+                5.643803094122362E102, StrictMath.cbrt(Double.MAX_VALUE));
+        assertEquals("Should return 0.01", 0.01, StrictMath.cbrt(0.000001));
+
+        assertEquals("Should return -3.0", -3.0, StrictMath.cbrt(-27.0));
+        assertEquals("Should return -23.111993172558684", -23.111993172558684,
+                StrictMath.cbrt(-12345.6));
+        assertEquals("Should return 1.7031839360032603E-108",
+                1.7031839360032603E-108, StrictMath.cbrt(Double.MIN_VALUE));
+        assertEquals("Should return -0.01", -0.01, StrictMath.cbrt(-0.000001));
+
+        try {
+            StrictMath.cbrt((Double) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            //expected
+        }
+    }
+
+    /**
+     * 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",
+                -78, StrictMath.ceil(-78.89), 0.0);
+    }
+
+    /**
+     * {@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
+        }
+
+        double d = Double.longBitsToDouble(0xfff8000000000000L);
+        assertEquals(1.0, StrictMath.copySign(1.0, d), 0d);
+    }
+
+    /**
+     * {@link java.lang.StrictMath#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(StrictMath
+                    .abs(magnitude));
+            final int negMagnitudeBits = Float.floatToIntBits(-StrictMath
+                    .abs(magnitude));
+
+            // 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);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * java.lang.StrictMath#cosh(double)
+     */
+    @SuppressWarnings("boxing")
+    public void test_cosh_D() {
+        // Test for special situations        
+        assertTrue("Should return NaN", Double.isNaN(StrictMath
+                .cosh(Double.NaN)));
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, StrictMath
+                .cosh(Double.POSITIVE_INFINITY));
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, StrictMath
+                .cosh(Double.NEGATIVE_INFINITY));
+        assertEquals("Should return 1.0", 1.0, StrictMath.cosh(+0.0));
+        assertEquals("Should return 1.0", 1.0, StrictMath.cosh(-0.0));
+
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, StrictMath.cosh(1234.56));
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, StrictMath.cosh(-1234.56));
+        assertEquals("Should return 1.0000000000005", 1.0000000000005,
+                StrictMath.cosh(0.000001));
+        assertEquals("Should return 1.0000000000005", 1.0000000000005,
+                StrictMath.cosh(-0.000001));
+        assertEquals("Should return 5.212214351945598", 5.212214351945598,
+                StrictMath.cosh(2.33482));
+
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, StrictMath.cosh(Double.MAX_VALUE));
+        assertEquals("Should return 1.0", 1.0, StrictMath
+                .cosh(Double.MIN_VALUE));
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * java.lang.StrictMath#expm1(double)
+     */
+    @SuppressWarnings("boxing")
+    public void test_expm1_D() {
+        //Test for special cases        
+        assertTrue("Should return NaN", Double.isNaN(StrictMath.expm1(Double.NaN)));
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, StrictMath.expm1(Double.POSITIVE_INFINITY));
+        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)));
+
+        assertEquals("Should return -9.999950000166666E-6",
+                -9.999950000166666E-6, StrictMath.expm1(-0.00001));
+        assertEquals("Should return 1.0145103074469635E60",
+                1.0145103074469635E60, StrictMath.expm1(138.16951162));
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, StrictMath
+                .expm1(123456789123456789123456789.4521584223));
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, StrictMath.expm1(Double.MAX_VALUE));
+        assertEquals("Should return MIN_VALUE", Double.MIN_VALUE, StrictMath
+                .expm1(Double.MIN_VALUE));
+
+    }
+
+    /**
+     * 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",
+                -79, StrictMath.floor(-78.89), 0.0);
+    }
+
+    /**
+     * {@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
+        }
+    }
+
+    /**
+     * {@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
+        }
+    }
+
+    /**
+     * java.lang.StrictMath#hypot(double, double)
+     */
+    @SuppressWarnings("boxing")
+    public void test_hypot_DD() {
+        // Test for special cases
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, StrictMath.hypot(Double.POSITIVE_INFINITY,
+                1.0));
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, StrictMath.hypot(Double.NEGATIVE_INFINITY,
+                123.324));
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, StrictMath.hypot(-758.2587,
+                Double.POSITIVE_INFINITY));
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, StrictMath.hypot(5687.21,
+                Double.NEGATIVE_INFINITY));
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, StrictMath.hypot(Double.POSITIVE_INFINITY,
+                Double.NEGATIVE_INFINITY));
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, StrictMath.hypot(Double.NEGATIVE_INFINITY,
+                Double.POSITIVE_INFINITY));
+        assertTrue("Should return NaN", Double.isNaN(StrictMath.hypot(Double.NaN,
+                2342301.89843)));
+        assertTrue("Should return NaN", Double.isNaN(StrictMath.hypot(-345.2680,
+                Double.NaN)));
+
+        assertEquals("Should return 2396424.905416697", 2396424.905416697, StrictMath
+                .hypot(12322.12, -2396393.2258));
+        assertEquals("Should return 138.16958070558556", 138.16958070558556,
+                StrictMath.hypot(-138.16951162, 0.13817035864));
+        assertEquals("Should return 1.7976931348623157E308",
+                1.7976931348623157E308, StrictMath.hypot(Double.MAX_VALUE, 211370.35));
+        assertEquals("Should return 5413.7185", 5413.7185, StrictMath.hypot(
+                -5413.7185, Double.MIN_VALUE));
+
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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));
+        }
+    }
+
+    /**
+     * java.lang.StrictMath#log10(double)
+     */
+    @SuppressWarnings("boxing")
+    public void test_log10_D() {
+        // Test for special cases        
+        assertTrue("Should return NaN", Double.isNaN(StrictMath
+                .log10(Double.NaN)));
+        assertTrue("Should return NaN", Double.isNaN(StrictMath
+                .log10(-2541.05745687234187532)));
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, StrictMath
+                .log10(Double.POSITIVE_INFINITY));
+        assertEquals("Should return NEGATIVE_INFINITY",
+                Double.NEGATIVE_INFINITY, StrictMath.log10(0.0));
+        assertEquals("Should return NEGATIVE_INFINITY",
+                Double.NEGATIVE_INFINITY, StrictMath.log10(+0.0));
+        assertEquals("Should return NEGATIVE_INFINITY",
+                Double.NEGATIVE_INFINITY, StrictMath.log10(-0.0));
+        assertEquals("Should return 14.0", 14.0, StrictMath.log10(StrictMath
+                .pow(10, 14)));
+
+        assertEquals("Should return 3.7389561269540406", 3.7389561269540406,
+                StrictMath.log10(5482.2158));
+        assertEquals("Should return 14.661551142893833", 14.661551142893833,
+                StrictMath.log10(458723662312872.125782332587));
+        assertEquals("Should return -0.9083828622192334", -0.9083828622192334,
+                StrictMath.log10(0.12348583358871));
+        assertEquals("Should return 308.25471555991675", 308.25471555991675,
+                StrictMath.log10(Double.MAX_VALUE));
+        assertEquals("Should return -323.3062153431158", -323.3062153431158,
+                StrictMath.log10(Double.MIN_VALUE));
+    }
+
+    /**
+     * java.lang.StrictMath#log1p(double)
+     */
+    @SuppressWarnings("boxing")
+    public void test_log1p_D() {
+        // Test for special cases
+        assertTrue("Should return NaN", Double.isNaN(StrictMath
+                .log1p(Double.NaN)));
+        assertTrue("Should return NaN", Double.isNaN(StrictMath
+                .log1p(-32.0482175)));
+        assertEquals("Should return POSITIVE_INFINITY",
+                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)));
+
+        assertEquals("Should return -0.2941782295312541", -0.2941782295312541,
+                StrictMath.log1p(-0.254856327));
+        assertEquals("Should return 7.368050685564151", 7.368050685564151,
+                StrictMath.log1p(1583.542));
+        assertEquals("Should return 0.4633708685409921", 0.4633708685409921,
+                StrictMath.log1p(0.5894227));
+        assertEquals("Should return 709.782712893384", 709.782712893384,
+                StrictMath.log1p(Double.MAX_VALUE));
+        assertEquals("Should return Double.MIN_VALUE", Double.MIN_VALUE,
+                StrictMath.log1p(Double.MIN_VALUE));
+    }
+
+    /**
+     * java.lang.StrictMath#max(double, double)
+     */
+    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);
+
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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));
+    }
+
+    /**
+     * 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));
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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));
+
+    }
+
+    /**
+     * 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));
+    }
+
+    /**
+     * {@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
+        }
+    }
+
+    /**
+     * {@link java.lang.StrictMath#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(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
+        }
+    }
+
+    /**
+     * {@link java.lang.StrictMath#nextUp(double)}
+     * @since 1.6
+     */
+    @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
+        }
+    }
+
+    /**
+     * {@link java.lang.StrictMath#nextUp(float)}
+     * @since 1.6
+     */
+    @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
+        }
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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));
+    }
+
+    /**
+     * 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));
+    }
+
+    /**
+     * {@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
+        }
+    }
+
+    /**
+     * {@link java.lang.StrictMath#scalb(float, int)}
+     * @since 1.6
+     */
+    @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));
+
+        float normal = StrictMath.scalb(0.2345f, -25);
+        assertEquals(6.98864459991455E-9f, normal);
+        // precision kept
+        assertEquals(0.2345f, StrictMath.scalb(normal, 25));
+
+        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));
+
+        // 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));
+
+        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);
+
+        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(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));
+
+        // 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)));
+
+        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)));
+
+        // 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
+        }
+    }
+
+    /**
+     * java.lang.StrictMath#signum(double)
+     */
+    public void test_signum_D() {
+        assertTrue(Double.isNaN(StrictMath.signum(Double.NaN)));
+        assertEquals(Double.doubleToLongBits(0.0), Double
+                .doubleToLongBits(StrictMath.signum(0.0)));
+        assertEquals(Double.doubleToLongBits(+0.0), Double
+                .doubleToLongBits(StrictMath.signum(+0.0)));
+        assertEquals(Double.doubleToLongBits(-0.0), Double
+                .doubleToLongBits(StrictMath.signum(-0.0)));
+
+        assertEquals(1.0, StrictMath.signum(253681.2187962), 0D);
+        assertEquals(-1.0, StrictMath.signum(-125874693.56), 0D);
+        assertEquals(1.0, StrictMath.signum(1.2587E-308), 0D);
+        assertEquals(-1.0, StrictMath.signum(-1.2587E-308), 0D);
+
+        assertEquals(1.0, StrictMath.signum(Double.MAX_VALUE), 0D);
+        assertEquals(1.0, StrictMath.signum(Double.MIN_VALUE), 0D);
+        assertEquals(-1.0, StrictMath.signum(-Double.MAX_VALUE), 0D);
+        assertEquals(-1.0, StrictMath.signum(-Double.MIN_VALUE), 0D);
+        assertEquals(1.0, StrictMath.signum(Double.POSITIVE_INFINITY), 0D);
+        assertEquals(-1.0, StrictMath.signum(Double.NEGATIVE_INFINITY), 0D);
+
+    }
+
+    /**
+     * java.lang.StrictMath#signum(float)
+     */
+    public void test_signum_F() {
+        assertTrue(Float.isNaN(StrictMath.signum(Float.NaN)));
+        assertEquals(Float.floatToIntBits(0.0f), Float
+                .floatToIntBits(StrictMath.signum(0.0f)));
+        assertEquals(Float.floatToIntBits(+0.0f), Float
+                .floatToIntBits(StrictMath.signum(+0.0f)));
+        assertEquals(Float.floatToIntBits(-0.0f), Float
+                .floatToIntBits(StrictMath.signum(-0.0f)));
+
+        assertEquals(1.0f, StrictMath.signum(253681.2187962f), 0f);
+        assertEquals(-1.0f, StrictMath.signum(-125874693.56f), 0f);
+        assertEquals(1.0f, StrictMath.signum(1.2587E-11f), 0f);
+        assertEquals(-1.0f, StrictMath.signum(-1.2587E-11f), 0f);
+
+        assertEquals(1.0f, StrictMath.signum(Float.MAX_VALUE), 0f);
+        assertEquals(1.0f, StrictMath.signum(Float.MIN_VALUE), 0f);
+        assertEquals(-1.0f, StrictMath.signum(-Float.MAX_VALUE), 0f);
+        assertEquals(-1.0f, StrictMath.signum(-Float.MIN_VALUE), 0f);
+        assertEquals(1.0f, StrictMath.signum(Float.POSITIVE_INFINITY), 0f);
+        assertEquals(-1.0f, StrictMath.signum(Float.NEGATIVE_INFINITY), 0f);
+    }
+
+    /**
+     * java.lang.StrictMath#sin(double)
+     */
+    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);
+    }
+
+    /**
+     * java.lang.StrictMath#sinh(double)
+     */
+    public void test_sinh_D() {
+        // Test for special situations
+        assertTrue(Double.isNaN(StrictMath.sinh(Double.NaN)));
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, StrictMath
+                .sinh(Double.POSITIVE_INFINITY), 0D);
+        assertEquals("Should return NEGATIVE_INFINITY",
+                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)));
+
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, StrictMath.sinh(1234.56), 0D);
+        assertEquals("Should return NEGATIVE_INFINITY",
+                Double.NEGATIVE_INFINITY, StrictMath.sinh(-1234.56), 0D);
+        assertEquals("Should return 1.0000000000001666E-6",
+                1.0000000000001666E-6, StrictMath.sinh(0.000001), 0D);
+        assertEquals("Should return -1.0000000000001666E-6",
+                -1.0000000000001666E-6, StrictMath.sinh(-0.000001), 0D);
+        assertEquals("Should return 5.115386441963859", 5.115386441963859,
+                StrictMath.sinh(2.33482), 0D);
+        assertEquals("Should return POSITIVE_INFINITY",
+                Double.POSITIVE_INFINITY, StrictMath.sinh(Double.MAX_VALUE), 0D);
+        assertEquals("Should return 4.9E-324", 4.9E-324, StrictMath
+                .sinh(Double.MIN_VALUE), 0D);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * java.lang.StrictMath#tanh(double)
+     */
+    public void test_tanh_D() {
+        // Test for special situations
+        assertTrue(Double.isNaN(StrictMath.tanh(Double.NaN)));
+        assertEquals("Should return +1.0", +1.0, StrictMath
+                .tanh(Double.POSITIVE_INFINITY), 0D);
+        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)));
+
+        assertEquals("Should return 1.0", 1.0, StrictMath.tanh(1234.56), 0D);
+        assertEquals("Should return -1.0", -1.0, StrictMath.tanh(-1234.56), 0D);
+        assertEquals("Should return 9.999999999996666E-7",
+                9.999999999996666E-7, StrictMath.tanh(0.000001), 0D);
+        assertEquals("Should return 0.981422884124941", 0.981422884124941,
+                StrictMath.tanh(2.33482), 0D);
+        assertEquals("Should return 1.0", 1.0, StrictMath
+                .tanh(Double.MAX_VALUE), 0D);
+        assertEquals("Should return 4.9E-324", 4.9E-324, StrictMath
+                .tanh(Double.MIN_VALUE), 0D);
+    }
+
+    /**
+     * 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);
+        }
+    }
+
+    /**
+     * 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);
+        }
+    }
+
+    /**
+     * 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);
+        }
+    }
+
+    /**
+     * java.lang.StrictMath#ulp(double)
+     */
+    @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);
+
+        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);
+    }
+
+    /**
+     * 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);
+
+        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);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/String2Test.java b/luni/src/test/java/tests/api/java/lang/String2Test.java
new file mode 100644
index 0000000..10394d4
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/String2Test.java
@@ -0,0 +1,976 @@
+/*
+ *  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.lang;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Locale;
+import java.nio.charset.Charset;
+
+public class String2Test extends junit.framework.TestCase {
+
+    String hw1 = "HelloWorld";
+
+    String hw2 = "HelloWorld";
+
+    String hwlc = "helloworld";
+
+    String hwuc = "HELLOWORLD";
+
+    String hello1 = "Hello";
+
+    String world1 = "World";
+
+    String comp11 = "Test String";
+
+    Object obj = new Object();
+
+    char[] buf = { 'W', 'o', 'r', 'l', 'd' };
+
+    char[] rbuf = new char[5];
+
+    /**
+     * java.lang.String#String()
+     */
+    public void test_Constructor() {
+        // Test for method java.lang.String()
+        assertTrue("Created incorrect string", new String().equals(""));
+    }
+
+    /**
+     * java.lang.String#String(byte[])
+     */
+    public void test_Constructor$B() {
+        // Test for method java.lang.String(byte [])
+        assertTrue("Failed to create string", new String(hw1.getBytes())
+                .equals(hw1));
+    }
+
+    /**
+     * java.lang.String#String(byte[], int)
+     */
+    @SuppressWarnings("deprecation")
+    public void test_Constructor$BI() {
+        // Test for method java.lang.String(byte [], int)
+        String s = new String(new byte[] { 65, 66, 67, 68, 69 }, 0);
+        assertTrue("Incorrect string returned: " + s, s.equals("ABCDE"));
+        s = new String(new byte[] { 65, 66, 67, 68, 69 }, 1);
+        assertTrue("Did not use nonzero hibyte", !s.equals("ABCDE"));
+    }
+
+    /**
+     * java.lang.String#String(byte[], int, int)
+     */
+    public void test_Constructor$BII() {
+        // Test for method java.lang.String(byte [], int, int)
+        assertTrue("Failed to create string", new String(hw1.getBytes(), 0, hw1
+                .getBytes().length).equals(hw1));
+
+        boolean exception = false;
+        try {
+            new String(new byte[0], 0, Integer.MAX_VALUE);
+        } catch (IndexOutOfBoundsException e) {
+            exception = true;
+        }
+        assertTrue("Did not throw exception", exception);
+    }
+
+    /**
+     * java.lang.String#String(byte[], int, int, int)
+     */
+    @SuppressWarnings("deprecation")
+    public void test_Constructor$BIII() {
+        // Test for method java.lang.String(byte [], int, int, int)
+        String s = new String(new byte[] { 65, 66, 67, 68, 69 }, 0, 1, 3);
+        assertTrue("Incorrect string returned: " + s, s.equals("BCD"));
+        s = new String(new byte[] { 65, 66, 67, 68, 69 }, 1, 0, 5);
+        assertTrue("Did not use nonzero hibyte", !s.equals("ABCDE"));
+    }
+
+    /**
+     * java.lang.String#String(byte[], int, int, java.lang.String)
+     */
+    public void test_Constructor$BIILjava_lang_String() throws Exception {
+        // Test for method java.lang.String(byte [], int, int, java.lang.String)
+        String s = null;
+        s = new String(new byte[] { 65, 66, 67, 68, 69 }, 0, 5, "8859_1");
+        assertTrue("Incorrect string returned: " + s, s.equals("ABCDE"));
+        // Regression for HARMONY-1111
+        assertNotNull(new String(new byte[] { (byte) 0xC0 }, 0, 1, "UTF-8"));
+    }
+
+    /**
+     * java.lang.String#String(byte[], java.lang.String)
+     */
+    public void test_Constructor$BLjava_lang_String() throws Exception {
+        // Test for method java.lang.String(byte [], java.lang.String)
+        String s = null;
+        s = new String(new byte[] { 65, 66, 67, 68, 69 }, "8859_1");
+        assertTrue("Incorrect string returned: " + s, s.equals("ABCDE"));
+    }
+
+    /**
+     * java.lang.String#String(char[])
+     */
+    public void test_Constructor$C() {
+        // Test for method java.lang.String(char [])
+        assertEquals("Failed Constructor test", "World", new String(buf));
+    }
+
+    /**
+     * java.lang.String#String(char[], int, int)
+     */
+    public void test_Constructor$CII() {
+        // Test for method java.lang.String(char [], int, int)
+        char[] buf = { 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' };
+        String s = new String(buf, 0, buf.length);
+        assertTrue("Incorrect string created", hw1.equals(s));
+
+        boolean exception = false;
+        try {
+            new String(new char[0], 0, Integer.MAX_VALUE);
+        } catch (IndexOutOfBoundsException e) {
+            exception = true;
+        }
+        assertTrue("Did not throw exception", exception);
+    }
+
+    /**
+     * java.lang.String#String(int[], int, int)
+     */
+    public void test_Constructor$III() {
+        // Test for method java.lang.String(int [], int, int)
+        try {
+            new String(new int[0], 2, Integer.MAX_VALUE);
+            fail("Did not throw exception");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.lang.String#String(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        // Test for method java.lang.String(java.lang.String)
+        String s = new String("Hello World");
+        assertEquals("Failed to construct correct string", "Hello World", s);
+    }
+
+    /**
+     * java.lang.String#String(java.lang.StringBuffer)
+     */
+    public void test_ConstructorLjava_lang_StringBuffer() {
+        // Test for method java.lang.String(java.lang.StringBuffer)
+        StringBuffer sb = new StringBuffer();
+        sb.append("HelloWorld");
+        assertEquals("Created incorrect string", "HelloWorld", new String(sb));
+    }
+
+    /**
+     * java.lang.String#charAt(int)
+     */
+    public void test_charAtI() {
+        // Test for method char java.lang.String.charAt(int)
+        assertTrue("Incorrect character returned", hw1.charAt(5) == 'W'
+                && (hw1.charAt(1) != 'Z'));
+    }
+
+    /**
+     * java.lang.String#compareTo(java.lang.String)
+     */
+    public void test_compareToLjava_lang_String() {
+        // Test for method int java.lang.String.compareTo(java.lang.String)
+        assertTrue("Returned incorrect value for first < second", "aaaaab"
+                .compareTo("aaaaac") < 0);
+        assertEquals("Returned incorrect value for first = second", 0, "aaaaac"
+                .compareTo("aaaaac"));
+        assertTrue("Returned incorrect value for first > second", "aaaaac"
+                .compareTo("aaaaab") > 0);
+        assertTrue("Considered case to not be of importance", !("A"
+                .compareTo("a") == 0));
+
+        try {
+            "fixture".compareTo(null);
+            fail("No NPE");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    /**
+     * java.lang.String#compareToIgnoreCase(java.lang.String)
+     */
+    public void test_compareToIgnoreCaseLjava_lang_String() {
+        // Test for method int
+        // java.lang.String.compareToIgnoreCase(java.lang.String)
+        assertTrue("Returned incorrect value for first < second", "aaaaab"
+                .compareToIgnoreCase("aaaaac") < 0);
+        assertEquals("Returned incorrect value for first = second", 0, "aaaaac"
+                .compareToIgnoreCase("aaaaac"));
+        assertTrue("Returned incorrect value for first > second", "aaaaac"
+                .compareToIgnoreCase("aaaaab") > 0);
+        assertEquals("Considered case to not be of importance", 0, "A"
+                .compareToIgnoreCase("a"));
+
+        assertTrue("0xbf should not compare = to 'ss'", "\u00df"
+                .compareToIgnoreCase("ss") != 0);
+        assertEquals("0x130 should compare = to 'i'", 0, "\u0130"
+                .compareToIgnoreCase("i"));
+        assertEquals("0x131 should compare = to 'i'", 0, "\u0131"
+                .compareToIgnoreCase("i"));
+
+        Locale defLocale = Locale.getDefault();
+        try {
+            Locale.setDefault(new Locale("tr", ""));
+            assertEquals("Locale tr: 0x130 should compare = to 'i'", 0,
+                    "\u0130".compareToIgnoreCase("i"));
+            assertEquals("Locale tr: 0x131 should compare = to 'i'", 0,
+                    "\u0131".compareToIgnoreCase("i"));
+        } finally {
+            Locale.setDefault(defLocale);
+        }
+
+        try {
+            "fixture".compareToIgnoreCase(null);
+            fail("No NPE");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    /**
+     * java.lang.String#concat(java.lang.String)
+     */
+    public void test_concatLjava_lang_String() {
+        // Test for method java.lang.String
+        // java.lang.String.concat(java.lang.String)
+        assertTrue("Concatenation failed to produce correct string", hello1
+                .concat(world1).equals(hw1));
+        boolean exception = false;
+        try {
+            String a = new String("test");
+            String b = null;
+            a.concat(b);
+        } catch (NullPointerException e) {
+            exception = true;
+        }
+        assertTrue("Concatenation failed to throw NP exception (1)", exception);
+        exception = false;
+        try {
+            String a = new String("");
+            String b = null;
+            a.concat(b);
+        } catch (NullPointerException e) {
+            exception = true;
+        }
+        assertTrue("Concatenation failed to throw NP exception (2)", exception);
+
+        String s1 = "";
+        String s2 = "s2";
+        String s3 = s1.concat(s2);
+        assertEquals(s2, s3);
+        // The RI returns a new string even when it's the same as the argument string.
+        // assertNotSame(s2, s3);
+        s3 = s2.concat(s1);
+        assertEquals(s2, s3);
+        // Neither Android nor the RI returns a new string when it's the same as *this*.
+        // assertNotSame(s2, s3);
+
+        s3 = s2.concat(s1);
+        assertSame(s2, s3);
+    }
+
+    /**
+     * java.lang.String#copyValueOf(char[])
+     */
+    public void test_copyValueOf$C() {
+        // Test for method java.lang.String java.lang.String.copyValueOf(char
+        // [])
+        char[] t = { 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' };
+        assertEquals("copyValueOf returned incorrect String", "HelloWorld",
+                String.copyValueOf(t));
+    }
+
+    /**
+     * java.lang.String#copyValueOf(char[], int, int)
+     */
+    public void test_copyValueOf$CII() {
+        // Test for method java.lang.String java.lang.String.copyValueOf(char
+        // [], int, int)
+        char[] t = { 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' };
+        assertEquals("copyValueOf returned incorrect String", "World", String
+                .copyValueOf(t, 5, 5));
+    }
+
+    /**
+     * java.lang.String#endsWith(java.lang.String)
+     */
+    public void test_endsWithLjava_lang_String() {
+        // Test for method boolean java.lang.String.endsWith(java.lang.String)
+        assertTrue("Failed to fine ending string", hw1.endsWith("ld"));
+    }
+
+    /**
+     * java.lang.String#equals(java.lang.Object)
+     */
+    public void test_equalsLjava_lang_Object() {
+        assertEquals("String not equal", hw1, hw2);
+        assertEquals("Empty string equals check", "", "");
+        assertEquals("Null string equals check", (String) null, (String) null);
+
+        assertFalse("Unequal strings reports as equal", hw1.equals(comp11));
+        assertFalse("Null string comparison failed", hw1.equals((String) null));
+    }
+
+    /**
+     * java.lang.String#equalsIgnoreCase(java.lang.String)
+     */
+    public void test_equalsIgnoreCaseLjava_lang_String() {
+        // Test for method boolean
+        // java.lang.String.equalsIgnoreCase(java.lang.String)
+        assertTrue("lc version returned unequal to uc", hwlc
+                .equalsIgnoreCase(hwuc));
+    }
+
+    /**
+     * java.lang.String#getBytes()
+     */
+    public void test_getBytes() {
+        // Test for method byte [] java.lang.String.getBytes()
+        byte[] sbytes = hw1.getBytes();
+
+        for (int i = 0; i < hw1.length(); i++) {
+            assertTrue("Returned incorrect bytes", sbytes[i] == (byte) hw1.charAt(i));
+        }
+
+        char[] chars = new char[1];
+        for (int i = 0; i < 65536; i++) {
+            // skip surrogates
+            if (i == 0xd800)
+                i = 0xe000;
+            byte[] result = null;
+            chars[0] = (char) i;
+            String string = new String(chars);
+            try {
+                result = string.getBytes("8859_1");
+                if (i < 256) {
+                    assertEquals((byte) i, result[0]);
+                } else {
+                    /*
+                     * Substitute character should be 0x1A [1], but may be '?'
+                     * character. [1]
+                     * http://en.wikipedia.org/wiki/Substitute_character
+                     */
+                    assertTrue(result[0] == '?' || result[0] == 0x1a);
+                }
+            } catch (java.io.UnsupportedEncodingException e) {
+            }
+            try {
+                result = string.getBytes("UTF8");
+                int length = i < 0x80 ? 1 : (i < 0x800 ? 2 : 3);
+                assertTrue("Wrong length UTF8: " + Integer.toHexString(i),
+                        result.length == length);
+                assertTrue(
+                        "Wrong bytes UTF8: " + Integer.toHexString(i),
+                        (i < 0x80 && result[0] == i)
+                                || (i >= 0x80
+                                && i < 0x800
+                                && result[0] == (byte) (0xc0 | ((i & 0x7c0) >> 6)) && result[1] == (byte) (0x80 | (i & 0x3f)))
+                                || (i >= 0x800
+                                && result[0] == (byte) (0xe0 | (i >> 12))
+                                && result[1] == (byte) (0x80 | ((i & 0xfc0) >> 6)) && result[2] == (byte) (0x80 | (i & 0x3f))));
+            } catch (java.io.UnsupportedEncodingException e) {
+            }
+
+            String bytes = null;
+            try {
+                bytes = new String(result, "UTF8");
+                assertTrue("Wrong UTF8 byte length: " + bytes.length() + "("
+                        + i + ")", bytes.length() == 1);
+                assertTrue(
+                        "Wrong char UTF8: "
+                                + Integer.toHexString(bytes.charAt(0)) + " ("
+                                + i + ")", bytes.charAt(0) == i);
+            } catch (java.io.UnsupportedEncodingException e) {
+            }
+        }
+
+        byte[] bytes = new byte[1];
+        for (int i = 0; i < 256; i++) {
+            bytes[0] = (byte) i;
+            String result = null;
+            try {
+                result = new String(bytes, "8859_1");
+                assertEquals("Wrong char length", 1, result.length());
+                assertTrue("Wrong char value", result.charAt(0) == (char) i);
+            } catch (java.io.UnsupportedEncodingException e) {
+            }
+        }
+    }
+
+    /**
+     * java.lang.String#getBytes(int, int, byte[], int)
+     */
+    @SuppressWarnings("deprecation")
+    public void test_getBytesII$BI() {
+        // Test for method void java.lang.String.getBytes(int, int, byte [],
+        // int)
+        byte[] buf = new byte[5];
+        "Hello World".getBytes(6, 11, buf, 0);
+        assertEquals("Returned incorrect bytes", "World", new String(buf));
+
+        try {
+            "Hello World".getBytes(-1, 1, null, 0);
+            fail("Expected StringIndexOutOfBoundsException");
+        } catch (StringIndexOutOfBoundsException e) {
+        } catch (NullPointerException e) {
+            fail("Threw wrong exception");
+        }
+    }
+
+    /**
+     * java.lang.String#getBytes(java.lang.String)
+     */
+    public void test_getBytesLjava_lang_String() throws Exception {
+        // Test for method byte [] java.lang.String.getBytes(java.lang.String)
+        byte[] buf = "Hello World".getBytes();
+        assertEquals("Returned incorrect bytes", "Hello World", new String(buf));
+
+        try {
+            "string".getBytes("8849_1");
+            fail("No UnsupportedEncodingException");
+        } catch (UnsupportedEncodingException e) {
+        }
+
+        byte[] bytes = "\u3048".getBytes("UTF-8");
+        byte[] expected = new byte[] { (byte) 0xE3, (byte) 0x81, (byte) 0x88 };
+        assertEquals(expected[0], bytes[0]);
+        assertEquals(expected[1], bytes[1]);
+        assertEquals(expected[2], bytes[2]);
+
+        // Regression for HARMONY-663
+        try {
+            "string".getBytes("?Q?D??_??_6ffa?+vG?_??\u951f\ufffd??");
+            fail("No UnsupportedEncodingException");
+        } catch (UnsupportedEncodingException e) {
+            // expected
+        }
+
+        // Regression for HARMONY-4135
+        bytes = "-".getBytes("UTF-16");
+        expected = new byte[] { -2, -1 };
+        assertEquals(expected[0], bytes[0]);
+        assertEquals(expected[1], bytes[1]);
+    }
+
+    /*
+     * java.lang.String#getBytes()
+     */
+    public void test_getBytes_NPE() throws Exception {
+        try {
+            "abc".getBytes((String) null);
+            fail("Should throw NullPointerException");
+        } catch (UnsupportedEncodingException whatTheRiDocumentsAndWeThrow) {
+        } catch (NullPointerException whatTheRiActuallyThrows) {
+        }
+
+        try {
+            "Hello World".getBytes(1, 2, null, 1);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.lang.String#getChars(int, int, char[], int)
+     */
+    public void test_getCharsII$CI() {
+        // Test for method void java.lang.String.getChars(int, int, char [],
+        // int)
+        hw1.getChars(5, hw1.length(), rbuf, 0);
+
+        for (int i = 0; i < rbuf.length; i++)
+            assertTrue("getChars returned incorrect char(s)", rbuf[i] == buf[i]);
+    }
+
+    /**
+     * java.lang.String#hashCode()
+     */
+    public void test_hashCode() {
+        // Test for method int java.lang.String.hashCode()
+        int hwHashCode = 0;
+        final int hwLength = hw1.length();
+        int powerOfThirtyOne = 1;
+        for (int counter = hwLength - 1; counter >= 0; counter--) {
+            hwHashCode += hw1.charAt(counter) * powerOfThirtyOne;
+            powerOfThirtyOne *= 31;
+        }
+        assertEquals("String did not hash to correct value", hwHashCode, hw1.hashCode());
+        assertEquals("The empty string \"\" did not hash to zero", 0, "".hashCode());
+        assertEquals("Calculated wrong string hashcode", -1933545242, "Harmony".hashCode());
+    }
+
+    /**
+     * java.lang.String#indexOf(int)
+     */
+    public void test_indexOfI() {
+        // Test for method int java.lang.String.indexOf(int)
+        assertEquals("Invalid index returned", 1, hw1.indexOf('e'));
+        assertEquals("Invalid index returned", 1, "a\ud800\udc00".indexOf(0x10000));
+    }
+
+    /**
+     * java.lang.String#indexOf(int, int)
+     */
+    public void test_indexOfII() {
+        // Test for method int java.lang.String.indexOf(int, int)
+        assertEquals("Invalid character index returned", 5, hw1.indexOf('W', 2));
+        assertEquals("Invalid index returned", 2, "ab\ud800\udc00".indexOf(0x10000, 1));
+    }
+
+    /**
+     * java.lang.String#indexOf(java.lang.String)
+     */
+    public void test_indexOfLjava_lang_String() {
+        // Test for method int java.lang.String.indexOf(java.lang.String)
+        assertTrue("Failed to find string", hw1.indexOf("World") > 0);
+        assertTrue("Failed to find string", !(hw1.indexOf("ZZ") > 0));
+    }
+
+    /**
+     * java.lang.String#indexOf(java.lang.String, int)
+     */
+    public void test_indexOfLjava_lang_StringI() {
+        // Test for method int java.lang.String.indexOf(java.lang.String, int)
+        assertTrue("Failed to find string", hw1.indexOf("World", 0) > 0);
+        assertTrue("Found string outside index", !(hw1.indexOf("Hello", 6) > 0));
+        assertEquals("Did not accept valid negative starting position", 0,
+                hello1.indexOf("", -5));
+        assertEquals("Reported wrong error code", 5, hello1.indexOf("", 5));
+        assertEquals("Wrong for empty in empty", 0, "".indexOf("", 0));
+    }
+
+    /**
+     * java.lang.String#intern()
+     */
+    public void test_intern() {
+        // Test for method java.lang.String java.lang.String.intern()
+        assertTrue("Intern returned incorrect result", hw1.intern() == hw2
+                .intern());
+    }
+
+    /**
+     * java.lang.String#lastIndexOf(int)
+     */
+    public void test_lastIndexOfI() {
+        // Test for method int java.lang.String.lastIndexOf(int)
+        assertEquals("Failed to return correct index", 5, hw1.lastIndexOf('W'));
+        assertEquals("Returned index for non-existent char", -1, hw1
+                .lastIndexOf('Z'));
+        assertEquals("Failed to return correct index", 1, "a\ud800\udc00"
+                .lastIndexOf(0x10000));
+    }
+
+    /**
+     * java.lang.String#lastIndexOf(int, int)
+     */
+    public void test_lastIndexOfII() {
+        // Test for method int java.lang.String.lastIndexOf(int, int)
+        assertEquals("Failed to return correct index", 5, hw1.lastIndexOf('W',
+                6));
+        assertEquals("Returned index for char out of specified range", -1, hw1
+                .lastIndexOf('W', 4));
+        assertEquals("Returned index for non-existent char", -1, hw1
+                .lastIndexOf('Z', 9));
+
+    }
+
+    /**
+     * java.lang.String#lastIndexOf(java.lang.String)
+     */
+    public void test_lastIndexOfLjava_lang_String() {
+        // Test for method int java.lang.String.lastIndexOf(java.lang.String)
+        assertEquals("Returned incorrect index", 5, hw1.lastIndexOf("World"));
+        assertEquals("Found String outside of index", -1, hw1
+                .lastIndexOf("HeKKKKKKKK"));
+    }
+
+    /**
+     * java.lang.String#lastIndexOf(java.lang.String, int)
+     */
+    public void test_lastIndexOfLjava_lang_StringI() {
+        // Test for method int java.lang.String.lastIndexOf(java.lang.String,
+        // int)
+        assertEquals("Returned incorrect index", 5, hw1.lastIndexOf("World", 9));
+        int result = hw1.lastIndexOf("Hello", 2);
+        assertTrue("Found String outside of index: " + result, result == 0);
+        assertEquals("Reported wrong error code", -1, hello1
+                .lastIndexOf("", -5));
+        assertEquals("Did not accept valid large starting position", 5, hello1
+                .lastIndexOf("", 5));
+    }
+
+    /**
+     * java.lang.String#length()
+     */
+    public void test_length() {
+        // Test for method int java.lang.String.length()
+        assertEquals("Invalid length returned", 11, comp11.length());
+    }
+
+    /**
+     * java.lang.String#regionMatches(int, java.lang.String, int, int)
+     */
+    public void test_regionMatchesILjava_lang_StringII() {
+        // Test for method boolean java.lang.String.regionMatches(int,
+        // java.lang.String, int, int)
+        String bogusString = "xxcedkedkleiorem lvvwr e''' 3r3r 23r";
+
+        assertTrue("identical regions failed comparison", hw1.regionMatches(2,
+                hw2, 2, 5));
+        assertTrue("Different regions returned true", !hw1.regionMatches(2,
+                bogusString, 2, 5));
+    }
+
+    /**
+     * java.lang.String#regionMatches(boolean, int, java.lang.String,
+     *int, int)
+     */
+    public void test_regionMatchesZILjava_lang_StringII() {
+        // Test for method boolean java.lang.String.regionMatches(boolean, int,
+        // java.lang.String, int, int)
+
+        String bogusString = "xxcedkedkleiorem lvvwr e''' 3r3r 23r";
+
+        assertTrue("identical regions failed comparison", hw1.regionMatches(
+                false, 2, hw2, 2, 5));
+        assertTrue("identical regions failed comparison with different cases",
+                hw1.regionMatches(true, 2, hw2, 2, 5));
+        assertTrue("Different regions returned true", !hw1.regionMatches(true,
+                2, bogusString, 2, 5));
+        assertTrue("identical regions failed comparison with different cases",
+                hw1.regionMatches(false, 2, hw2, 2, 5));
+    }
+
+    /**
+     * java.lang.String#replace(char, char)
+     */
+    public void test_replaceCC() {
+        // Test for method java.lang.String java.lang.String.replace(char, char)
+        assertEquals("Failed replace", "HezzoWorzd", hw1.replace('l', 'z'));
+    }
+
+    /**
+     * java.lang.String#replace(CharSequence, CharSequence)
+     */
+    public void test_replaceLjava_langCharSequenceLjava_langCharSequence() {
+        assertEquals("Failed replace", "aaccdd", "aabbdd".replace(
+                new StringBuffer("bb"), "cc"));
+        assertEquals("Failed replace by bigger seq", "cccbccc", "aba".replace(
+                "a", "ccc"));
+        assertEquals("Failed replace by smaller seq", "$bba^", "$aaaaa^"
+                .replace(new StringBuilder("aa"), "b"));
+        assertEquals("Failed to replace empty string", "%%a%%b%%c%%",
+                "abc".replace("", "%%"));
+        assertEquals("Failed to replace with empty string", "aacc",
+                "aabbcc".replace("b", ""));
+        assertEquals("Failed to replace in empty string", "abc",
+                "".replace("", "abc"));
+    }
+
+    /**
+     * java.lang.String#startsWith(java.lang.String)
+     */
+    public void test_startsWithLjava_lang_String() {
+        // Test for method boolean java.lang.String.startsWith(java.lang.String)
+        assertTrue("Failed to find string", hw1.startsWith("Hello"));
+        assertTrue("Found incorrect string", !hw1.startsWith("T"));
+    }
+
+    /**
+     * java.lang.String#startsWith(java.lang.String, int)
+     */
+    public void test_startsWithLjava_lang_StringI() {
+        // Test for method boolean java.lang.String.startsWith(java.lang.String,
+        // int)
+        assertTrue("Failed to find string", hw1.startsWith("World", 5));
+        assertTrue("Found incorrect string", !hw1.startsWith("Hello", 5));
+    }
+
+    /**
+     * java.lang.String#substring(int)
+     */
+    public void test_substringI() {
+        // Test for method java.lang.String java.lang.String.substring(int)
+        assertEquals("Incorrect substring returned", "World", hw1.substring(5));
+        assertTrue("not identical", hw1.substring(0) == hw1);
+    }
+
+    /**
+     * java.lang.String#substring(int, int)
+     */
+    public void test_substringII() {
+        // Test for method java.lang.String java.lang.String.substring(int, int)
+        assertTrue("Incorrect substring returned", hw1.substring(0, 5).equals(
+                "Hello")
+                && (hw1.substring(5, 10).equals("World")));
+        assertTrue("not identical", hw1.substring(0, hw1.length()) == hw1);
+    }
+
+    /**
+     * java.lang.String#substring(int, int)
+     */
+    public void test_substringErrorMessage() {
+        try {
+            hw1.substring(-1, 1);
+        } catch (StringIndexOutOfBoundsException ex) {
+            String msg = ex.getMessage();
+            assertTrue("Expected message to contain -1: " + msg, msg
+                    .indexOf("-1") != -1);
+        }
+        try {
+            hw1.substring(4, 1);
+        } catch (StringIndexOutOfBoundsException ex) {
+            String msg = ex.getMessage();
+            assertTrue("Expected message to contain -3: " + msg, msg
+                    .indexOf("-3") != -1);
+        }
+        try {
+            hw1.substring(0, 100);
+        } catch (StringIndexOutOfBoundsException ex) {
+            String msg = ex.getMessage();
+            assertTrue("Expected message to contain 100: " + msg, msg
+                    .indexOf("100") != -1);
+        }
+    }
+
+    /**
+     * java.lang.String#toCharArray()
+     */
+    public void test_toCharArray() {
+        // Test for method char [] java.lang.String.toCharArray()
+
+        String s = new String(buf, 0, buf.length);
+        char[] schars = s.toCharArray();
+        for (int i = 0; i < s.length(); i++)
+            assertTrue("Returned incorrect char aray", buf[i] == schars[i]);
+    }
+
+    /**
+     * java.lang.String#toLowerCase()
+     */
+    public void test_toLowerCase() {
+        // Test for method java.lang.String java.lang.String.toLowerCase()
+        assertTrue("toLowerCase case conversion did not succeed", hwuc
+                .toLowerCase().equals(hwlc));
+
+        assertEquals(
+                "a) Sigma has ordinary lower case value when isolated with Unicode 4.0",
+                "\u03c3", "\u03a3".toLowerCase());
+        assertEquals(
+                "b) Sigma has final form lower case value at end of word with Unicode 4.0",
+                "a\u03c2", "a\u03a3".toLowerCase());
+
+        assertEquals("toLowerCase case conversion did not succeed",
+                "\uD801\uDC44", "\uD801\uDC1C".toLowerCase());
+    }
+
+    /**
+     * java.lang.String#toLowerCase(java.util.Locale)
+     */
+    public void test_toLowerCaseLjava_util_Locale() {
+        // Test for method java.lang.String
+        // java.lang.String.toLowerCase(java.util.Locale)
+        assertTrue("toLowerCase case conversion did not succeed", hwuc
+                .toLowerCase(java.util.Locale.getDefault()).equals(hwlc));
+        assertEquals("Invalid \\u0049 for English", "\u0069", "\u0049"
+                .toLowerCase(Locale.ENGLISH));
+        assertEquals("Invalid \\u0049 for Turkish", "\u0131", "\u0049"
+                .toLowerCase(new Locale("tr", "")));
+    }
+
+    /**
+     * java.lang.String#toString()
+     */
+    public void test_toString() {
+        // Test for method java.lang.String java.lang.String.toString()
+        assertTrue("Incorrect string returned", hw1.toString().equals(hw1));
+    }
+
+    /**
+     * java.lang.String#toUpperCase()
+     */
+    public void test_toUpperCase() {
+        // Test for method java.lang.String java.lang.String.toUpperCase()
+        assertTrue("Returned string is not UpperCase", hwlc.toUpperCase()
+                .equals(hwuc));
+
+        assertEquals("Wrong conversion", "SS", "\u00df".toUpperCase());
+
+        String s = "a\u00df\u1f56";
+        assertTrue("Invalid conversion", !s.toUpperCase().equals(s));
+
+        assertEquals("toUpperCase case conversion did not succeed",
+                "\uD801\uDC1C", "\uD801\uDC44".toUpperCase());
+    }
+
+    /**
+     * java.lang.String#toUpperCase(java.util.Locale)
+     */
+    public void test_toUpperCaseLjava_util_Locale() {
+        // Test for method java.lang.String
+        // java.lang.String.toUpperCase(java.util.Locale)
+        assertTrue("Returned string is not UpperCase", hwlc.toUpperCase()
+                .equals(hwuc));
+        assertEquals("Invalid \\u0069 for English", "\u0049", "\u0069"
+                .toUpperCase(Locale.ENGLISH));
+        assertEquals("Invalid \\u0069 for Turkish", "\u0130", "\u0069"
+                .toUpperCase(new Locale("tr", "")));
+    }
+
+    /**
+     * java.lang.String#toUpperCase(java.util.Locale)
+     */
+    public void test_toUpperCaseLjava_util_Locale_subtest0() {
+        // Test for method java.lang.String
+        // java.lang.String.toUpperCase(java.util.Locale)
+    }
+
+    /**
+     * java.lang.String#trim()
+     */
+    public void test_trim() {
+        // Test for method java.lang.String java.lang.String.trim()
+        assertTrue("Incorrect string returned", " HelloWorld ".trim().equals(
+                hw1));
+    }
+
+    /**
+     * java.lang.String#valueOf(char[])
+     */
+    public void test_valueOf$C() {
+        // Test for method java.lang.String java.lang.String.valueOf(char [])
+        assertEquals("Returned incorrect String", "World", String.valueOf(buf));
+    }
+
+    /**
+     * java.lang.String#valueOf(char[], int, int)
+     */
+    public void test_valueOf$CII() {
+        // Test for method java.lang.String java.lang.String.valueOf(char [],
+        // int, int)
+        char[] t = { 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' };
+        assertEquals("copyValueOf returned incorrect String", "World", String
+                .valueOf(t, 5, 5));
+    }
+
+    /**
+     * java.lang.String#valueOf(char)
+     */
+    public void test_valueOfC() {
+        // Test for method java.lang.String java.lang.String.valueOf(char)
+        for (int i = 0; i < 65536; i++)
+            assertTrue("Incorrect valueOf(char) returned: " + i, String
+                    .valueOf((char) i).charAt(0) == (char) i);
+    }
+
+    /**
+     * java.lang.String#valueOf(double)
+     */
+    public void test_valueOfD() {
+        // Test for method java.lang.String java.lang.String.valueOf(double)
+        assertEquals("Incorrect double string returned",
+                "1.7976931348623157E308", String.valueOf(Double.MAX_VALUE));
+    }
+
+    /**
+     * java.lang.String#valueOf(float)
+     */
+    public void test_valueOfF() {
+        // Test for method java.lang.String java.lang.String.valueOf(float)
+        assertTrue("incorrect float string returned--got: "
+                + String.valueOf(1.0F) + " wanted: 1.0", String.valueOf(1.0F)
+                .equals("1.0"));
+        assertTrue("incorrect float string returned--got: "
+                + String.valueOf(0.9F) + " wanted: 0.9", String.valueOf(0.9F)
+                .equals("0.9"));
+        assertTrue("incorrect float string returned--got: "
+                + String.valueOf(109.567F) + " wanted: 109.567", String
+                .valueOf(109.567F).equals("109.567"));
+    }
+
+    /**
+     * java.lang.String#valueOf(int)
+     */
+    public void test_valueOfI() {
+        // Test for method java.lang.String java.lang.String.valueOf(int)
+        assertEquals("returned invalid int string", "1", String.valueOf(1));
+    }
+
+    /**
+     * java.lang.String#valueOf(long)
+     */
+    public void test_valueOfJ() {
+        // Test for method java.lang.String java.lang.String.valueOf(long)
+        assertEquals("returned incorrect long string", "927654321098", String
+                .valueOf(927654321098L));
+    }
+
+    /**
+     * java.lang.String#valueOf(java.lang.Object)
+     */
+    public void test_valueOfLjava_lang_Object() {
+        // Test for method java.lang.String
+        // java.lang.String.valueOf(java.lang.Object)
+        assertTrue("Incorrect Object string returned", obj.toString().equals(
+                String.valueOf(obj)));
+    }
+
+    /**
+     * java.lang.String#valueOf(boolean)
+     */
+    public void test_valueOfZ() {
+        // Test for method java.lang.String java.lang.String.valueOf(boolean)
+        assertTrue("Incorrect boolean string returned", String.valueOf(false)
+                .equals("false")
+                && (String.valueOf(true).equals("true")));
+    }
+
+    /**
+     * java.lang.String#contentEquals(CharSequence cs)
+     */
+    public void test_contentEqualsLjava_lang_CharSequence() {
+        // Test for method java.lang.String
+        // java.lang.String.contentEquals(CharSequence cs)
+        assertFalse("Incorrect result of compare", "qwerty".contentEquals(""));
+    }
+
+    /**
+     * java.lang.String#format(Locale, String, Object[])
+     */
+    @SuppressWarnings("boxing")
+    public void test_format() {
+        assertEquals("13% of sum is 0x11", String.format("%d%% of %s is 0x%x",
+                13, "sum", 17));
+        assertEquals("empty format", "", String.format("", 123, this));
+        try {
+            String.format(null);
+            fail("NPE is expected on null format");
+        } catch (NullPointerException ok) {
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/StringBuffer2Test.java b/luni/src/test/java/tests/api/java/lang/StringBuffer2Test.java
new file mode 100644
index 0000000..1240ba8
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/StringBuffer2Test.java
@@ -0,0 +1,610 @@
+/*
+ *  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.lang;
+
+public class StringBuffer2Test extends junit.framework.TestCase {
+
+    StringBuffer testBuffer;
+
+    /**
+     * java.lang.StringBuffer#StringBuffer()
+     */
+    public void test_Constructor() {
+        // Test for method java.lang.StringBuffer()
+        new StringBuffer();
+        assertTrue("Invalid buffer created", true);
+    }
+
+    /**
+     * java.lang.StringBuffer#StringBuffer(int)
+     */
+    public void test_ConstructorI() {
+        // Test for method java.lang.StringBuffer(int)
+        StringBuffer sb = new StringBuffer(8);
+        assertEquals("Newly constructed buffer is of incorrect length", 0, sb
+                .length());
+    }
+
+    /**
+     * java.lang.StringBuffer#StringBuffer(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        // Test for method java.lang.StringBuffer(java.lang.String)
+
+        StringBuffer sb = new StringBuffer("HelloWorld");
+
+        assertTrue("Invalid buffer created", sb.length() == 10
+                && (sb.toString().equals("HelloWorld")));
+
+        boolean pass = false;
+        try {
+            new StringBuffer(null);
+        } catch (NullPointerException e) {
+            pass = true;
+        }
+        assertTrue("Should throw NullPointerException", pass);
+    }
+
+    /**
+     * java.lang.StringBuffer#append(char[])
+     */
+    public void test_append$C() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.append(char [])
+        char buf[] = new char[4];
+        "char".getChars(0, 4, buf, 0);
+        testBuffer.append(buf);
+        assertEquals("Append of char[] failed",
+                "This is a test bufferchar", testBuffer.toString());
+    }
+
+    /**
+     * java.lang.StringBuffer#append(char[], int, int)
+     */
+    public void test_append$CII() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.append(char [], int, int)
+        StringBuffer sb = new StringBuffer();
+        char[] buf1 = { 'H', 'e', 'l', 'l', 'o' };
+        char[] buf2 = { 'W', 'o', 'r', 'l', 'd' };
+        sb.append(buf1, 0, buf1.length);
+        assertEquals("Buffer is invalid length after append", 5, sb.length());
+        sb.append(buf2, 0, buf2.length);
+        assertEquals("Buffer is invalid length after append", 10, sb.length());
+        assertTrue("Buffer contains invalid chars", (sb.toString()
+                .equals("HelloWorld")));
+    }
+
+    /**
+     * java.lang.StringBuffer#append(char)
+     */
+    public void test_appendC() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.append(char)
+        StringBuffer sb = new StringBuffer();
+        char buf1 = 'H';
+        char buf2 = 'W';
+        sb.append(buf1);
+        assertEquals("Buffer is invalid length after append", 1, sb.length());
+        sb.append(buf2);
+        assertEquals("Buffer is invalid length after append", 2, sb.length());
+        assertTrue("Buffer contains invalid chars",
+                (sb.toString().equals("HW")));
+    }
+
+    /**
+     * java.lang.StringBuffer#append(double)
+     */
+    public void test_appendD() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.append(double)
+        StringBuffer sb = new StringBuffer();
+        sb.append(Double.MAX_VALUE);
+        assertEquals("Buffer is invalid length after append", 22, sb.length());
+        assertEquals("Buffer contains invalid characters",
+                "1.7976931348623157E308", sb.toString());
+    }
+
+    /**
+     * java.lang.StringBuffer#append(float)
+     */
+    public void test_appendF() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.append(float)
+        StringBuffer sb = new StringBuffer();
+        final float floatNum = 900.87654F;
+        sb.append(floatNum);
+        assertTrue("Buffer is invalid length after append: " + sb.length(), sb
+                .length() == String.valueOf(floatNum).length());
+        assertTrue("Buffer contains invalid characters", sb.toString().equals(
+                String.valueOf(floatNum)));
+    }
+
+    /**
+     * java.lang.StringBuffer#append(int)
+     */
+    public void test_appendI() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.append(int)
+        StringBuffer sb = new StringBuffer();
+        sb.append(9000);
+        assertEquals("Buffer is invalid length after append", 4, sb.length());
+        sb.append(1000);
+        assertEquals("Buffer is invalid length after append", 8, sb.length());
+        assertEquals("Buffer contains invalid characters",
+                "90001000", sb.toString());
+    }
+
+    /**
+     * java.lang.StringBuffer#append(long)
+     */
+    public void test_appendJ() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.append(long)
+
+        StringBuffer sb = new StringBuffer();
+        long t = 927654321098L;
+        sb.append(t);
+        assertEquals("Buffer is of invlaid length", 12, sb.length());
+        assertEquals("Buffer contains invalid characters",
+                "927654321098", sb.toString());
+    }
+
+    /**
+     * java.lang.StringBuffer#append(java.lang.Object)
+     */
+    public void test_appendLjava_lang_Object() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.append(java.lang.Object)
+        StringBuffer sb = new StringBuffer();
+        Object obj1 = new Object();
+        Object obj2 = new Object();
+        sb.append(obj1);
+        sb.append(obj2);
+        assertTrue("Buffer contains invalid characters", sb.toString().equals(
+                obj1.toString() + obj2.toString()));
+    }
+
+    /**
+     * java.lang.StringBuffer#append(java.lang.String)
+     */
+    public void test_appendLjava_lang_String() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.append(java.lang.String)
+        StringBuffer sb = new StringBuffer();
+        String buf1 = "Hello";
+        String buf2 = "World";
+        sb.append(buf1);
+        assertEquals("Buffer is invalid length after append", 5, sb.length());
+        sb.append(buf2);
+        assertEquals("Buffer is invalid length after append", 10, sb.length());
+        assertTrue("Buffer contains invalid chars", (sb.toString()
+                .equals("HelloWorld")));
+    }
+
+    /**
+     * java.lang.StringBuffer#append(boolean)
+     */
+    public void test_appendZ() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.append(boolean)
+        StringBuffer sb = new StringBuffer();
+        sb.append(false);
+        assertEquals("Buffer is invalid length after append", 5, sb.length());
+        sb.append(true);
+        assertEquals("Buffer is invalid length after append", 9, sb.length());
+        assertTrue("Buffer is invalid length after append", (sb.toString()
+                .equals("falsetrue")));
+    }
+
+    /**
+     * java.lang.StringBuffer#capacity()
+     */
+    public void test_capacity() {
+        // Test for method int java.lang.StringBuffer.capacity()
+        StringBuffer sb = new StringBuffer(10);
+        assertEquals("Returned incorrect capacity", 10, sb.capacity());
+        sb.ensureCapacity(100);
+        assertTrue("Returned incorrect capacity", sb.capacity() >= 100);
+    }
+
+    /**
+     * java.lang.StringBuffer#charAt(int)
+     */
+    public void test_charAtI() {
+        // Test for method char java.lang.StringBuffer.charAt(int)
+        assertEquals("Returned incorrect char", 's', testBuffer.charAt(3));
+
+        // Test for StringIndexOutOfBoundsException
+        boolean exception = false;
+        try {
+            testBuffer.charAt(-1);
+        } catch (StringIndexOutOfBoundsException e) {
+            exception = true;
+        } catch (ArrayIndexOutOfBoundsException e) {
+        }
+        assertTrue("Should throw StringIndexOutOfBoundsException", exception);
+    }
+
+    /**
+     * java.lang.StringBuffer#delete(int, int)
+     */
+    public void test_deleteII() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.delete(int, int)
+        testBuffer.delete(7, 7);
+        assertEquals("Deleted chars when start == end", "This is a test buffer", testBuffer.toString()
+        );
+        testBuffer.delete(4, 14);
+        assertEquals("Deleted incorrect chars",
+                "This buffer", testBuffer.toString());
+
+        testBuffer = new StringBuffer("This is a test buffer");
+        String sharedStr = testBuffer.toString();
+        testBuffer.delete(0, testBuffer.length());
+        assertEquals("Didn't clone shared buffer", "This is a test buffer", sharedStr
+        );
+        assertTrue("Deleted incorrect chars", testBuffer.toString().equals(""));
+        testBuffer.append("more stuff");
+        assertEquals("Didn't clone shared buffer 2", "This is a test buffer", sharedStr
+        );
+        assertEquals("Wrong contents", "more stuff", testBuffer.toString());
+        try {
+            testBuffer.delete(-5, 2);
+        } catch (IndexOutOfBoundsException e) {
+        }
+        assertEquals("Wrong contents 2",
+                "more stuff", testBuffer.toString());
+    }
+
+    /**
+     * java.lang.StringBuffer#deleteCharAt(int)
+     */
+    public void test_deleteCharAtI() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.deleteCharAt(int)
+        testBuffer.deleteCharAt(3);
+        assertEquals("Deleted incorrect char",
+                "Thi is a test buffer", testBuffer.toString());
+    }
+
+    /**
+     * java.lang.StringBuffer#ensureCapacity(int)
+     */
+    public void test_ensureCapacityI() {
+        // Test for method void java.lang.StringBuffer.ensureCapacity(int)
+        StringBuffer sb = new StringBuffer(10);
+
+        sb.ensureCapacity(100);
+        assertTrue("Failed to increase capacity", sb.capacity() >= 100);
+    }
+
+    /**
+     * java.lang.StringBuffer#getChars(int, int, char[], int)
+     */
+    public void test_getCharsII$CI() {
+        // Test for method void java.lang.StringBuffer.getChars(int, int, char
+        // [], int)
+
+        char[] buf = new char[10];
+        testBuffer.getChars(4, 8, buf, 2);
+        assertTrue("Returned incorrect chars", new String(buf, 2, 4)
+                .equals(testBuffer.toString().substring(4, 8)));
+
+        boolean exception = false;
+        try {
+            StringBuffer buf2 = new StringBuffer("");
+            buf2.getChars(0, 0, new char[5], 2);
+        } catch (IndexOutOfBoundsException e) {
+            exception = true;
+        }
+        assertTrue("did not expect IndexOutOfBoundsException", !exception);
+    }
+
+    /**
+     * java.lang.StringBuffer#insert(int, char[])
+     */
+    public void test_insertI$C() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.insert(int, char [])
+        char buf[] = new char[4];
+        "char".getChars(0, 4, buf, 0);
+        testBuffer.insert(15, buf);
+        assertEquals("Insert test failed",
+                "This is a test charbuffer", testBuffer.toString());
+
+        boolean exception = false;
+        StringBuffer buf1 = new StringBuffer("abcd");
+        try {
+            buf1.insert(-1, (char[]) null);
+        } catch (StringIndexOutOfBoundsException e) {
+            exception = true;
+        } catch (NullPointerException e) {
+        }
+        assertTrue("Should throw StringIndexOutOfBoundsException", exception);
+    }
+
+    /**
+     * java.lang.StringBuffer#insert(int, char[], int, int)
+     */
+    public void test_insertI$CII() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.insert(int, char [], int, int)
+        char[] c = new char[] { 'n', 'o', 't', ' ' };
+        testBuffer.insert(8, c, 0, 4);
+        assertEquals("This is not a test buffer", testBuffer.toString());
+
+        StringBuffer buf1 = new StringBuffer("abcd");
+        try {
+            buf1.insert(-1, (char[]) null, 0, 0);
+            fail();
+        } catch (NullPointerException expected) {
+        } catch (StringIndexOutOfBoundsException expected) {
+        }
+
+        try {
+            testBuffer.insert(testBuffer.length() - 1, c, -1, 1);
+        } catch (StringIndexOutOfBoundsException e) {
+            //expected
+        }
+
+    }
+
+    /**
+     * java.lang.StringBuffer#insert(int, char)
+     */
+    public void test_insertIC() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.insert(int, char)
+        testBuffer.insert(15, 'T');
+        assertEquals("Insert test failed",
+                "This is a test Tbuffer", testBuffer.toString());
+    }
+
+    /**
+     * java.lang.StringBuffer#insert(int, double)
+     */
+    public void test_insertID() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.insert(int, double)
+        testBuffer.insert(15, Double.MAX_VALUE);
+        assertTrue("Insert test failed", testBuffer.toString().equals(
+                "This is a test " + Double.MAX_VALUE + "buffer"));
+    }
+
+    /**
+     * java.lang.StringBuffer#insert(int, float)
+     */
+    public void test_insertIF() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.insert(int, float)
+        testBuffer.insert(15, Float.MAX_VALUE);
+        String testBufferString = testBuffer.toString();
+        String expectedResult = "This is a test "
+                + String.valueOf(Float.MAX_VALUE) + "buffer";
+        assertTrue("Insert test failed, got: " + "\'" + testBufferString + "\'"
+                + " but wanted: " + "\'" + expectedResult + "\'",
+                testBufferString.equals(expectedResult));
+    }
+
+    /**
+     * java.lang.StringBuffer#insert(int, int)
+     */
+    public void test_insertII() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.insert(int, int)
+        testBuffer.insert(15, 100);
+        assertEquals("Insert test failed",
+                "This is a test 100buffer", testBuffer.toString());
+    }
+
+    /**
+     * java.lang.StringBuffer#insert(int, long)
+     */
+    public void test_insertIJ() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.insert(int, long)
+        testBuffer.insert(15, 88888888888888888L);
+        assertEquals("Insert test failed",
+                "This is a test 88888888888888888buffer", testBuffer.toString());
+    }
+
+    /**
+     * java.lang.StringBuffer#insert(int, java.lang.Object)
+     */
+    public void test_insertILjava_lang_Object() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.insert(int, java.lang.Object)
+        Object obj1 = new Object();
+        testBuffer.insert(15, obj1);
+        assertTrue("Insert test failed", testBuffer.toString().equals(
+                "This is a test " + obj1.toString() + "buffer"));
+    }
+
+    /**
+     * java.lang.StringBuffer#insert(int, java.lang.String)
+     */
+    public void test_insertILjava_lang_String() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.insert(int, java.lang.String)
+
+        testBuffer.insert(15, "STRING ");
+        assertEquals("Insert test failed",
+                "This is a test STRING buffer", testBuffer.toString());
+    }
+
+    /**
+     * java.lang.StringBuffer#insert(int, boolean)
+     */
+    public void test_insertIZ() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.insert(int, boolean)
+        testBuffer.insert(15, true);
+        assertEquals("Insert test failed",
+                "This is a test truebuffer", testBuffer.toString());
+    }
+
+    /**
+     * java.lang.StringBuffer#length()
+     */
+    public void test_length() {
+        // Test for method int java.lang.StringBuffer.length()
+        assertEquals("Incorrect length returned", 21, testBuffer.length());
+    }
+
+    /**
+     * java.lang.StringBuffer#replace(int, int, java.lang.String)
+     */
+    public void test_replaceIILjava_lang_String() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.replace(int, int, java.lang.String)
+        testBuffer.replace(5, 9, "is a replaced");
+        assertTrue("Replace failed, wanted: " + "\'"
+                + "This is a replaced test buffer" + "\'" + " but got: " + "\'"
+                + testBuffer.toString() + "\'", testBuffer.toString().equals(
+                "This is a replaced test buffer"));
+        assertEquals("insert1", "text", new StringBuffer().replace(0, 0, "text")
+                .toString());
+        assertEquals("insert2", "123text", new StringBuffer("123").replace(3, 3, "text")
+                .toString());
+        assertEquals("insert2", "1text23", new StringBuffer("123").replace(1, 1, "text")
+                .toString());
+    }
+
+    private String writeString(String in) {
+        StringBuffer result = new StringBuffer();
+        result.append("\"");
+        for (int i = 0; i < in.length(); i++) {
+            result.append(" 0x" + Integer.toHexString(in.charAt(i)));
+        }
+        result.append("\"");
+        return result.toString();
+    }
+
+    private void reverseTest(String id, String org, String rev, String back) {
+        // create non-shared StringBuffer
+        StringBuffer sb = new StringBuffer(org);
+        sb.reverse();
+        String reversed = sb.toString();
+        assertTrue("reversed surrogate " + id + ": " + writeString(reversed),
+                reversed.equals(rev));
+        // create non-shared StringBuffer
+        sb = new StringBuffer(reversed);
+        sb.reverse();
+        reversed = sb.toString();
+        assertTrue("reversed surrogate " + id + "a: " + writeString(reversed),
+                reversed.equals(back));
+
+        // test algorithm when StringBuffer is shared
+        sb = new StringBuffer(org);
+        String copy = sb.toString();
+        assertEquals(org, copy);
+        sb.reverse();
+        reversed = sb.toString();
+        assertTrue("reversed surrogate " + id + ": " + writeString(reversed),
+                reversed.equals(rev));
+        sb = new StringBuffer(reversed);
+        copy = sb.toString();
+        assertEquals(rev, copy);
+        sb.reverse();
+        reversed = sb.toString();
+        assertTrue("reversed surrogate " + id + "a: " + writeString(reversed),
+                reversed.equals(back));
+
+    }
+
+    /**
+     * java.lang.StringBuffer#reverse()
+     */
+    public void test_reverse() {
+        // Test for method java.lang.StringBuffer
+        // java.lang.StringBuffer.reverse()
+        String org;
+        org = "a";
+        reverseTest("0", org, org, org);
+
+        org = "ab";
+        reverseTest("1", org, "ba", org);
+
+        org = "abcdef";
+        reverseTest("2", org, "fedcba", org);
+
+        org = "abcdefg";
+        reverseTest("3", org, "gfedcba", org);
+
+    }
+
+    /**
+     * java.lang.StringBuffer#setCharAt(int, char)
+     */
+    public void test_setCharAtIC() {
+        // Test for method void java.lang.StringBuffer.setCharAt(int, char)
+        StringBuffer s = new StringBuffer("HelloWorld");
+        s.setCharAt(4, 'Z');
+        assertEquals("Returned incorrect char", 'Z', s.charAt(4));
+    }
+
+    /**
+     * java.lang.StringBuffer#setLength(int)
+     */
+    public void test_setLengthI() {
+        // Test for method void java.lang.StringBuffer.setLength(int)
+        testBuffer.setLength(1000);
+        assertEquals("Failed to increase length", 1000, testBuffer.length());
+        assertTrue("Increase in length trashed buffer", testBuffer.toString()
+                .startsWith("This is a test buffer"));
+        testBuffer.setLength(2);
+        assertEquals("Failed to decrease length", 2, testBuffer.length());
+        assertEquals("Decrease in length failed",
+                "Th", testBuffer.toString());
+    }
+
+    /**
+     * java.lang.StringBuffer#substring(int)
+     */
+    public void test_substringI() {
+        // Test for method java.lang.String
+        // java.lang.StringBuffer.substring(int)
+        assertEquals("Returned incorrect substring", "is a test buffer", testBuffer.substring(5)
+        );
+    }
+
+    /**
+     * java.lang.StringBuffer#substring(int, int)
+     */
+    public void test_substringII() {
+        // Test for method java.lang.String
+        // java.lang.StringBuffer.substring(int, int)
+        assertEquals("Returned incorrect substring", "is", testBuffer.substring(5, 7)
+        );
+    }
+
+    /**
+     * java.lang.StringBuffer#toString()
+     */
+    public void test_toString() {
+        // Test for method java.lang.String java.lang.StringBuffer.toString()
+        assertEquals("Incorrect string value returned", "This is a test buffer", testBuffer.toString()
+        );
+    }
+
+    @Override
+    protected void setUp() {
+        testBuffer = new StringBuffer("This is a test buffer");
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/StringBufferTest.java b/luni/src/test/java/tests/api/java/lang/StringBufferTest.java
new file mode 100644
index 0000000..0cd8f63
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/StringBufferTest.java
@@ -0,0 +1,623 @@
+/* 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.lang;
+
+import java.io.Serializable;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class StringBufferTest extends TestCase {
+
+    /**
+     * java.lang.StringBuffer#setLength(int)
+     */
+    public void test_setLengthI() {
+        // Regression for HARMONY-90
+        StringBuffer buffer = new StringBuffer("abcde");
+        try {
+            buffer.setLength(-1);
+            fail("Assert 0: IndexOutOfBoundsException must be thrown");
+        } 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));
+        }
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * StringBuffer.StringBuffer(CharSequence);
+     */
+    public void test_constructorLjava_lang_CharSequence() {
+        try {
+            new StringBuffer((CharSequence) null);
+            fail("Assert 0: NPE must be thrown.");
+        } catch (NullPointerException e) {
+        }
+
+        assertEquals("Assert 1: must equal 'abc'.", "abc", new StringBuffer((CharSequence) "abc").toString());
+    }
+
+    public void test_trimToSize() {
+        StringBuffer buffer = new StringBuffer(25);
+        buffer.append("abc");
+        int origCapacity = buffer.capacity();
+        buffer.trimToSize();
+        int trimCapacity = buffer.capacity();
+        assertTrue("Assert 0: capacity must be smaller.", trimCapacity < origCapacity);
+        assertEquals("Assert 1: length must still be 3", 3, buffer.length());
+        assertEquals("Assert 2: value must still be 'abc'.", "abc", buffer.toString());
+    }
+
+    /**
+     * java.lang.StringBuffer.append(CharSequence)
+     */
+    public void test_appendLjava_lang_CharSequence() {
+        StringBuffer sb = new StringBuffer();
+        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());
+    }
+
+    /**
+     * java.lang.StringBuffer.append(CharSequence, int, int)
+     */
+    @SuppressWarnings("cast")
+    public void test_appendLjava_lang_CharSequenceII() {
+        StringBuffer sb = new StringBuffer();
+        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());
+    }
+
+    /**
+     * java.lang.StringBuffer.append(char[], int, int)
+     */
+    public void test_append$CII_2() {
+        StringBuffer obj = new StringBuffer();
+        try {
+            obj.append(new char[0], -1, -1);
+            fail("ArrayIndexOutOfBoundsException expected");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.lang.StringBuffer.append(char[], int, int)
+     */
+    public void test_append$CII_3() throws Exception {
+        StringBuffer obj = new StringBuffer();
+        try {
+            obj.append((char[]) null, -1, -1);
+            fail("NullPointerException expected");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.lang.StringBuffer.insert(int, CharSequence)
+     */
+    public void test_insertILjava_lang_CharSequence() {
+        final String fixture = "0000";
+        StringBuffer sb = new StringBuffer(fixture);
+        assertSame(sb, sb.insert(0, (CharSequence) "ab"));
+        assertEquals("ab0000", sb.toString());
+        assertEquals(6, sb.length());
+
+        sb = new StringBuffer(fixture);
+        assertSame(sb, sb.insert(2, (CharSequence) "ab"));
+        assertEquals("00ab00", sb.toString());
+        assertEquals(6, sb.length());
+
+        sb = new StringBuffer(fixture);
+        assertSame(sb, sb.insert(4, (CharSequence) "ab"));
+        assertEquals("0000ab", sb.toString());
+        assertEquals(6, sb.length());
+
+        sb = new StringBuffer(fixture);
+        assertSame(sb, sb.insert(4, (CharSequence) null));
+        assertEquals("0000null", sb.toString());
+        assertEquals(8, sb.length());
+
+        try {
+            sb = new StringBuffer(fixture);
+            sb.insert(-1, (CharSequence) "ab");
+            fail("no IOOBE, negative index");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        try {
+            sb = new StringBuffer(fixture);
+            sb.insert(5, (CharSequence) "ab");
+            fail("no IOOBE, index too large index");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.lang.StringBuffer.insert(int, CharSequence, int, int)
+     */
+    @SuppressWarnings("cast")
+    public void test_insertILjava_lang_CharSequenceII() {
+        final String fixture = "0000";
+        StringBuffer sb = new StringBuffer(fixture);
+        assertSame(sb, sb.insert(0, (CharSequence) "ab", 0, 2));
+        assertEquals("ab0000", sb.toString());
+        assertEquals(6, sb.length());
+
+        sb = new StringBuffer(fixture);
+        assertSame(sb, sb.insert(0, (CharSequence) "ab", 0, 1));
+        assertEquals("a0000", sb.toString());
+        assertEquals(5, sb.length());
+
+        sb = new StringBuffer(fixture);
+        assertSame(sb, sb.insert(2, (CharSequence) "ab", 0, 2));
+        assertEquals("00ab00", sb.toString());
+        assertEquals(6, sb.length());
+
+        sb = new StringBuffer(fixture);
+        assertSame(sb, sb.insert(2, (CharSequence) "ab", 0, 1));
+        assertEquals("00a00", sb.toString());
+        assertEquals(5, sb.length());
+
+        sb = new StringBuffer(fixture);
+        assertSame(sb, sb.insert(4, (CharSequence) "ab", 0, 2));
+        assertEquals("0000ab", sb.toString());
+        assertEquals(6, sb.length());
+
+        sb = new StringBuffer(fixture);
+        assertSame(sb, sb.insert(4, (CharSequence) "ab", 0, 1));
+        assertEquals("0000a", sb.toString());
+        assertEquals(5, sb.length());
+
+        sb = new StringBuffer(fixture);
+        assertSame(sb, sb.insert(4, (CharSequence) null, 0, 2));
+        assertEquals("0000nu", sb.toString());
+        assertEquals(6, sb.length());
+
+        try {
+            sb = new StringBuffer(fixture);
+            sb.insert(-1, (CharSequence) "ab", 0, 2);
+            fail("no IOOBE, negative index");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        try {
+            sb = new StringBuffer(fixture);
+            sb.insert(5, (CharSequence) "ab", 0, 2);
+            fail("no IOOBE, index too large index");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        try {
+            sb = new StringBuffer(fixture);
+            sb.insert(5, (CharSequence) "ab", -1, 2);
+            fail("no IOOBE, negative offset");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        try {
+            sb = new StringBuffer(fixture);
+            sb.insert(5, new char[] { 'a', 'b' }, 0, -1);
+            fail("no IOOBE, negative length");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        try {
+            sb = new StringBuffer(fixture);
+            sb.insert(5, new char[] { 'a', 'b' }, 0, 3);
+            fail("no IOOBE, too long");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.lang.StringBuffer.insert(int, char)
+     */
+    public void test_insertIC() {
+        StringBuffer obj = new StringBuffer();
+        try {
+            obj.insert(-1, ' ');
+            fail("ArrayIndexOutOfBoundsException expected");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.lang.StringBuffer.appendCodePoint(int)'
+     */
+    public void test_appendCodePointI() {
+        StringBuffer sb = new StringBuffer();
+        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());
+    }
+
+    /**
+     * java.lang.StringBuffer.codePointAt(int)
+     */
+    public void test_codePointAtI() {
+        StringBuffer sb = new StringBuffer("abc");
+        assertEquals('a', sb.codePointAt(0));
+        assertEquals('b', sb.codePointAt(1));
+        assertEquals('c', sb.codePointAt(2));
+
+        sb = new StringBuffer("\uD800\uDC00");
+        assertEquals(0x10000, sb.codePointAt(0));
+        assertEquals('\uDC00', sb.codePointAt(1));
+
+        try {
+            sb.codePointAt(-1);
+            fail("No IOOBE on negative index.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+
+        try {
+            sb.codePointAt(sb.length());
+            fail("No IOOBE on index equal to length.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+
+        try {
+            sb.codePointAt(sb.length() + 1);
+            fail("No IOOBE on index greater than length.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+    }
+
+    /**
+     * java.lang.StringBuffer.codePointBefore(int)
+     */
+    public void test_codePointBeforeI() {
+        StringBuffer sb = new StringBuffer("abc");
+        assertEquals('a', sb.codePointBefore(1));
+        assertEquals('b', sb.codePointBefore(2));
+        assertEquals('c', sb.codePointBefore(3));
+
+        sb = new StringBuffer("\uD800\uDC00");
+        assertEquals(0x10000, sb.codePointBefore(2));
+        assertEquals('\uD800', sb.codePointBefore(1));
+
+        try {
+            sb.codePointBefore(0);
+            fail("No IOOBE on zero index.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+
+        try {
+            sb.codePointBefore(-1);
+            fail("No IOOBE on negative index.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+
+        try {
+            sb.codePointBefore(sb.length() + 1);
+            fail("No IOOBE on index greater than length.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+    }
+
+    /**
+     * java.lang.StringBuffer.codePointCount(int, int)
+     */
+    public void test_codePointCountII() {
+        assertEquals(1, new StringBuffer("\uD800\uDC00").codePointCount(0, 2));
+        assertEquals(1, new StringBuffer("\uD800\uDC01").codePointCount(0, 2));
+        assertEquals(1, new StringBuffer("\uD801\uDC01").codePointCount(0, 2));
+        assertEquals(1, new StringBuffer("\uDBFF\uDFFF").codePointCount(0, 2));
+
+        assertEquals(3, new StringBuffer("a\uD800\uDC00b").codePointCount(0, 4));
+        assertEquals(4, new StringBuffer("a\uD800\uDC00b\uD800").codePointCount(0, 5));
+
+        StringBuffer sb = new StringBuffer("abc");
+        try {
+            sb.codePointCount(-1, 2);
+            fail("No IOOBE for negative begin index.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+
+        try {
+            sb.codePointCount(0, 4);
+            fail("No IOOBE for end index that's too large.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+
+        try {
+            sb.codePointCount(3, 2);
+            fail("No IOOBE for begin index larger than end index.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+    }
+
+    /**
+     * java.lang.StringBuffer.getChars(int, int, char[], int)
+     */
+    public void test_getCharsII$CI() {
+        StringBuffer obj = new StringBuffer();
+        try {
+            obj.getChars(0, 0, new char[0], -1);
+            fail("ArrayIndexOutOfBoundsException expected");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.lang.StringBuffer.offsetByCodePoints(int, int)'
+     */
+    public void test_offsetByCodePointsII() {
+        int result = new StringBuffer("a\uD800\uDC00b").offsetByCodePoints(0, 2);
+        assertEquals(3, result);
+
+        result = new StringBuffer("abcd").offsetByCodePoints(3, -1);
+        assertEquals(2, result);
+
+        result = new StringBuffer("a\uD800\uDC00b").offsetByCodePoints(0, 3);
+        assertEquals(4, result);
+
+        result = new StringBuffer("a\uD800\uDC00b").offsetByCodePoints(3, -1);
+        assertEquals(1, result);
+
+        result = new StringBuffer("a\uD800\uDC00b").offsetByCodePoints(3, 0);
+        assertEquals(3, result);
+
+        result = new StringBuffer("\uD800\uDC00bc").offsetByCodePoints(3, 0);
+        assertEquals(3, result);
+
+        result = new StringBuffer("a\uDC00bc").offsetByCodePoints(3, -1);
+        assertEquals(2, result);
+
+        result = new StringBuffer("a\uD800bc").offsetByCodePoints(3, -1);
+        assertEquals(2, result);
+
+        StringBuffer sb = new StringBuffer("abc");
+        try {
+            sb.offsetByCodePoints(-1, 1);
+            fail("No IOOBE for negative index.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+
+        try {
+            sb.offsetByCodePoints(0, 4);
+            fail("No IOOBE for offset that's too large.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+
+        try {
+            sb.offsetByCodePoints(3, -4);
+            fail("No IOOBE for offset that's too small.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+
+        try {
+            sb.offsetByCodePoints(3, 1);
+            fail("No IOOBE for index that's too large.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+
+        try {
+            sb.offsetByCodePoints(4, -1);
+            fail("No IOOBE for index that's too large.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+    }
+
+    /**
+     * {@link java.lang.StringBuffer#indexOf(String, int)}
+     */
+    @SuppressWarnings("nls")
+    public void test_IndexOfStringInt() {
+        final String fixture = "0123456789";
+        StringBuffer sb = new StringBuffer(fixture);
+        assertEquals(0, sb.indexOf("0"));
+        assertEquals(0, sb.indexOf("012"));
+        assertEquals(-1, sb.indexOf("02"));
+        assertEquals(8, sb.indexOf("89"));
+
+        assertEquals(0, sb.indexOf("0"), 0);
+        assertEquals(0, sb.indexOf("012"), 0);
+        assertEquals(-1, sb.indexOf("02"), 0);
+        assertEquals(8, sb.indexOf("89"), 0);
+
+        assertEquals(-1, sb.indexOf("0"), 5);
+        assertEquals(-1, sb.indexOf("012"), 5);
+        assertEquals(-1, sb.indexOf("02"), 0);
+        assertEquals(8, sb.indexOf("89"), 5);
+
+        try {
+            sb.indexOf(null, 0);
+            fail("Should throw a NullPointerExceptionE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * {@link java.lang.StringBuffer#lastIndexOf(String, int)}
+     */
+    @SuppressWarnings("nls")
+    public void test_lastIndexOfLjava_lang_StringI() {
+        final String fixture = "0123456789";
+        StringBuffer sb = new StringBuffer(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(-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("Should throw a NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+    }
+
+    // comparator for StringBuffer objects
+    private static final SerializableAssert STRING_BUFFER_COMPARATOR = new SerializableAssert() {
+        public void assertDeserialized(Serializable initial,
+                Serializable deserialized) {
+
+            StringBuffer init = (StringBuffer) initial;
+            StringBuffer desr = (StringBuffer) deserialized;
+
+            // serializable fields are: 'count', 'shared', 'value'
+            // serialization of 'shared' is not verified
+            // 'count' + 'value' should result in required string
+            assertEquals("toString", init.toString(), desr.toString());
+        }
+    };
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        SerializationTest.verifySelf(new StringBuffer("0123456789"),
+                STRING_BUFFER_COMPARATOR);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        SerializationTest.verifyGolden(this, new StringBuffer("0123456789"),
+                STRING_BUFFER_COMPARATOR);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/StringBuilderTest.java b/luni/src/test/java/tests/api/java/lang/StringBuilderTest.java
new file mode 100644
index 0000000..b634ddf
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/StringBuilderTest.java
@@ -0,0 +1,1986 @@
+/*
+ * 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.lang;
+
+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;
+
+public class StringBuilderTest extends TestCase {
+
+    /**
+     * java.lang.StringBuilder.StringBuilder()
+     */
+    public void test_Constructor() {
+        StringBuilder sb = new StringBuilder();
+        assertNotNull(sb);
+        assertEquals(16, sb.capacity());
+    }
+
+    /**
+     * 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
+        }
+
+        assertNotNull(new StringBuilder(0));
+    }
+
+    /**
+     * 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());
+
+        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
+        }
+    }
+
+    /**
+     * 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) {
+        }
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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
+        }
+    }
+
+    /**
+     * 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' }, 2, 2));
+        assertEquals("cd", 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(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' }, 2, 3);
+            fail("no IOOBE, offset and length overflow");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * java.lang.StringBuilder.capacity()'
+     */
+    public void test_capacity() {
+        StringBuilder sb = new StringBuilder();
+        assertEquals(16, sb.capacity());
+        sb.append("0123456789ABCDEF0123456789ABCDEF");
+        assertTrue(sb.capacity() > 16);
+    }
+
+    /**
+     * 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(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) {
+        }
+    }
+
+    /**
+     * java.lang.StringBuilder.codePointAt(int)
+     */
+    public void test_codePointAtI() {
+        StringBuilder sb = new StringBuilder("abc");
+        assertEquals('a', sb.codePointAt(0));
+        assertEquals('b', sb.codePointAt(1));
+        assertEquals('c', sb.codePointAt(2));
+
+        sb = new StringBuilder("\uD800\uDC00");
+        assertEquals(0x10000, sb.codePointAt(0));
+        assertEquals('\uDC00', sb.codePointAt(1));
+
+        sb = new StringBuilder();
+        sb.append("abc");
+        try {
+            sb.codePointAt(-1);
+            fail("No IOOBE on negative index.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+
+        try {
+            sb.codePointAt(sb.length());
+            fail("No IOOBE on index equal to length.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+
+        try {
+            sb.codePointAt(sb.length() + 1);
+            fail("No IOOBE on index greater than length.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+    }
+
+    /**
+     * java.lang.StringBuilder.codePointBefore(int)
+     */
+    public void test_codePointBeforeI() {
+        StringBuilder sb = new StringBuilder("abc");
+        assertEquals('a', sb.codePointBefore(1));
+        assertEquals('b', sb.codePointBefore(2));
+        assertEquals('c', sb.codePointBefore(3));
+
+        sb = new StringBuilder("\uD800\uDC00");
+        assertEquals(0x10000, sb.codePointBefore(2));
+        assertEquals('\uD800', sb.codePointBefore(1));
+
+        sb = new StringBuilder();
+        sb.append("abc");
+
+        try {
+            sb.codePointBefore(0);
+            fail("No IOOBE on zero index.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+
+        try {
+            sb.codePointBefore(-1);
+            fail("No IOOBE on negative index.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+
+        try {
+            sb.codePointBefore(sb.length() + 1);
+            fail("No IOOBE on index greater than length.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+    }
+
+    /**
+     * 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));
+        assertEquals(1, new StringBuilder("\uDBFF\uDFFF").codePointCount(0, 2));
+
+        assertEquals(3, new StringBuilder("a\uD800\uDC00b").codePointCount(0, 4));
+        assertEquals(4, new StringBuilder("a\uD800\uDC00b\uD800").codePointCount(0, 5));
+
+        StringBuilder sb = new StringBuilder();
+        sb.append("abc");
+        try {
+            sb.codePointCount(-1, 2);
+            fail("No IOOBE for negative begin index.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+
+        try {
+            sb.codePointCount(0, 4);
+            fail("No IOOBE for end index that's too large.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+
+        try {
+            sb.codePointCount(3, 2);
+            fail("No IOOBE for begin index larger than end index.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+    }
+
+    /**
+     * 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());
+
+        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(13, 12);
+            fail("no SIOOBE, start larger than end");
+        } catch (StringIndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        // 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());
+    }
+
+    /**
+     * 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(-1);
+            fail("no SIOOBE, negative index");
+        } catch (StringIndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        try {
+            new StringBuilder(fixture).deleteCharAt(fixture.length());
+            fail("no SIOOBE, index equals length");
+        } catch (StringIndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        try {
+            new StringBuilder(fixture).deleteCharAt(fixture.length() + 1);
+            fail("no SIOOBE, index exceeds length");
+        } catch (StringIndexOutOfBoundsException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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');
+        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(0, 5, dst, 5);
+        fixture.getChars(0, 5, fixtureChars, 5);
+        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));
+
+        try {
+            sb.getChars(0, 10, null, 0);
+            fail("no NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            sb.getChars(-1, 10, dst, 0);
+            fail("no IOOBE, srcBegin negative");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        try {
+            sb.getChars(0, 10, dst, -1);
+            fail("no IOOBE, dstBegin 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, 11, dst, 0);
+            fail("no IOOBE, srcEnd > length");
+        } 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
+        }
+    }
+
+    /**
+     * 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"));
+
+        try {
+            sb.indexOf(null);
+            fail("no NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * 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(0, sb.indexOf("0"), 0);
+        assertEquals(0, sb.indexOf("012"), 0);
+        assertEquals(-1, sb.indexOf("02"), 0);
+        assertEquals(8, sb.indexOf("89"), 0);
+
+        assertEquals(-1, sb.indexOf("0"), 5);
+        assertEquals(-1, sb.indexOf("012"), 5);
+        assertEquals(-1, sb.indexOf("02"), 0);
+        assertEquals(8, sb.indexOf("89"), 5);
+
+        try {
+            sb.indexOf(null, 0);
+            fail("no NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * 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(0, false));
+        assertEquals("false0000", sb.toString());
+        assertEquals(9, 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(4, false));
+        assertEquals("0000false", sb.toString());
+        assertEquals(9, sb.length());
+
+        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
+        }
+    }
+
+    /**
+     * 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
+//		}
+    }
+
+    /**
+     * java.lang.StringBuilder.insert(int, char)
+     */
+    public void test_insertIC_2() {
+        StringBuilder obj = new StringBuilder();
+        try {
+            obj.insert(-1, '?');
+            fail("ArrayIndexOutOfBoundsException expected");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+    }
+
+    /**
+     * 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(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.
+           */
+
+        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(5, new char[] { 'a', 'b' });
+            fail("no SIOOBE, index too large index");
+        } catch (StringIndexOutOfBoundsException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * 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(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(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());
+
+        /*
+           * 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 = 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' }, -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, 3);
+            fail("no SIOOBE, too long");
+        } catch (StringIndexOutOfBoundsException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * 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(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());
+
+        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
+        }
+    }
+
+    /**
+     * 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());
+
+        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, 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, 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());
+
+        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", -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, 3);
+            fail("no IOOBE, too long");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * 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(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());
+
+        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
+        }
+    }
+
+    /**
+     * 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(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());
+
+        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
+        }
+    }
+
+    /**
+     * 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(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());
+
+        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
+        }
+    }
+
+    /**
+     * 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(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());
+
+        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
+        }
+    }
+
+    /**
+     * 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(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());
+
+        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
+        }
+    }
+
+    /**
+     * 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(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());
+
+        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
+        }
+    }
+
+    /**
+     * 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
+        }
+    }
+
+    /**
+     * 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(-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
+        }
+    }
+
+    /**
+     * java.lang.StringBuilder.length()
+     */
+    public void test_length() {
+        StringBuilder sb = new StringBuilder();
+        assertEquals(0, sb.length());
+        sb.append("0000");
+        assertEquals(4, sb.length());
+    }
+
+    /**
+     * java.lang.StringBuilder.offsetByCodePoints(int, int)'
+     */
+    public void test_offsetByCodePointsII() {
+        int result = new StringBuilder("a\uD800\uDC00b").offsetByCodePoints(0, 2);
+        assertEquals(3, result);
+
+        result = new StringBuilder("abcd").offsetByCodePoints(3, -1);
+        assertEquals(2, result);
+
+        result = new StringBuilder("a\uD800\uDC00b").offsetByCodePoints(0, 3);
+        assertEquals(4, result);
+
+        result = new StringBuilder("a\uD800\uDC00b").offsetByCodePoints(3, -1);
+        assertEquals(1, result);
+
+        result = new StringBuilder("a\uD800\uDC00b").offsetByCodePoints(3, 0);
+        assertEquals(3, result);
+
+        result = new StringBuilder("\uD800\uDC00bc").offsetByCodePoints(3, 0);
+        assertEquals(3, result);
+
+        result = new StringBuilder("a\uDC00bc").offsetByCodePoints(3, -1);
+        assertEquals(2, result);
+
+        result = new StringBuilder("a\uD800bc").offsetByCodePoints(3, -1);
+        assertEquals(2, result);
+
+        StringBuilder sb = new StringBuilder();
+        sb.append("abc");
+        try {
+            sb.offsetByCodePoints(-1, 1);
+            fail("No IOOBE for negative index.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+
+        try {
+            sb.offsetByCodePoints(0, 4);
+            fail("No IOOBE for offset that's too large.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+
+        try {
+            sb.offsetByCodePoints(3, -4);
+            fail("No IOOBE for offset that's too small.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+
+        try {
+            sb.offsetByCodePoints(3, 1);
+            fail("No IOOBE for index that's too large.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+
+        try {
+            sb.offsetByCodePoints(4, -1);
+            fail("No IOOBE for index that's too large.");
+        } catch (IndexOutOfBoundsException e) {
+
+        }
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * java.lang.StringBuilder.reverse()
+     */
+    public void test_reverse() {
+        final String fixture = "0123456789";
+        StringBuilder sb = new StringBuilder(fixture);
+        assertSame(sb, sb.reverse());
+        assertEquals("9876543210", sb.toString());
+
+        sb = new StringBuilder("012345678");
+        assertSame(sb, sb.reverse());
+        assertEquals("876543210", sb.toString());
+
+        sb.setLength(1);
+        assertSame(sb, sb.reverse());
+        assertEquals("8", sb.toString());
+
+        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);
+    }
+
+    /**
+     * 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
+        }
+    }
+
+    /**
+     * 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.charAt(3);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        sb = new StringBuilder();
+        sb.append("abcdefg");
+        sb.setLength(2);
+        sb.setLength(5);
+        for (int i = 2; i < 5; i++) {
+            assertEquals(0, sb.charAt(i));
+        }
+
+        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));
+        }
+
+        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));
+        }
+    }
+
+    /**
+     * 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());
+
+        ss = sb.subSequence(0, 0);
+        assertEquals("", ss.toString());
+
+        try {
+            sb.subSequence(-1, 1);
+            fail("No IOOBE, negative start.");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        try {
+            sb.subSequence(0, -1);
+            fail("No IOOBE, negative end.");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        try {
+            sb.subSequence(0, fixture.length() + 1);
+            fail("No IOOBE, end > length.");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        try {
+            sb.subSequence(3, 2);
+            fail("No IOOBE, start > end.");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * 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(10);
+        assertEquals("", ss);
+
+        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(fixture.length() + 1);
+            fail("No SIOOBE, start > length.");
+        } catch (StringIndexOutOfBoundsException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * 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
+        }
+    }
+
+    /**
+     * java.lang.StringBuilder.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());
+    }
+
+    /**
+     * 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() {
+        public void assertDeserialized(Serializable initial,
+                Serializable deserialized) {
+
+            StringBuilder init = (StringBuilder) initial;
+            StringBuilder desr = (StringBuilder) deserialized;
+
+            assertEquals("toString", init.toString(), desr.toString());
+        }
+    };
+    */
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        // SerializationTest.verifySelf(new StringBuilder("0123456789"),
+        //        STRING_BILDER_COMPARATOR);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    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 Fixture() {
+            super();
+        }
+
+        @Override
+        public String toString() {
+            return "fixture";
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/StringIndexOutOfBoundsExceptionTest.java b/luni/src/test/java/tests/api/java/lang/StringIndexOutOfBoundsExceptionTest.java
new file mode 100644
index 0000000..1c26c7d
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/StringIndexOutOfBoundsExceptionTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class StringIndexOutOfBoundsExceptionTest extends TestCase {
+
+    /**
+     * java.lang.StringIndexOutOfBoundsException#StringIndexOutOfBoundsException()
+     */
+    public void test_Constructor() {
+        StringIndexOutOfBoundsException e = new StringIndexOutOfBoundsException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.StringIndexOutOfBoundsException#StringIndexOutOfBoundsException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        StringIndexOutOfBoundsException e = new StringIndexOutOfBoundsException("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/SystemTest.java b/luni/src/test/java/tests/api/java/lang/SystemTest.java
new file mode 100644
index 0000000..cb0d564
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/SystemTest.java
@@ -0,0 +1,413 @@
+/*
+ *  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.lang;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.Map;
+import java.util.Properties;
+
+public class SystemTest extends junit.framework.TestCase {
+
+    static boolean flag = false;
+
+    static boolean ranFinalize = false;
+
+    /**
+     * java.lang.System#setIn(java.io.InputStream)
+     */
+    public void test_setInLjava_io_InputStream() {
+        InputStream orgIn = System.in;
+        InputStream in = new ByteArrayInputStream(new byte[0]);
+        System.setIn(in);
+        assertTrue("in not set", System.in == in);
+        System.setIn(orgIn);
+    }
+
+    /**
+     * java.lang.System#setOut(java.io.PrintStream)
+     */
+    public void test_setOutLjava_io_PrintStream() {
+        PrintStream orgOut = System.out;
+        PrintStream out = new PrintStream(new ByteArrayOutputStream());
+        System.setOut(out);
+        assertTrue("out not set", System.out == out);
+        System.setOut(orgOut);
+    }
+
+    /**
+     * java.lang.System#setErr(java.io.PrintStream)
+     */
+    public void test_setErrLjava_io_PrintStream() {
+        PrintStream orgErr = System.err;
+        PrintStream err = new PrintStream(new ByteArrayOutputStream());
+        System.setErr(err);
+        assertTrue("err not set", System.err == err);
+        System.setErr(orgErr);
+    }
+
+    /**
+     * java.lang.System#arraycopy(java.lang.Object, int,
+     *java.lang.Object, int, int)
+     */
+    public void test_arraycopyLjava_lang_ObjectILjava_lang_ObjectII() {
+        // Test for method void java.lang.System.arraycopy(java.lang.Object,
+        // int, java.lang.Object, int, int)
+        Integer a[] = new Integer[20];
+        Integer b[] = new Integer[20];
+        int i = 0;
+        while (i < a.length) {
+            a[i] = new Integer(i);
+            ++i;
+        }
+        System.arraycopy(a, 0, b, 0, a.length);
+        for (i = 0; i < a.length; i++)
+            assertTrue("Copied elements incorrectly", a[i].equals(b[i]));
+
+        /* Non primitive array types don't need to be identical */
+        String[] source1 = new String[] { "element1" };
+        Object[] dest1 = new Object[1];
+        System.arraycopy(source1, 0, dest1, 0, dest1.length);
+        assertTrue("Invalid copy 1", dest1[0] == source1[0]);
+
+        char[][] source = new char[][] { { 'H', 'e', 'l', 'l', 'o' },
+                { 'W', 'o', 'r', 'l', 'd' } };
+        char[][] dest = new char[2][];
+        System.arraycopy(source, 0, dest, 0, dest.length);
+        assertTrue("Invalid copy 2", dest[0] == source[0]
+                && dest[1] == source[1]);
+    }
+
+    /**
+     * java.lang.System#currentTimeMillis()
+     */
+    public void test_currentTimeMillis() {
+        // Test for method long java.lang.System.currentTimeMillis()
+        long firstRead = System.currentTimeMillis();
+        try {
+            Thread.sleep(150);
+        } catch (InterruptedException e) {
+        }
+        long secondRead = System.currentTimeMillis();
+        assertTrue("Incorrect times returned: " + firstRead + ", "
+                + secondRead, firstRead < secondRead);
+    }
+
+    /**
+     * java.lang.System#exit(int)
+     */
+    public void test_exitI() {
+        // Test for method void java.lang.System.exit(int)
+        // Tested in destructive test: Test_System_Exit ???
+    }
+
+    /**
+     * java.lang.System#getProperties()
+     */
+    public void test_getProperties() {
+        // Test for method java.util.Properties java.lang.System.getProperties()
+        Properties p = System.getProperties();
+
+        // Ensure spec'ed properties are non-null. See System.getProperties()
+        // spec.
+        String[] props = { "java.version", "java.vendor", "java.vendor.url",
+                "java.home", "java.vm.specification.version",
+                "java.vm.specification.vendor", "java.vm.specification.name",
+                "java.vm.version", "java.vm.vendor", "java.vm.name",
+                "java.specification.name", "java.specification.vendor",
+                "java.specification.name", "java.class.version",
+                "java.class.path", "java.ext.dirs", "os.name", "os.arch",
+                "os.version", "file.separator", "path.separator",
+                "line.separator", "user.name", "user.home", "user.dir", };
+        for (int i = 0; i < props.length; i++) {
+            assertNotNull(props[i], System.getProperty(props[i]));
+        }
+    }
+
+    /**
+     * java.lang.System#getProperty(java.lang.String)
+     */
+    public void test_getPropertyLjava_lang_String() {
+        // Test for method java.lang.String
+        // java.lang.System.getProperty(java.lang.String)
+
+        boolean is8859_1 = true;
+        String encoding = System.getProperty("file.encoding");
+        byte[] bytes = new byte[128];
+        char[] chars = new char[128];
+        for (int i = 0; i < bytes.length; i++) {
+            bytes[i] = (byte) (i + 128);
+            chars[i] = (char) (i + 128);
+        }
+        String charResult = new String(bytes);
+        byte[] byteResult = new String(chars).getBytes();
+        if (charResult.length() == 128 && byteResult.length == 128) {
+            for (int i = 0; i < bytes.length; i++) {
+                if (charResult.charAt(i) != (char) (i + 128)
+                        || byteResult[i] != (byte) (i + 128))
+                    is8859_1 = false;
+            }
+        } else
+            is8859_1 = false;
+        String[] possibles = new String[] { "ISO8859_1", "8859_1", "ISO8859-1",
+                "ISO-8859-1", "ISO_8859-1", "ISO_8859-1:1978", "ISO-IR-100",
+                "LATIN1", "CSISOLATIN1" };
+        boolean found8859_1 = false;
+        for (int i = 0; i < possibles.length; i++) {
+            if (possibles[i].equals(encoding)) {
+                found8859_1 = true;
+                break;
+            }
+        }
+        assertTrue("Wrong encoding: " + encoding, !is8859_1 || found8859_1);
+    }
+
+    /**
+     * java.lang.System#getProperty(java.lang.String)
+     * Tests that there are no extra path separator in boot class path.
+     * Regression test for HARMONY-3298
+     */
+    public void test_getProperty_bootClassPath() {
+        String bootClassPath = System.getProperty("org.apache.harmony.boot.class.path");
+
+        if (bootClassPath == null) {
+            bootClassPath = System.getProperty("sun.boot.class.path");
+        }
+
+        if (bootClassPath != null
+                && (bootClassPath.indexOf(File.pathSeparator + File.pathSeparator) >= 0)) {
+            fail("Boot class path contains extra path separator: " + bootClassPath);
+        }
+    }
+
+    /**
+     * java.lang.System#getProperty(java.lang.String, java.lang.String)
+     */
+    public void test_getPropertyLjava_lang_StringLjava_lang_String() {
+        // Test for method java.lang.String
+        // java.lang.System.getProperty(java.lang.String, java.lang.String)
+        assertTrue(!System.getProperty("java.version", "99999").equals("99999"));
+        assertEquals("Failed to return correct property value", "bogus", System
+                .getProperty("bogus.prop", "bogus"));
+    }
+
+    /**
+     * java.lang.System#setProperty(java.lang.String, java.lang.String)
+     */
+    public void test_setPropertyLjava_lang_StringLjava_lang_String() {
+        // Test for method java.lang.String
+        // java.lang.System.setProperty(java.lang.String, java.lang.String)
+
+        assertNull("Failed to return null", System.setProperty("testing",
+                "value1"));
+        assertTrue("Failed to return old value", System.setProperty("testing",
+                "value2") == "value1");
+        assertTrue("Failed to find value",
+                System.getProperty("testing") == "value2");
+
+        boolean exception = false;
+        try {
+            System.setProperty("", "default");
+        } catch (IllegalArgumentException e) {
+            exception = true;
+        }
+        assertTrue("Expected IllegalArgumentException", exception);
+    }
+
+    /**
+     * java.lang.System#getSecurityManager()
+     */
+    public void test_getSecurityManager() {
+        // Test for method java.lang.SecurityManager
+        // java.lang.System.getSecurityManager()
+        assertNull("Returned incorrect SecurityManager", System
+                .getSecurityManager());
+    }
+
+    /**
+     * java.lang.System#identityHashCode(java.lang.Object)
+     */
+    public void test_identityHashCodeLjava_lang_Object() {
+        // Test for method int
+        // java.lang.System.identityHashCode(java.lang.Object)
+        Object o = new Object();
+        String s = "Gabba";
+        assertEquals("Nonzero returned for null",
+                0, System.identityHashCode(null));
+        assertTrue("Nonequal has returned for Object", System
+                .identityHashCode(o) == o.hashCode());
+        assertTrue("Same as usual hash returned for String", System
+                .identityHashCode(s) != s.hashCode());
+    }
+
+    /**
+     * java.lang.System#runFinalization()
+     */
+    public void test_runFinalization() {
+        // Test for method void java.lang.System.runFinalization()
+
+        flag = true;
+        createInstance();
+        int count = 10;
+        // the gc below likely bogosifies the test, but will have to do for
+        // the moment
+        while (!ranFinalize && count-- > 0) {
+            System.gc();
+            System.runFinalization();
+        }
+        assertTrue("Failed to run finalization", ranFinalize);
+    }
+
+    /**
+     * java.lang.System#runFinalizersOnExit(boolean)
+     */
+    @SuppressWarnings("deprecation")
+    public void test_runFinalizersOnExitZ() {
+        // Can we call the method at least?
+        System.runFinalizersOnExit(false);
+    }
+
+    /**
+     * java.lang.System#setProperties(java.util.Properties)
+     */
+    public void test_setPropertiesLjava_util_Properties() {
+        // Test for method void
+        // java.lang.System.setProperties(java.util.Properties)
+
+        Properties orgProps = System.getProperties();
+        java.util.Properties tProps = new java.util.Properties();
+        tProps.put("test.prop", "this is a test property");
+        tProps.put("bogus.prop", "bogus");
+        System.setProperties(tProps);
+        try {
+            assertEquals("Failed to set properties", "this is a test property", System.getProperties()
+                    .getProperty("test.prop"));
+        } finally {
+            // restore the original properties
+            System.setProperties(orgProps);
+        }
+    }
+
+    //Regression Test for Harmony-2356
+    public void testEnvUnmodifiable() {
+        Map map = System.getenv();
+        try {
+            map.containsKey(null);
+            fail("Should throw NullPointerExcepiton.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            map.containsKey(new Integer(10));
+            fail("Should throw ClassCastException.");
+        } catch (ClassCastException e) {
+            // expected
+        }
+
+        try {
+            map.containsValue(null);
+            fail("Should throw NullPointerExcepiton.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            map.containsValue(new Integer(10));
+            fail("Should throw ClassCastException.");
+        } catch (ClassCastException e) {
+            // expected
+        }
+
+        try {
+            map.get(null);
+            fail("Should throw NullPointerExcepiton.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            map.get(new Integer(10));
+            fail("Should throw ClassCastException.");
+        } catch (ClassCastException e) {
+            // expected
+        }
+
+        try {
+            map.put(null, "AAA");
+            fail("Should throw UnsupportedOperationExcepiton.");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+
+        try {
+            map.put("AAA", new Integer(10));
+            fail("Should throw UnsupportedOperationException.");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+
+        try {
+            map.put("AAA", "BBB");
+            fail("Should throw UnsupportedOperationException.");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+
+        try {
+            map.clear();
+            fail("Should throw UnsupportedOperationException.");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+
+        try {
+            map.remove(null);
+            // Android isn't as strict about requiring this exception; no modification takes place anyway
+            // fail("Should throw UnsupportedOperationException.");
+        } catch (UnsupportedOperationException expected) {
+        }
+
+    }
+
+    @Override
+    protected void setUp() {
+        flag = false;
+        ranFinalize = false;
+    }
+
+    protected SystemTest createInstance() {
+        return new SystemTest("FT");
+    }
+
+    @Override
+    protected void finalize() {
+        if (flag)
+            ranFinalize = true;
+    }
+
+    public SystemTest() {
+    }
+
+    public SystemTest(String name) {
+        super(name);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/ThreadDeathTest.java b/luni/src/test/java/tests/api/java/lang/ThreadDeathTest.java
new file mode 100644
index 0000000..0c7fff3
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/ThreadDeathTest.java
@@ -0,0 +1,30 @@
+/*
+ *  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.lang;
+
+public class ThreadDeathTest extends junit.framework.TestCase {
+
+    /**
+     * 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/tests/api/java/lang/ThreadGroupTest.java b/luni/src/test/java/tests/api/java/lang/ThreadGroupTest.java
new file mode 100644
index 0000000..a3c9761
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/ThreadGroupTest.java
@@ -0,0 +1,1110 @@
+/*
+ *  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.lang;
+
+import java.util.Vector;
+
+public class ThreadGroupTest extends junit.framework.TestCase {
+
+    class MyThread extends Thread {
+        public volatile int heartBeat = 0;
+
+        public MyThread(ThreadGroup group, String name)
+                throws SecurityException, IllegalThreadStateException {
+            super(group, name);
+        }
+
+        @Override
+        public void run() {
+            while (true) {
+                heartBeat++;
+                try {
+                    Thread.sleep(50);
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+
+        public boolean isActivelyRunning() {
+            long MAX_WAIT = 100;
+            return isActivelyRunning(MAX_WAIT);
+        }
+
+        public boolean isActivelyRunning(long maxWait) {
+            int beat = heartBeat;
+            long start = System.currentTimeMillis();
+            do {
+                Thread.yield();
+                int beat2 = heartBeat;
+                if (beat != beat2) {
+                    return true;
+                }
+            } while (System.currentTimeMillis() - start < maxWait);
+            return false;
+        }
+
+    }
+
+    private ThreadGroup rootThreadGroup = null;
+
+    private ThreadGroup initialThreadGroup = null;
+
+    /**
+     * java.lang.ThreadGroup#ThreadGroup(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        // Test for method java.lang.ThreadGroup(java.lang.String)
+
+        // Unfortunately we have to use other APIs as well as we test the
+        // constructor
+
+        ThreadGroup newGroup = null;
+        ThreadGroup initial = getInitialThreadGroup();
+        final String name = "Test name";
+        newGroup = new ThreadGroup(name);
+        assertTrue(
+                "Has to be possible to create a subgroup of current group using simple constructor",
+                newGroup.getParent() == initial);
+        assertTrue("Name has to be correct", newGroup.getName().equals(name));
+
+        // cleanup
+        newGroup.destroy();
+
+    }
+
+    /**
+     * java.lang.ThreadGroup#ThreadGroup(java.lang.ThreadGroup,
+     *java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_String() {
+        // Test for method java.lang.ThreadGroup(java.lang.ThreadGroup,
+        // java.lang.String)
+
+        // Unfortunately we have to use other APIs as well as we test the
+        // constructor
+
+        ThreadGroup newGroup = null;
+
+        try {
+            newGroup = new ThreadGroup(null, null);
+        } catch (NullPointerException e) {
+        }
+        assertNull("Can't create a ThreadGroup with a null parent",
+                newGroup);
+
+        newGroup = new ThreadGroup(getInitialThreadGroup(), null);
+        assertTrue("Has to be possible to create a subgroup of current group",
+                newGroup.getParent() == Thread.currentThread().getThreadGroup());
+
+        // Lets start all over
+        newGroup.destroy();
+
+        newGroup = new ThreadGroup(getRootThreadGroup(), "a name here");
+        assertTrue("Has to be possible to create a subgroup of root group",
+                newGroup.getParent() == getRootThreadGroup());
+
+        // Lets start all over
+        newGroup.destroy();
+
+        try {
+            newGroup = new ThreadGroup(newGroup, "a name here");
+        } catch (IllegalThreadStateException e) {
+            newGroup = null;
+        }
+        ;
+        assertNull("Can't create a subgroup of a destroyed group",
+                newGroup);
+    }
+
+    /**
+     * java.lang.ThreadGroup#activeCount()
+     */
+    public void test_activeCount() {
+        // Test for method int java.lang.ThreadGroup.activeCount()
+        ThreadGroup tg = new ThreadGroup("activeCount");
+        Thread t1 = new Thread(tg, new Runnable() {
+            public void run() {
+                try {
+                    Thread.sleep(5000);
+                } catch (InterruptedException e) {
+                }
+            }
+        });
+        int count = tg.activeCount();
+        assertTrue("wrong active count: " + count, count == 0);
+        t1.start();
+        count = tg.activeCount();
+        assertTrue("wrong active count: " + count, count == 1);
+        t1.interrupt();
+        try {
+            t1.join();
+        } catch (InterruptedException e) {
+        }
+        // cleanup
+        tg.destroy();
+    }
+
+    /**
+     * java.lang.ThreadGroup#destroy()
+     */
+    public void test_destroy() {
+        // Test for method void java.lang.ThreadGroup.destroy()
+
+        final ThreadGroup originalCurrent = getInitialThreadGroup();
+        ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group");
+        final int DEPTH = 4;
+        final Vector<ThreadGroup> subgroups = buildRandomTreeUnder(testRoot, DEPTH);
+
+        // destroy them all
+        testRoot.destroy();
+
+        for (int i = 0; i < subgroups.size(); i++) {
+            ThreadGroup child = subgroups.elementAt(i);
+            assertEquals("Destroyed child can't have children", 0, child
+                    .activeCount());
+            boolean passed = false;
+            try {
+                child.destroy();
+            } catch (IllegalThreadStateException e) {
+                passed = true;
+            }
+            ;
+            assertTrue("Destroyed child can't be destroyed again", passed);
+        }
+
+        testRoot = new ThreadGroup(originalCurrent, "Test group (daemon)");
+        testRoot.setDaemon(true);
+
+        ThreadGroup child = new ThreadGroup(testRoot, "daemon child");
+
+        // If we destroy the last daemon's child, the daemon should get destroyed
+        // as well
+        child.destroy();
+
+        boolean passed = false;
+        try {
+            child.destroy();
+        } catch (IllegalThreadStateException e) {
+            passed = true;
+        }
+        ;
+        assertTrue("Daemon should have been destroyed already", passed);
+
+        passed = false;
+        try {
+            testRoot.destroy();
+        } catch (IllegalThreadStateException e) {
+            passed = true;
+        }
+        ;
+        assertTrue("Daemon parent should have been destroyed automatically",
+                passed);
+
+        assertTrue(
+                "Destroyed daemon's child should not be in daemon's list anymore",
+                !arrayIncludes(groups(testRoot), child));
+        assertTrue("Destroyed daemon should not be in parent's list anymore",
+                !arrayIncludes(groups(originalCurrent), testRoot));
+
+        testRoot = new ThreadGroup(originalCurrent, "Test group (daemon)");
+        testRoot.setDaemon(true);
+        Thread noOp = new Thread(testRoot, null, "no-op thread") {
+            @Override
+            public void run() {
+            }
+        };
+        noOp.start();
+
+        // Wait for the no-op thread to run inside daemon ThreadGroup
+        try {
+            noOp.join();
+        } catch (InterruptedException ie) {
+            fail("Should not be interrupted");
+        }
+        ;
+
+        passed = false;
+        try {
+            child.destroy();
+        } catch (IllegalThreadStateException e) {
+            passed = true;
+        }
+        ;
+        assertTrue(
+                "Daemon group should have been destroyed already when last thread died",
+                passed);
+
+        testRoot = new ThreadGroup(originalCurrent, "Test group (daemon)");
+        noOp = new Thread(testRoot, null, "no-op thread") {
+            @Override
+            public void run() {
+                try {
+                    Thread.sleep(500);
+                } catch (InterruptedException ie) {
+                    fail("Should not be interrupted");
+                }
+            }
+        };
+
+        // Has to execute the next lines in an interval < the sleep interval of
+        // the no-op thread
+        noOp.start();
+        passed = false;
+        try {
+            testRoot.destroy();
+        } catch (IllegalThreadStateException its) {
+            passed = true;
+        }
+        assertTrue("Can't destroy a ThreadGroup that has threads", passed);
+
+        // But after the thread dies, we have to be able to destroy the thread
+        // group
+        try {
+            noOp.join();
+        } catch (InterruptedException ie) {
+            fail("Should not be interrupted");
+        }
+        ;
+        passed = true;
+        try {
+            testRoot.destroy();
+        } catch (IllegalThreadStateException its) {
+            passed = false;
+        }
+        assertTrue(
+                "Should be able to destroy a ThreadGroup that has no threads",
+                passed);
+
+    }
+
+    /**
+     * java.lang.ThreadGroup#destroy()
+     */
+    public void test_destroy_subtest0() {
+        ThreadGroup group1 = new ThreadGroup("test_destroy_subtest0");
+        group1.destroy();
+        try {
+            new Thread(group1, "test_destroy_subtest0");
+            fail("should throw IllegalThreadStateException");
+        } catch (IllegalThreadStateException e) {
+        }
+    }
+
+    /**
+     * java.lang.ThreadGroup#getMaxPriority()
+     */
+    public void test_getMaxPriority() {
+        // Test for method int java.lang.ThreadGroup.getMaxPriority()
+
+        final ThreadGroup originalCurrent = getInitialThreadGroup();
+        ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group");
+
+        boolean passed = true;
+        try {
+            testRoot.setMaxPriority(Thread.MIN_PRIORITY);
+        } catch (IllegalArgumentException iae) {
+            passed = false;
+        }
+        assertTrue("Should be able to set priority", passed);
+
+        assertTrue("New value should be the same as we set", testRoot
+                .getMaxPriority() == Thread.MIN_PRIORITY);
+
+        testRoot.destroy();
+
+    }
+
+    /**
+     * java.lang.ThreadGroup#getName()
+     */
+    public void test_getName() {
+        // Test for method java.lang.String java.lang.ThreadGroup.getName()
+
+        final ThreadGroup originalCurrent = getInitialThreadGroup();
+        final String name = "Test group";
+        final ThreadGroup testRoot = new ThreadGroup(originalCurrent, name);
+
+        assertTrue("Setting a name&getting does not work", testRoot.getName()
+                .equals(name));
+
+        testRoot.destroy();
+
+    }
+
+    /**
+     * java.lang.ThreadGroup#getParent()
+     */
+    public void test_getParent() {
+        // Test for method java.lang.ThreadGroup
+        // java.lang.ThreadGroup.getParent()
+
+        final ThreadGroup originalCurrent = getInitialThreadGroup();
+        ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group");
+
+        assertTrue("Parent is wrong", testRoot.getParent() == originalCurrent);
+
+        // Create some groups, nested some levels.
+        final int TOTAL_DEPTH = 5;
+        ThreadGroup current = testRoot;
+        Vector<ThreadGroup> groups = new Vector<ThreadGroup>();
+        // To maintain the invariant that a thread in the Vector is parent
+        // of the next one in the collection (and child of the previous one)
+        groups.addElement(testRoot);
+
+        for (int i = 0; i < TOTAL_DEPTH; i++) {
+            current = new ThreadGroup(current, "level " + i);
+            groups.addElement(current);
+        }
+
+        // Now we walk the levels down, checking if parent is ok
+        for (int i = 1; i < groups.size(); i++) {
+            current = groups.elementAt(i);
+            ThreadGroup previous = groups.elementAt(i - 1);
+            assertTrue("Parent is wrong", current.getParent() == previous);
+        }
+
+        testRoot.destroy();
+    }
+
+    /**
+     * java.lang.ThreadGroup#isDaemon()
+     */
+    public void test_isDaemon() {
+        // Test for method boolean java.lang.ThreadGroup.isDaemon()
+
+        daemonTests();
+
+    }
+
+    /**
+     * java.lang.ThreadGroup#list()
+     */
+    public void test_list() {
+        // Test for method void java.lang.ThreadGroup.list()
+
+        final ThreadGroup originalCurrent = getInitialThreadGroup();
+        // wipeSideEffectThreads destroy all side effect of threads created in
+        // java.lang.Thread
+        boolean result = wipeSideEffectThreads(originalCurrent);
+        if (result == false) {
+            fail("wipe threads in test_list() not successful");
+        }
+        final ThreadGroup testRoot = new ThreadGroup(originalCurrent,
+                "Test group");
+
+        // First save the original System.out
+        java.io.PrintStream originalOut = System.out;
+
+        try {
+            java.io.ByteArrayOutputStream contentsStream = new java.io.ByteArrayOutputStream(
+                    100);
+            java.io.PrintStream newOut = new java.io.PrintStream(contentsStream);
+
+            // We have to "redirect" System.out to test the method 'list'
+            System.setOut(newOut);
+
+            originalCurrent.list();
+
+            /*
+                * The output has to look like this
+                *
+                * java.lang.ThreadGroup[name=main,maxpri=10] Thread[main,5,main]
+                * java.lang.ThreadGroup[name=Test group,maxpri=10]
+                *
+                */
+
+            String contents = new String(contentsStream.toByteArray());
+            boolean passed = (contents.indexOf("ThreadGroup[name=main") != -1) &&
+                    (contents.indexOf("Thread[") != -1) &&
+                    (contents.indexOf("ThreadGroup[name=Test group") != -1);
+            assertTrue("'list()' does not print expected contents. "
+                    + "Result from list: "
+                    + contents, passed);
+            // Do proper cleanup
+            testRoot.destroy();
+
+        } finally {
+            // No matter what, we need to restore the original System.out
+            System.setOut(originalOut);
+        }
+
+    }
+
+    /**
+     * java.lang.ThreadGroup#parentOf(java.lang.ThreadGroup)
+     */
+    public void test_parentOfLjava_lang_ThreadGroup() {
+        // Test for method boolean
+        // java.lang.ThreadGroup.parentOf(java.lang.ThreadGroup)
+
+        final ThreadGroup originalCurrent = getInitialThreadGroup();
+        final ThreadGroup testRoot = new ThreadGroup(originalCurrent,
+                "Test group");
+        final int DEPTH = 4;
+        buildRandomTreeUnder(testRoot, DEPTH);
+
+        final ThreadGroup[] allChildren = allGroups(testRoot);
+        for (ThreadGroup element : allChildren) {
+            assertTrue("Have to be parentOf all children", testRoot
+                    .parentOf(element));
+        }
+
+        assertTrue("Have to be parentOf itself", testRoot.parentOf(testRoot));
+
+        testRoot.destroy();
+        assertTrue("Parent can't have test group as subgroup anymore",
+                !arrayIncludes(groups(testRoot.getParent()), testRoot));
+    }
+
+    /**
+     * java.lang.ThreadGroup#setDaemon(boolean)
+     */
+    public void test_setDaemonZ() {
+        // Test for method void java.lang.ThreadGroup.setDaemon(boolean)
+
+        daemonTests();
+
+    }
+
+    /*
+     * java.lang.ThreadGroupt#setDaemon(boolean)
+     */
+    public void test_setDaemon_Parent_Child() {
+        ThreadGroup ptg = new ThreadGroup("Parent");
+        ThreadGroup ctg = new ThreadGroup(ptg, "Child");
+
+        ctg.setDaemon(true);
+        assertTrue(ctg.isDaemon());
+
+        ctg.setDaemon(false);
+        assertFalse(ctg.isDaemon());
+
+        ptg.setDaemon(true);
+        assertFalse(ctg.isDaemon());
+
+        ptg.setDaemon(false);
+        assertFalse(ctg.isDaemon());
+    }
+
+    /**
+     * java.lang.ThreadGroup#setMaxPriority(int)
+     */
+    public void test_setMaxPriorityI() {
+        // Test for method void java.lang.ThreadGroup.setMaxPriority(int)
+
+        final ThreadGroup originalCurrent = getInitialThreadGroup();
+        ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group");
+
+        boolean passed;
+
+        // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+        int currentMax = testRoot.getMaxPriority();
+        testRoot.setMaxPriority(Thread.MAX_PRIORITY + 1);
+        passed = testRoot.getMaxPriority() == currentMax;
+        assertTrue(
+                "setMaxPriority: Any value higher than the current one is ignored. Before: "
+                        + currentMax + " , after: " + testRoot.getMaxPriority(),
+                passed);
+
+        // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+        currentMax = testRoot.getMaxPriority();
+        testRoot.setMaxPriority(Thread.MIN_PRIORITY - 1);
+        passed = testRoot.getMaxPriority() == Thread.MIN_PRIORITY;
+        assertTrue(
+                "setMaxPriority: Any value smaller than MIN_PRIORITY is adjusted to MIN_PRIORITY. Before: "
+                        + currentMax + " , after: " + testRoot.getMaxPriority(),
+                passed);
+
+        // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+        testRoot.destroy();
+        testRoot = new ThreadGroup(originalCurrent, "Test group");
+
+        // Create some groups, nested some levels. Each level will have maxPrio
+        // 1 unit smaller than the parent's. However, there can't be a group
+        // with priority < Thread.MIN_PRIORITY
+        final int TOTAL_DEPTH = testRoot.getMaxPriority() - Thread.MIN_PRIORITY
+                - 2;
+        ThreadGroup current = testRoot;
+        for (int i = 0; i < TOTAL_DEPTH; i++) {
+            current = new ThreadGroup(current, "level " + i);
+        }
+
+        // Now we walk the levels down, changing the maxPrio and later verifying
+        // that the value is indeed 1 unit smaller than the parent's maxPrio.
+        int maxPrio, parentMaxPrio;
+        current = testRoot;
+
+        // To maintain the invariant that when we are to modify a child,
+        // its maxPriority is always 1 unit smaller than its parent's.
+        // We have to set it for the root manually, and the loop does the rest
+        // for all the other sub-levels
+        current.setMaxPriority(current.getParent().getMaxPriority() - 1);
+
+        for (int i = 0; i < TOTAL_DEPTH; i++) {
+            maxPrio = current.getMaxPriority();
+            parentMaxPrio = current.getParent().getMaxPriority();
+
+            ThreadGroup[] children = groups(current);
+            assertEquals("Can only have 1 subgroup", 1, children.length);
+            current = children[0];
+            assertTrue(
+                    "Had to be 1 unit smaller than parent's priority in iteration="
+                            + i + " checking->" + current,
+                    maxPrio == parentMaxPrio - 1);
+            current.setMaxPriority(maxPrio - 1);
+
+            // The next test is sort of redundant, since in next iteration it
+            // will be the parent tGroup, so the test will be done.
+            assertTrue("Had to be possible to change max priority", current
+                    .getMaxPriority() == maxPrio - 1);
+        }
+
+        assertTrue(
+                "Priority of leaf child group has to be much smaller than original root group",
+                current.getMaxPriority() == testRoot.getMaxPriority()
+                        - TOTAL_DEPTH);
+
+        testRoot.destroy();
+
+        // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+        passed = true;
+        testRoot = new ThreadGroup(originalCurrent, "Test group");
+        try {
+            testRoot.setMaxPriority(Thread.MAX_PRIORITY);
+        } catch (IllegalArgumentException iae) {
+            passed = false;
+        }
+        assertTrue(
+                "Max Priority = Thread.MAX_PRIORITY should be possible if the test is run with default system ThreadGroup as root",
+                passed);
+        testRoot.destroy();
+    }
+
+    /**
+     * java.lang.ThreadGroup#uncaughtException(java.lang.Thread,
+     *java.lang.Throwable)
+     */
+    @SuppressWarnings("deprecation")
+    public void test_uncaughtExceptionLjava_lang_ThreadLjava_lang_Throwable() {
+        // Test for method void
+        // java.lang.ThreadGroup.uncaughtException(java.lang.Thread,
+        // java.lang.Throwable)
+
+        final ThreadGroup originalCurrent = getInitialThreadGroup();
+
+        // indices for the array defined below
+        final int TEST_DEATH = 0;
+        final int TEST_OTHER = 1;
+        final int TEST_EXCEPTION_IN_UNCAUGHT = 2;
+        final int TEST_OTHER_THEN_DEATH = 3;
+        final int TEST_FORCING_THROW_THREAD_DEATH = 4;
+        final int TEST_KILLING = 5;
+        final int TEST_DEATH_AFTER_UNCAUGHT = 6;
+
+        final boolean[] passed = new boolean[] { false, false, false, false,
+                false, false, false };
+
+        ThreadGroup testRoot;
+        Thread thread;
+
+        // Our own exception class
+        class TestException extends RuntimeException {
+            private static final long serialVersionUID = 1L;
+        }
+
+        // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+        // - - - - - - -
+        testRoot = new ThreadGroup(originalCurrent,
+                "Test killing a Thread, forcing it to throw ThreadDeath") {
+            @Override
+            public void uncaughtException(Thread t, Throwable e) {
+                if (e instanceof ThreadDeath) {
+                    passed[TEST_KILLING] = true;
+                }
+                // always forward, any exception
+                super.uncaughtException(t, e);
+            }
+        };
+
+        // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+        // - - - - - - -
+        testRoot = new ThreadGroup(originalCurrent,
+                "Test Forcing a throw of ThreadDeath") {
+            @Override
+            public void uncaughtException(Thread t, Throwable e) {
+                if (e instanceof ThreadDeath) {
+                    passed[TEST_FORCING_THROW_THREAD_DEATH] = true;
+                }
+                // always forward, any exception
+                super.uncaughtException(t, e);
+            }
+        };
+
+        // Test if a Thread tells its ThreadGroup about ThreadDeath
+        thread = new Thread(testRoot, null, "suicidal thread") {
+            @Override
+            public void run() {
+                throw new ThreadDeath();
+            }
+        };
+        thread.start();
+        try {
+            thread.join();
+        } catch (InterruptedException ie) {
+            fail("Should not have been interrupted");
+        }
+        testRoot.destroy();
+        assertTrue(
+                "Any thread should notify its ThreadGroup about its own death, even if suicide:"
+                        + testRoot, passed[TEST_FORCING_THROW_THREAD_DEATH]);
+
+        // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+        // - - - - - - -
+
+        testRoot = new ThreadGroup(originalCurrent, "Test ThreadDeath") {
+            @Override
+            public void uncaughtException(Thread t, Throwable e) {
+                passed[TEST_DEATH] = false;
+                // always forward, any exception
+                super.uncaughtException(t, e);
+            }
+        };
+
+        // Test if a Thread tells its ThreadGroup about ThreadDeath
+        passed[TEST_DEATH] = true;
+        thread = new Thread(testRoot, null, "no-op thread");
+        thread.start();
+        try {
+            thread.join();
+        } catch (InterruptedException ie) {
+            fail("Should not have been interrupted");
+        }
+        testRoot.destroy();
+        assertTrue("A thread should not call uncaughtException when it dies:"
+                + testRoot, passed[TEST_DEATH]);
+
+        // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+        // - - - - - - -
+
+        testRoot = new ThreadGroup(originalCurrent, "Test other Exception") {
+            @Override
+            public void uncaughtException(Thread t, Throwable e) {
+                if (e instanceof TestException) {
+                    passed[TEST_OTHER] = true;
+                } else {
+                    // only forward exceptions other than our test
+                    super.uncaughtException(t, e);
+                }
+            }
+        };
+
+        // Test if a Thread tells its ThreadGroup about an Exception
+        thread = new Thread(testRoot, null, "no-op thread") {
+            @Override
+            public void run() {
+                throw new TestException();
+            }
+        };
+        thread.start();
+        try {
+            thread.join();
+        } catch (InterruptedException ie) {
+            fail("Should not have been interrupted");
+        }
+        testRoot.destroy();
+        assertTrue(
+                "Any thread should notify its ThreadGroup about an uncaught exception:"
+                        + testRoot, passed[TEST_OTHER]);
+
+        // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+        // - - - - - - -
+
+        // Our own uncaught exception class
+        class UncaughtException extends TestException {
+            private static final long serialVersionUID = 1L;
+        }
+
+        testRoot = new ThreadGroup(originalCurrent,
+                "Test Exception in uncaught exception") {
+            @Override
+            public void uncaughtException(Thread t, Throwable e) {
+                if (e instanceof TestException) {
+                    passed[TEST_EXCEPTION_IN_UNCAUGHT] = true;
+                    // Let's simulate an error inside our uncaughtException
+                    // method.
+                    // This should be no-op according to the spec
+                    throw new UncaughtException();
+                }
+                // only forward exceptions other than our test
+                super.uncaughtException(t, e);
+            }
+        };
+
+        // Test if an Exception in uncaughtException is really a no-op
+        thread = new Thread(testRoot, null, "no-op thread") {
+            @Override
+            public void run() {
+                try {
+                    throw new TestException();
+                } catch (UncaughtException ue) {
+                    // any exception in my ThreadGroup's uncaughtException must
+                    // not be propagated.
+                    // If it gets propagated and we detected that, the test failed
+                    passed[TEST_EXCEPTION_IN_UNCAUGHT] = false;
+                }
+            }
+        };
+        thread.start();
+        try {
+            thread.join();
+        } catch (InterruptedException ie) {
+            fail("Should not have been interrupted");
+        }
+        testRoot.destroy();
+        assertTrue(
+                "Any uncaughtException in uncaughtException should be no-op:"
+                        + testRoot, passed[TEST_EXCEPTION_IN_UNCAUGHT]);
+
+        // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+        // - - - - - - -
+
+        // This is a mix of 2 of the tests above. It is assumed that ThreadDeath
+        // and any random exception do work , tested separately. Now we test
+        // if after an uncaughtException is forwarded to the ThreadGroup and
+        // the Thread dies, if ThreadDeath is also forwarded. It should be
+        // (so that a ThreadGroup can know its Thread died)
+        testRoot = new ThreadGroup(originalCurrent,
+                "Test Uncaught followed by ThreadDeath") {
+            @Override
+            public void uncaughtException(Thread t, Throwable e) {
+                if (e instanceof ThreadDeath) {
+                    passed[TEST_DEATH_AFTER_UNCAUGHT] = true;
+                }
+                if (e instanceof TestException) {
+                    passed[TEST_OTHER_THEN_DEATH] = true;
+                } else {
+                    // only forward exceptions other than our test
+                    super.uncaughtException(t, e);
+                }
+            }
+        };
+
+        // Test if a Thread tells its ThreadGroup about an Exception and also
+        // ThreadDeath
+        thread = new Thread(testRoot, null, "no-op thread") {
+            @Override
+            public void run() {
+                throw new TestException();
+            }
+        };
+        thread.start();
+        try {
+            thread.join();
+        } catch (InterruptedException ie) {
+            fail("Should not have been interrupted");
+        }
+        testRoot.destroy();
+    }
+
+    @Override
+    protected void setUp() {
+        initialThreadGroup = Thread.currentThread().getThreadGroup();
+        rootThreadGroup = initialThreadGroup;
+        while (rootThreadGroup.getParent() != null) {
+            rootThreadGroup = rootThreadGroup.getParent();
+        }
+    }
+
+    @Override
+    protected void tearDown() {
+        try {
+            // Give the threads a chance to die.
+            Thread.sleep(50);
+        } catch (InterruptedException e) {
+        }
+    }
+
+    private Thread[] threads(ThreadGroup parent) {
+        // No API to get the count of immediate children only ?
+        int count = parent.activeCount();
+        Thread[] all = new Thread[count];
+        int actualSize = parent.enumerate(all, false);
+        Thread[] result;
+        if (actualSize == all.length) {
+            result = all;
+        } else {
+            result = new Thread[actualSize];
+            System.arraycopy(all, 0, result, 0, actualSize);
+        }
+
+        return result;
+
+    }
+
+    private ThreadGroup getInitialThreadGroup() {
+        return initialThreadGroup;
+    }
+
+    private ThreadGroup[] allGroups(ThreadGroup parent) {
+        int count = parent.activeGroupCount();
+        ThreadGroup[] all = new ThreadGroup[count];
+        parent.enumerate(all, true);
+        return all;
+    }
+
+    private void daemonTests() {
+        // Test for method void java.lang.ThreadGroup.setDaemon(boolean)
+
+        final ThreadGroup originalCurrent = getInitialThreadGroup();
+        final ThreadGroup testRoot = new ThreadGroup(originalCurrent,
+                "Test group");
+
+        testRoot.setDaemon(true);
+        assertTrue("Setting daemon&getting does not work", testRoot.isDaemon());
+
+        testRoot.setDaemon(false);
+        assertTrue("Setting daemon&getting does not work", !testRoot.isDaemon());
+
+        testRoot.destroy();
+
+    }
+
+    private boolean wipeAllThreads(final ThreadGroup aGroup) {
+        boolean ok = true;
+        Thread[] threads = threads(aGroup);
+        for (Thread t : threads) {
+            ok = ok && wipeThread(t);
+        }
+
+        // Recursively for subgroups (if any)
+        ThreadGroup[] children = groups(aGroup);
+        for (ThreadGroup element : children) {
+            ok = ok && wipeAllThreads(element);
+        }
+
+        return ok;
+
+    }
+
+    private boolean wipeSideEffectThreads(ThreadGroup aGroup) {
+        boolean ok = true;
+        Thread[] threads = threads(aGroup);
+        for (Thread t : threads) {
+            if (t.getName().equals("SimpleThread")
+                    || t.getName().equals("Bogus Name")
+                    || t.getName().equals("Testing")
+                    || t.getName().equals("foo")
+                    || t.getName().equals("Test Group")
+                    || t.getName().equals("Squawk")
+                    || t.getName().equals("Thread-1")
+                    || t.getName().equals("firstOne")
+                    || t.getName().equals("secondOne")
+                    || t.getName().equals("Thread-16")
+                    || t.getName().equals("Thread-14")) {
+                ok = ok && wipeThread(t);
+            }
+        }
+
+        // Recursively for subgroups (if any)
+        ThreadGroup[] children = groups(aGroup);
+
+        for (ThreadGroup element : children) {
+            ok = ok && wipeSideEffectThreads(element);
+            if (element.getName().equals("Test Group")
+                    || element.getName().equals("foo")
+                    || element.getName().equals("jp")) {
+                element.destroy();
+            }
+        }
+        try {
+            // Give the threads a chance to die.
+            Thread.sleep(50);
+        } catch (InterruptedException e) {
+        }
+        return ok;
+    }
+
+    private void asyncBuildRandomTreeUnder(final ThreadGroup aGroup,
+            final int depth, final Vector<ThreadGroup> allCreated) {
+        if (depth <= 0) {
+            return;
+        }
+
+        final int maxImmediateSubgroups = random(3);
+        for (int i = 0; i < maxImmediateSubgroups; i++) {
+            final int iClone = i;
+            final String name = " Depth = " + depth + ",N = " + iClone
+                    + ",Vector size at creation: " + allCreated.size();
+            // Use concurrency to maximize chance of exposing concurrency bugs
+            // in ThreadGroups
+            Thread t = new Thread(aGroup, name) {
+                @Override
+                public void run() {
+                    ThreadGroup newGroup = new ThreadGroup(aGroup, name);
+                    allCreated.addElement(newGroup);
+                    asyncBuildRandomTreeUnder(newGroup, depth - 1, allCreated);
+                }
+            };
+            t.start();
+        }
+
+    }
+
+    private Vector<ThreadGroup> asyncBuildRandomTreeUnder(final ThreadGroup aGroup,
+            final int depth) {
+        Vector<ThreadGroup> result = new Vector<ThreadGroup>();
+        asyncBuildRandomTreeUnder(aGroup, depth, result);
+        return result;
+
+    }
+
+    private boolean allSuspended(Vector<MyThread> threads) {
+        for (int i = 0; i < threads.size(); i++) {
+            MyThread t = threads.elementAt(i);
+            if (t.isActivelyRunning()) {
+                return false;
+            }
+        }
+
+        return true;
+
+    }
+
+    private ThreadGroup[] groups(ThreadGroup parent) {
+        // No API to get the count of immediate children only ?
+        int count = parent.activeGroupCount();
+        ThreadGroup[] all = new ThreadGroup[count];
+        parent.enumerate(all, false);
+        // Now we may have nulls in the array, we must find the actual size
+        int actualSize = 0;
+        for (; actualSize < all.length; actualSize++) {
+            if (all[actualSize] == null) {
+                break;
+            }
+        }
+        ThreadGroup[] result;
+        if (actualSize == all.length) {
+            result = all;
+        } else {
+            result = new ThreadGroup[actualSize];
+            System.arraycopy(all, 0, result, 0, actualSize);
+        }
+
+        return result;
+
+    }
+
+    private Vector<MyThread> populateGroupsWithThreads(final ThreadGroup aGroup,
+            final int threadCount) {
+        Vector<MyThread> result = new Vector<MyThread>();
+        populateGroupsWithThreads(aGroup, threadCount, result);
+        return result;
+
+    }
+
+    private void populateGroupsWithThreads(final ThreadGroup aGroup,
+            final int threadCount, final Vector<MyThread> allCreated) {
+        for (int i = 0; i < threadCount; i++) {
+            final int iClone = i;
+            final String name = "(MyThread)N =" + iClone + "/" + threadCount
+                    + " ,Vector size at creation: " + allCreated.size();
+
+            MyThread t = new MyThread(aGroup, name);
+            allCreated.addElement(t);
+        }
+
+        // Recursively for subgroups (if any)
+        ThreadGroup[] children = groups(aGroup);
+        for (ThreadGroup element : children) {
+            populateGroupsWithThreads(element, threadCount, allCreated);
+        }
+
+    }
+
+    private int random(int max) {
+
+        return 1 + ((new Object()).hashCode() % max);
+
+    }
+
+    @SuppressWarnings("deprecation")
+    private boolean wipeThread(Thread t) {
+        t.stop();
+        try {
+            t.join(1000);
+        } catch (InterruptedException ie) {
+            fail("Should not have been interrupted");
+        }
+        // The thread had plenty (subjective) of time to die so there
+        // is a problem.
+        if (t.isAlive()) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private Vector<ThreadGroup> buildRandomTreeUnder(ThreadGroup aGroup, int depth) {
+        Vector<ThreadGroup> result = asyncBuildRandomTreeUnder(aGroup, depth);
+        while (true) {
+            int sizeBefore = result.size();
+            try {
+                Thread.sleep(1000);
+                int sizeAfter = result.size();
+                // If no activity for a while, we assume async building may be
+                // done.
+                if (sizeBefore == sizeAfter) {
+                    // It can only be done if no more threads. Unfortunately we
+                    // are relying on this API to work as well.
+                    // If it does not, we may loop forever.
+                    if (aGroup.activeCount() == 0) {
+                        break;
+                    }
+                }
+            } catch (InterruptedException e) {
+            }
+        }
+        return result;
+
+    }
+
+    private boolean arrayIncludes(Object[] array, Object toTest) {
+        for (Object element : array) {
+            if (element == toTest) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    protected void myassertTrue(String msg, boolean b) {
+        // This method is defined here just to solve a visibility problem
+        // of protected methods with inner types
+        assertTrue(msg, b);
+    }
+
+    private ThreadGroup getRootThreadGroup() {
+        return rootThreadGroup;
+
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/ThreadLocalTest.java b/luni/src/test/java/tests/api/java/lang/ThreadLocalTest.java
new file mode 100644
index 0000000..a0902d8
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/ThreadLocalTest.java
@@ -0,0 +1,150 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class ThreadLocalTest extends TestCase {
+
+    /**
+     * java.lang.ThreadLocal#ThreadLocal()
+     */
+    public void test_Constructor() {
+        new ThreadLocal<Object>();
+    }
+
+    /**
+     * java.lang.ThreadLocal#remove()
+     */
+    public void test_remove() {
+        ThreadLocal<String> tl = new ThreadLocal<String>() {
+            @Override
+            protected String initialValue() {
+                return "initial";
+            }
+        };
+
+        assertEquals("initial", tl.get());
+        tl.set("fixture");
+        assertEquals("fixture", tl.get());
+        tl.remove();
+        assertEquals("initial", tl.get());
+    }
+
+    /**
+     * java.lang.ThreadLocal#get()
+     */
+    public void test_get() {
+        // Test for method java.lang.Object java.lang.ThreadLocal.get()
+        ThreadLocal<Object> l = new ThreadLocal<Object>();
+        assertNull("ThreadLocal's initial value is null", l.get());
+
+        // The ThreadLocal has to run once for each thread that touches the
+        // ThreadLocal
+        final Object INITIAL_VALUE = "'foo'";
+        final ThreadLocal<Object> l1 = new ThreadLocal<Object>() {
+            @Override
+            protected Object initialValue() {
+                return INITIAL_VALUE;
+            }
+        };
+
+        assertTrue("ThreadLocal's initial value should be " + INITIAL_VALUE
+                + " but is " + l1.get(), l1.get() == INITIAL_VALUE);
+
+        // We need this because inner types cannot assign to variables in
+        // container method. But assigning to object slots in the container
+        // method is ok.
+        class ResultSlot {
+            public Object result = null;
+        }
+
+        final ResultSlot THREADVALUE = new ResultSlot();
+        Thread t = new Thread() {
+            @Override
+            public void run() {
+                THREADVALUE.result = l1.get();
+            }
+        };
+
+        // Wait for the other Thread assign what it observes as the value of the
+        // variable
+        t.start();
+        try {
+            t.join();
+        } catch (InterruptedException ie) {
+            fail("Interrupted!!");
+        }
+
+        assertTrue("ThreadLocal's initial value in other Thread should be "
+                + INITIAL_VALUE, THREADVALUE.result == INITIAL_VALUE);
+
+        /* Regression test for implementation vulnerability reported
+         * on Harmony dev list.
+         */
+        ThreadLocal<Object> thrVar = new ThreadLocal<Object>() {
+            public int hashCode() {
+                fail("ThreadLocal should not be asked for it's hashCode");
+                return 0; // never reached
+            }
+        };
+        thrVar.get();
+    }
+
+    /**
+     * java.lang.ThreadLocal#set(java.lang.Object)
+     */
+    public void test_setLjava_lang_Object() {
+        // Test for method void java.lang.ThreadLocal.set(java.lang.Object)
+
+        final Object OBJ = new Object();
+        final ThreadLocal<Object> l = new ThreadLocal<Object>();
+        l.set(OBJ);
+        assertTrue("ThreadLocal's initial value is " + OBJ, l.get() == OBJ);
+
+        // We need this because inner types cannot assign to variables in
+        // container method.
+        // But assigning to object slots in the container method is ok.
+        class ResultSlot {
+            public Object result = null;
+        }
+
+        final ResultSlot THREADVALUE = new ResultSlot();
+        Thread t = new Thread() {
+            @Override
+            public void run() {
+                THREADVALUE.result = l.get();
+            }
+        };
+
+        // Wait for the other Thread assign what it observes as the value of the
+        // variable
+        t.start();
+        try {
+            t.join();
+        } catch (InterruptedException ie) {
+            fail("Interrupted!!");
+        }
+
+        // ThreadLocal is not inherited, so the other Thread should see it as
+        // null
+        assertNull("ThreadLocal's value in other Thread should be null",
+                THREADVALUE.result);
+
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/ThreadTest.java b/luni/src/test/java/tests/api/java/lang/ThreadTest.java
new file mode 100644
index 0000000..f246039
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/ThreadTest.java
@@ -0,0 +1,1017 @@
+/*
+ *  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.lang;
+
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.security.Permission;
+import java.util.Map;
+
+public class ThreadTest extends junit.framework.TestCase {
+
+    static class SimpleThread implements Runnable {
+        int delay;
+
+        public void run() {
+            try {
+                synchronized (this) {
+                    this.notify();
+                    this.wait(delay);
+                }
+            } catch (InterruptedException e) {
+                return;
+            }
+
+        }
+
+        public SimpleThread(int d) {
+            if (d >= 0)
+                delay = d;
+        }
+    }
+
+    static class YieldThread implements Runnable {
+        volatile int delay;
+
+        public void run() {
+            int x = 0;
+            while (true) {
+                ++x;
+            }
+        }
+
+        public YieldThread(int d) {
+            if (d >= 0)
+                delay = d;
+        }
+    }
+
+    static class ResSupThread implements Runnable {
+        Thread parent;
+
+        volatile int checkVal = -1;
+
+        public void run() {
+            try {
+                synchronized (this) {
+                    this.notify();
+                }
+                while (true) {
+                    checkVal++;
+                    zz();
+                    Thread.sleep(100);
+                }
+            } catch (InterruptedException e) {
+                return;
+            } catch (BogusException e) {
+                try {
+                    // Give parent a chance to sleep
+                    Thread.sleep(500);
+                } catch (InterruptedException x) {
+                }
+                parent.interrupt();
+                while (!Thread.currentThread().isInterrupted()) {
+                    // Don't hog the CPU
+                    try {
+                        Thread.sleep(50);
+                    } catch (InterruptedException x) {
+                        // This is what we've been waiting for...don't throw it
+                        // away!
+                        break;
+                    }
+                }
+            }
+        }
+
+        public void zz() throws BogusException {
+        }
+
+        public ResSupThread(Thread t) {
+            parent = t;
+        }
+
+        public synchronized int getCheckVal() {
+            return checkVal;
+        }
+    }
+
+    static class BogusException extends Throwable {
+
+        private static final long serialVersionUID = 1L;
+
+        public BogusException(String s) {
+            super(s);
+        }
+    }
+
+    Thread st, ct, spinner;
+
+    /**
+     * java.lang.Thread#Thread(java.lang.Runnable)
+     */
+    public void test_ConstructorLjava_lang_Runnable() {
+        // Test for method java.lang.Thread(java.lang.Runnable)
+        ct = new Thread(new SimpleThread(10));
+        ct.start();
+    }
+
+    /**
+     * java.lang.Thread#Thread(java.lang.Runnable, java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_RunnableLjava_lang_String() {
+        // Test for method java.lang.Thread(java.lang.Runnable,
+        // java.lang.String)
+        Thread st1 = new Thread(new SimpleThread(1), "SimpleThread1");
+        assertEquals("Constructed thread with incorrect thread name", "SimpleThread1", st1
+                .getName());
+        st1.start();
+    }
+
+    /**
+     * java.lang.Thread#Thread(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        // Test for method java.lang.Thread(java.lang.String)
+        Thread t = new Thread("Testing");
+        assertEquals("Created tread with incorrect name",
+                "Testing", t.getName());
+        t.start();
+    }
+
+    /**
+     * java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.Runnable)
+     */
+    public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_Runnable() {
+        // Test for method java.lang.Thread(java.lang.ThreadGroup,
+        // java.lang.Runnable)
+        ThreadGroup tg = new ThreadGroup("Test Group1");
+        st = new Thread(tg, new SimpleThread(1), "SimpleThread2");
+        assertTrue("Returned incorrect thread group", st.getThreadGroup() == tg);
+        st.start();
+        try {
+            st.join();
+        } catch (InterruptedException e) {
+        }
+        tg.destroy();
+    }
+
+    /**
+     * java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.Runnable,
+     *java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_RunnableLjava_lang_String() {
+        // Test for method java.lang.Thread(java.lang.ThreadGroup,
+        // java.lang.Runnable, java.lang.String)
+        ThreadGroup tg = new ThreadGroup("Test Group2");
+        st = new Thread(tg, new SimpleThread(1), "SimpleThread3");
+        assertTrue("Constructed incorrect thread", (st.getThreadGroup() == tg)
+                && st.getName().equals("SimpleThread3"));
+        st.start();
+        try {
+            st.join();
+        } catch (InterruptedException e) {
+        }
+        tg.destroy();
+
+        Runnable r = new Runnable() {
+            public void run() {
+            }
+        };
+
+        ThreadGroup foo = null;
+        try {
+            new Thread(foo = new ThreadGroup("foo"), r, null);
+            // Should not get here
+            fail("Null cannot be accepted as Thread name");
+        } catch (NullPointerException npe) {
+            assertTrue("Null cannot be accepted as Thread name", true);
+            foo.destroy();
+        }
+
+    }
+
+    /**
+     * java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_String() {
+        // Test for method java.lang.Thread(java.lang.ThreadGroup,
+        // java.lang.String)
+        st = new Thread(new SimpleThread(1), "SimpleThread4");
+        assertEquals("Returned incorrect thread name",
+                "SimpleThread4", st.getName());
+        st.start();
+    }
+
+    /**
+     * java.lang.Thread#activeCount()
+     */
+    public void test_activeCount() {
+        // Test for method int java.lang.Thread.activeCount()
+        Thread t = new Thread(new SimpleThread(10));
+        int active = 0;
+        synchronized (t) {
+            t.start();
+            active = Thread.activeCount();
+        }
+        assertTrue("Incorrect activeCount for current group: " + active, active > 1);
+        try {
+            t.join();
+        } catch (InterruptedException e) {
+        }
+    }
+
+    /**
+     * java.lang.Thread#checkAccess()
+     */
+    public void test_checkAccess() {
+        // Test for method void java.lang.Thread.checkAccess()
+        ThreadGroup tg = new ThreadGroup("Test Group3");
+        try {
+            st = new Thread(tg, new SimpleThread(1), "SimpleThread5");
+            st.checkAccess();
+            assertTrue("CheckAccess passed", true);
+        } catch (SecurityException e) {
+            fail("CheckAccess failed : " + e.getMessage());
+        }
+        st.start();
+        try {
+            st.join();
+        } catch (InterruptedException e) {
+        }
+        tg.destroy();
+    }
+
+    /**
+     * java.lang.Thread#countStackFrames()
+     */
+    @SuppressWarnings("deprecation")
+    public void test_countStackFrames() {
+        /*
+         * Thread.countStackFrames() is unpredictable, so we just test that it
+         * doesn't throw an exception.
+         */
+        Thread.currentThread().countStackFrames();
+    }
+
+    /**
+     * java.lang.Thread#currentThread()
+     */
+    public void test_currentThread() {
+        assertNotNull(Thread.currentThread());
+    }
+
+    /**
+     * java.lang.Thread#destroy()
+     */
+    @SuppressWarnings("deprecation")
+    public void test_destroy() {
+        try {
+            new Thread().destroy();
+            // FIXME uncomment when IBM VME is updated
+            //fail("NoSuchMethodError was not thrown");
+        } catch (NoSuchMethodError e) {
+        }
+    }
+
+    /**
+     * java.lang.Thread#enumerate(java.lang.Thread[])
+     */
+    public void test_enumerate$Ljava_lang_Thread() {
+        // Test for method int java.lang.Thread.enumerate(java.lang.Thread [])
+        // The test has been updated according to HARMONY-1974 JIRA issue.
+
+        class MyThread extends Thread {
+            MyThread(ThreadGroup tg, String name) {
+                super(tg, name);
+            }
+
+            boolean failed = false;
+            String failMessage = null;
+
+            public void run() {
+                SimpleThread st1 = null;
+                SimpleThread st2 = null;
+                ThreadGroup mytg = null;
+                Thread firstOne = null;
+                Thread secondOne = null;
+                try {
+                    int arrayLength = 10;
+                    Thread[] tarray = new Thread[arrayLength];
+                    st1 = new SimpleThread(-1);
+                    st2 = new SimpleThread(-1);
+                    mytg = new ThreadGroup("jp");
+                    firstOne = new Thread(mytg, st1, "firstOne2");
+                    secondOne = new Thread(mytg, st2, "secondOne1");
+                    int count = Thread.enumerate(tarray);
+                    assertEquals("Incorrect value returned1",
+                            1, count);
+                    synchronized (st1) {
+                        firstOne.start();
+                        try {
+                            st1.wait();
+                        } catch (InterruptedException e) {
+                        }
+                    }
+                    count = Thread.enumerate(tarray);
+                    assertEquals("Incorrect value returned2",
+                            2, count);
+                    synchronized (st2) {
+                        secondOne.start();
+                        try {
+                            st2.wait();
+                        } catch (InterruptedException e) {
+                        }
+                    }
+                    count = Thread.enumerate(tarray);
+                    assertEquals("Incorrect value returned3",
+                            3, count);
+                } catch (junit.framework.AssertionFailedError e) {
+                    failed = true;
+                    failMessage = e.getMessage();
+                } finally {
+                    synchronized (st1) {
+                        firstOne.interrupt();
+                    }
+                    synchronized (st2) {
+                        secondOne.interrupt();
+                    }
+                    try {
+                        firstOne.join();
+                        secondOne.join();
+                    } catch (InterruptedException e) {
+                    }
+                    mytg.destroy();
+                }
+            }
+        }
+        ;
+
+        ThreadGroup tg = new ThreadGroup("tg");
+        MyThread t = new MyThread(tg, "top");
+        t.start();
+        try {
+            t.join();
+        } catch (InterruptedException e) {
+            fail("Unexpected interrupt");
+        } finally {
+            tg.destroy();
+        }
+        assertFalse(t.failMessage, t.failed);
+    }
+
+    /**
+     * java.lang.Thread#getContextClassLoader()
+     */
+    public void test_getContextClassLoader() {
+        // Test for method java.lang.ClassLoader
+        // java.lang.Thread.getContextClassLoader()
+        Thread t = new Thread();
+        assertTrue("Incorrect class loader returned",
+                t.getContextClassLoader() == Thread.currentThread()
+                        .getContextClassLoader());
+        t.start();
+
+    }
+
+    /**
+     * java.lang.Thread#getName()
+     */
+    public void test_getName() {
+        // Test for method java.lang.String java.lang.Thread.getName()
+        st = new Thread(new SimpleThread(1), "SimpleThread6");
+        assertEquals("Returned incorrect thread name",
+                "SimpleThread6", st.getName());
+        st.start();
+    }
+
+    /**
+     * java.lang.Thread#getPriority()
+     */
+    public void test_getPriority() {
+        // Test for method int java.lang.Thread.getPriority()
+        st = new Thread(new SimpleThread(1));
+        st.setPriority(Thread.MAX_PRIORITY);
+        assertTrue("Returned incorrect thread priority",
+                st.getPriority() == Thread.MAX_PRIORITY);
+        st.start();
+    }
+
+    /**
+     * java.lang.Thread#getThreadGroup()
+     */
+    public void test_getThreadGroup() {
+        // Test for method java.lang.ThreadGroup
+        // java.lang.Thread.getThreadGroup()
+        ThreadGroup tg = new ThreadGroup("Test Group4");
+        st = new Thread(tg, new SimpleThread(1), "SimpleThread8");
+        assertTrue("Returned incorrect thread group", st.getThreadGroup() == tg);
+        st.start();
+        try {
+            st.join();
+        } catch (InterruptedException e) {
+        }
+        assertNull("group should be null", st.getThreadGroup());
+        assertNotNull("toString() should not be null", st.toString());
+        tg.destroy();
+
+        final Object lock = new Object();
+        Thread t = new Thread() {
+            @Override
+            public void run() {
+                synchronized (lock) {
+                    lock.notifyAll();
+                }
+            }
+        };
+        synchronized (lock) {
+            t.start();
+            try {
+                lock.wait();
+            } catch (InterruptedException e) {
+            }
+        }
+        int running = 0;
+        while (t.isAlive())
+            running++;
+        ThreadGroup group = t.getThreadGroup();
+        assertNull("ThreadGroup is not null", group);
+    }
+
+    /**
+     * java.lang.Thread#interrupt()
+     */
+    public void test_interrupt() {
+        // Test for method void java.lang.Thread.interrupt()
+        final Object lock = new Object();
+        class ChildThread1 extends Thread {
+            Thread parent;
+
+            boolean sync;
+
+            @Override
+            public void run() {
+                if (sync) {
+                    synchronized (lock) {
+                        lock.notify();
+                        try {
+                            lock.wait();
+                        } catch (InterruptedException e) {
+                        }
+                    }
+                }
+                parent.interrupt();
+            }
+
+            public ChildThread1(Thread p, String name, boolean sync) {
+                super(name);
+                parent = p;
+                this.sync = sync;
+            }
+        }
+        boolean interrupted = false;
+        try {
+            ct = new ChildThread1(Thread.currentThread(), "Interrupt Test1",
+                    false);
+            synchronized (lock) {
+                ct.start();
+                lock.wait();
+            }
+        } catch (InterruptedException e) {
+            interrupted = true;
+        }
+        assertTrue("Failed to Interrupt thread1", interrupted);
+
+        interrupted = false;
+        try {
+            ct = new ChildThread1(Thread.currentThread(), "Interrupt Test2",
+                    true);
+            synchronized (lock) {
+                ct.start();
+                lock.wait();
+                lock.notify();
+            }
+            Thread.sleep(20000);
+        } catch (InterruptedException e) {
+            interrupted = true;
+        }
+        assertTrue("Failed to Interrupt thread2", interrupted);
+
+    }
+
+    /**
+     * java.lang.Thread#interrupted()
+     */
+    public void test_interrupted() {
+        assertFalse("Interrupted returned true for non-interrupted thread", Thread
+                .interrupted());
+        Thread.currentThread().interrupt();
+        assertTrue("Interrupted returned true for non-interrupted thread", Thread.interrupted());
+        assertFalse("Failed to clear interrupted flag", Thread.interrupted());
+    }
+
+    /**
+     * java.lang.Thread#isAlive()
+     */
+    public void test_isAlive() {
+        // Test for method boolean java.lang.Thread.isAlive()
+        SimpleThread simple;
+        st = new Thread(simple = new SimpleThread(500));
+        assertFalse("A thread that wasn't started is alive.", st.isAlive());
+        synchronized (simple) {
+            st.start();
+            try {
+                simple.wait();
+            } catch (InterruptedException e) {
+            }
+        }
+        assertTrue("Started thread returned false", st.isAlive());
+        try {
+            st.join();
+        } catch (InterruptedException e) {
+            fail("Thread did not die");
+        }
+        assertTrue("Stopped thread returned true", !st.isAlive());
+    }
+
+    /**
+     * java.lang.Thread#isDaemon()
+     */
+    public void test_isDaemon() {
+        // Test for method boolean java.lang.Thread.isDaemon()
+        st = new Thread(new SimpleThread(1), "SimpleThread10");
+        assertTrue("Non-Daemon thread returned true", !st.isDaemon());
+        st.setDaemon(true);
+        assertTrue("Daemon thread returned false", st.isDaemon());
+        st.start();
+    }
+
+    /**
+     * java.lang.Thread#isInterrupted()
+     */
+    public void test_isInterrupted() {
+        // Test for method boolean java.lang.Thread.isInterrupted()
+        class SpinThread implements Runnable {
+            public volatile boolean done = false;
+
+            public void run() {
+                while (!Thread.currentThread().isInterrupted())
+                    ;
+                while (!done)
+                    ;
+            }
+        }
+
+        SpinThread spin = new SpinThread();
+        spinner = new Thread(spin);
+        spinner.start();
+        Thread.yield();
+        try {
+            assertTrue("Non-Interrupted thread returned true", !spinner
+                    .isInterrupted());
+            spinner.interrupt();
+            assertTrue("Interrupted thread returned false", spinner
+                    .isInterrupted());
+            spin.done = true;
+        } finally {
+            spinner.interrupt();
+            spin.done = true;
+        }
+    }
+
+    /**
+     * java.lang.Thread#join()
+     */
+    public void test_join() {
+        // Test for method void java.lang.Thread.join()
+        SimpleThread simple;
+        try {
+            st = new Thread(simple = new SimpleThread(100));
+            // cause isAlive() to be compiled by the JIT, as it must be called
+            // within 100ms below.
+            assertTrue("Thread is alive", !st.isAlive());
+            synchronized (simple) {
+                st.start();
+                simple.wait();
+            }
+            st.join();
+        } catch (InterruptedException e) {
+            fail("Join failed ");
+        }
+        assertTrue("Joined thread is still alive", !st.isAlive());
+        boolean result = true;
+        Thread th = new Thread("test");
+        try {
+            th.join();
+        } catch (InterruptedException e) {
+            result = false;
+        }
+        assertTrue("Hung joining a non-started thread", result);
+        th.start();
+    }
+
+    /**
+     * java.lang.Thread#join(long)
+     */
+    public void test_joinJ() {
+        // Test for method void java.lang.Thread.join(long)
+        SimpleThread simple;
+        try {
+            st = new Thread(simple = new SimpleThread(1000), "SimpleThread12");
+            // cause isAlive() to be compiled by the JIT, as it must be called
+            // within 100ms below.
+            assertTrue("Thread is alive", !st.isAlive());
+            synchronized (simple) {
+                st.start();
+                simple.wait();
+            }
+            st.join(10);
+        } catch (InterruptedException e) {
+            fail("Join failed ");
+        }
+        assertTrue("Join failed to timeout", st.isAlive());
+
+        st.interrupt();
+        try {
+            st = new Thread(simple = new SimpleThread(100), "SimpleThread13");
+            synchronized (simple) {
+                st.start();
+                simple.wait();
+            }
+            st.join(1000);
+        } catch (InterruptedException e) {
+            fail("Join failed : " + e.getMessage());
+            return;
+        }
+        assertTrue("Joined thread is still alive", !st.isAlive());
+
+        final Object lock = new Object();
+        final Thread main = Thread.currentThread();
+        Thread killer = new Thread(new Runnable() {
+            public void run() {
+                try {
+                    synchronized (lock) {
+                        lock.notify();
+                    }
+                    Thread.sleep(100);
+                } catch (InterruptedException e) {
+                    return;
+                }
+                main.interrupt();
+            }
+        });
+        boolean result = true;
+        Thread th = new Thread("test");
+        try {
+            synchronized (lock) {
+                killer.start();
+                lock.wait();
+            }
+            th.join(200);
+        } catch (InterruptedException e) {
+            result = false;
+        }
+        killer.interrupt();
+        assertTrue("Hung joining a non-started thread", result);
+        th.start();
+    }
+
+    /**
+     * java.lang.Thread#join(long, int)
+     */
+    public void test_joinJI() throws Exception {
+        // Test for method void java.lang.Thread.join(long, int)
+        SimpleThread simple;
+        st = new Thread(simple = new SimpleThread(1000), "Squawk1");
+        assertTrue("Thread is alive", !st.isAlive());
+        synchronized (simple) {
+            st.start();
+            simple.wait();
+        }
+
+        long firstRead = System.currentTimeMillis();
+        st.join(100, 999999);
+        long secondRead = System.currentTimeMillis();
+        assertTrue("Did not join by appropriate time: " + secondRead + "-"
+                + firstRead + "=" + (secondRead - firstRead), secondRead
+                - firstRead <= 300);
+        assertTrue("Joined thread is not alive", st.isAlive());
+        st.interrupt();
+
+        final Object lock = new Object();
+        final Thread main = Thread.currentThread();
+        Thread killer = new Thread(new Runnable() {
+            public void run() {
+                try {
+                    synchronized (lock) {
+                        lock.notify();
+                    }
+                    Thread.sleep(100);
+                } catch (InterruptedException e) {
+                    return;
+                }
+                main.interrupt();
+            }
+        });
+        boolean result = true;
+        Thread th = new Thread("test");
+        try {
+            synchronized (lock) {
+                killer.start();
+                lock.wait();
+            }
+            th.join(200, 20);
+        } catch (InterruptedException e) {
+            result = false;
+        }
+        killer.interrupt();
+        assertTrue("Hung joining a non-started thread", result);
+        th.start();
+    }
+
+    /**
+     * java.lang.Thread#run()
+     */
+    public void test_run() {
+        // Test for method void java.lang.Thread.run()
+        class RunThread implements Runnable {
+            boolean didThreadRun = false;
+
+            public void run() {
+                didThreadRun = true;
+            }
+        }
+        RunThread rt = new RunThread();
+        Thread t = new Thread(rt);
+        try {
+            t.start();
+            int count = 0;
+            while (!rt.didThreadRun && count < 20) {
+                Thread.sleep(100);
+                count++;
+            }
+            assertTrue("Thread did not run", rt.didThreadRun);
+            t.join();
+        } catch (InterruptedException e) {
+            assertTrue("Joined thread was interrupted", true);
+        }
+        assertTrue("Joined thread is still alive", !t.isAlive());
+    }
+
+    /**
+     * java.lang.Thread#setDaemon(boolean)
+     */
+    public void test_setDaemonZ() {
+        // Test for method void java.lang.Thread.setDaemon(boolean)
+        st = new Thread(new SimpleThread(1), "SimpleThread14");
+        st.setDaemon(true);
+        assertTrue("Failed to set thread as daemon thread", st.isDaemon());
+        st.start();
+    }
+
+    /**
+     * java.lang.Thread#setName(java.lang.String)
+     */
+    public void test_setNameLjava_lang_String() {
+        // Test for method void java.lang.Thread.setName(java.lang.String)
+        st = new Thread(new SimpleThread(1), "SimpleThread15");
+        st.setName("Bogus Name");
+        assertEquals("Failed to set thread name",
+                "Bogus Name", st.getName());
+        try {
+            st.setName(null);
+            fail("Null should not be accepted as a valid name");
+        } catch (NullPointerException e) {
+            // success
+            assertTrue("Null should not be accepted as a valid name", true);
+        }
+        st.start();
+    }
+
+    /**
+     * java.lang.Thread#setPriority(int)
+     */
+    public void test_setPriorityI() {
+        // Test for method void java.lang.Thread.setPriority(int)
+        st = new Thread(new SimpleThread(1));
+        st.setPriority(Thread.MAX_PRIORITY);
+        assertTrue("Failed to set priority",
+                st.getPriority() == Thread.MAX_PRIORITY);
+        st.start();
+    }
+
+    /**
+     * java.lang.Thread#sleep(long)
+     */
+    public void test_sleepJ() {
+        // Test for method void java.lang.Thread.sleep(long)
+
+        // TODO : Test needs enhancing.
+        long stime = 0, ftime = 0;
+        try {
+            stime = System.currentTimeMillis();
+            Thread.sleep(1000);
+            ftime = System.currentTimeMillis();
+        } catch (InterruptedException e) {
+            fail("Unexpected interrupt received");
+        }
+        assertTrue("Failed to sleep long enough", (ftime - stime) >= 800);
+    }
+
+    /**
+     * java.lang.Thread#sleep(long, int)
+     */
+    public void test_sleepJI() {
+        // Test for method void java.lang.Thread.sleep(long, int)
+
+        // TODO : Test needs revisiting.
+        long stime = 0, ftime = 0;
+        try {
+            stime = System.currentTimeMillis();
+            Thread.sleep(1000, 999999);
+            ftime = System.currentTimeMillis();
+        } catch (InterruptedException e) {
+            fail("Unexpected interrupt received");
+        }
+        long result = ftime - stime;
+        assertTrue("Failed to sleep long enough: " + result, result >= 900
+                && result <= 1100);
+    }
+
+    /**
+     * java.lang.Thread#start()
+     */
+    public void test_start() {
+        // Test for method void java.lang.Thread.start()
+        try {
+            ResSupThread t = new ResSupThread(Thread.currentThread());
+            synchronized (t) {
+                ct = new Thread(t, "Interrupt Test4");
+                ct.start();
+                t.wait();
+            }
+            assertTrue("Thread is not running1", ct.isAlive());
+            // Let the child thread get going.
+            int orgval = t.getCheckVal();
+            Thread.sleep(150);
+            assertTrue("Thread is not running2", orgval != t.getCheckVal());
+            ct.interrupt();
+        } catch (InterruptedException e) {
+            fail("Unexpected interrupt occurred");
+        }
+    }
+
+    /**
+     * java.lang.Thread#toString()
+     */
+    public void test_toString() {
+        // Test for method java.lang.String java.lang.Thread.toString()
+        ThreadGroup tg = new ThreadGroup("Test Group5");
+        st = new Thread(tg, new SimpleThread(1), "SimpleThread17");
+        final String stString = st.toString();
+        final String expected = "Thread[SimpleThread17,5,Test Group5]";
+        assertTrue("Returned incorrect string: " + stString + "\t(expecting :"
+                + expected + ")", stString.equals(expected));
+        st.start();
+        try {
+            st.join();
+        } catch (InterruptedException e) {
+        }
+        tg.destroy();
+    }
+
+    /**
+     * java.lang.Thread#getAllStackTraces()
+     */
+    public void test_getAllStackTraces() {
+        Map<Thread, StackTraceElement[]> stMap = Thread.getAllStackTraces();
+        assertNotNull(stMap);
+        //TODO add security-based tests
+    }
+
+    /**
+     * java.lang.Thread#getDefaultUncaughtExceptionHandler
+     * java.lang.Thread#setDefaultUncaughtExceptionHandler
+     */
+    public void test_get_setDefaultUncaughtExceptionHandler() {
+        class Handler implements UncaughtExceptionHandler {
+            public void uncaughtException(Thread thread, Throwable ex) {
+            }
+        }
+
+        final Handler handler = new Handler();
+        Thread.setDefaultUncaughtExceptionHandler(handler);
+        assertSame(handler, Thread.getDefaultUncaughtExceptionHandler());
+
+        Thread.setDefaultUncaughtExceptionHandler(null);
+        assertNull(Thread.getDefaultUncaughtExceptionHandler());
+        //TODO add security-based tests
+    }
+
+    /**
+     * java.lang.Thread#getStackTrace()
+     */
+    public void test_getStackTrace() {
+        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
+
+        assertNotNull(stackTrace);
+
+        stack_trace_loop:
+        {
+            for (int i = 0; i < stackTrace.length; i++) {
+                StackTraceElement e = stackTrace[i];
+                if (getClass().getName().equals(e.getClassName())) {
+                    if ("test_getStackTrace".equals(e.getMethodName())) {
+                        break stack_trace_loop;
+                    }
+                }
+            }
+            fail("class and method not found in stack trace");
+        }
+
+        //TODO add security-based tests
+    }
+
+    /**
+     * java.lang.Thread#getState()
+     */
+    public void test_getState() {
+        Thread.State state = Thread.currentThread().getState();
+        assertNotNull(state);
+        assertEquals(Thread.State.RUNNABLE, state);
+        //TODO add additional state tests
+    }
+
+    /**
+     * java.lang.Thread#getUncaughtExceptionHandler
+     * java.lang.Thread#setUncaughtExceptionHandler
+     */
+    public void test_get_setUncaughtExceptionHandler() {
+        class Handler implements UncaughtExceptionHandler {
+            public void uncaughtException(Thread thread, Throwable ex) {
+            }
+        }
+
+        final Handler handler = new Handler();
+        Thread.currentThread().setUncaughtExceptionHandler(handler);
+        assertSame(handler, Thread.currentThread().getUncaughtExceptionHandler());
+
+        Thread.currentThread().setUncaughtExceptionHandler(null);
+
+        //TODO add security-based tests
+    }
+
+    /**
+     * java.lang.Thread#getId()
+     */
+    public void test_getId() {
+        assertTrue("current thread's ID is not positive", Thread.currentThread().getId() > 0);
+
+        //check all the current threads for positive IDs
+        Map<Thread, StackTraceElement[]> stMap = Thread.getAllStackTraces();
+        for (Thread thread : stMap.keySet()) {
+            assertTrue("thread's ID is not positive: " + thread.getName(), thread.getId() > 0);
+        }
+    }
+
+
+    @Override
+    protected void tearDown() {
+        try {
+            if (st != null)
+                st.interrupt();
+        } catch (Exception e) {
+        }
+        try {
+            if (spinner != null)
+                spinner.interrupt();
+        } catch (Exception e) {
+        }
+        try {
+            if (ct != null)
+                ct.interrupt();
+        } catch (Exception e) {
+        }
+
+        try {
+            spinner = null;
+            st = null;
+            ct = null;
+            System.runFinalization();
+        } catch (Exception e) {
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/ThrowableTest.java b/luni/src/test/java/tests/api/java/lang/ThrowableTest.java
new file mode 100644
index 0000000..0a7f02d
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/ThrowableTest.java
@@ -0,0 +1,183 @@
+/*
+ *  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.lang;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+import junit.framework.TestCase;
+
+public class ThrowableTest extends TestCase {
+
+    /**
+     * java.lang.Throwable#Throwable()
+     */
+    public void test_Constructor() {
+        Throwable e = new Throwable();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.Throwable#Throwable(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        Throwable e = new Throwable("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.Throwable#fillInStackTrace()
+     */
+    public void test_fillInStackTrace() {
+        // Test for method java.lang.Throwable
+        // java.lang.Throwable.fillInStackTrace()
+        class Test implements Runnable {
+            public int x;
+
+            public Test(int x) {
+                this.x = x;
+            }
+
+            public void anotherMethod() {
+                if (true)
+                    throw new IndexOutOfBoundsException();
+            }
+
+            public void run() {
+                if (x == 0)
+                    throw new IndexOutOfBoundsException();
+                try {
+                    anotherMethod();
+                } catch (IndexOutOfBoundsException e) {
+                    e.fillInStackTrace();
+                    throw e;
+                }
+            }
+        }
+        ByteArrayOutputStream bao = new ByteArrayOutputStream();
+        PrintStream ps = new PrintStream(bao);
+        try {
+            new Test(0).run();
+        } catch (Throwable e) {
+            e.printStackTrace(ps);
+        }
+        ps.flush();
+        String s = fixStacktrace(new String(bao.toByteArray(), 0, bao.size()));
+
+        bao.reset();
+        try {
+            new Test(1).run();
+        } catch (Throwable e) {
+            e.printStackTrace(ps);
+        }
+        ps.close();
+        String s2 = fixStacktrace(new String(bao.toByteArray(), 0, bao.size()));
+        assertTrue("Invalid stackTrace? length: " + s2.length() + "\n" + s2, s2
+                .length() > 300);
+        assertTrue("Incorrect stackTrace printed: \n" + s2
+                + "\n\nCompared with:\n" + s, s2.equals(s));
+    }
+
+    private String fixStacktrace(String trace) {
+        // remove linenumbers
+        StringBuffer sb = new StringBuffer();
+        int lastIndex = 0;
+        while (lastIndex < trace.length()) {
+            int index = trace.indexOf('\n', lastIndex);
+            if (index == -1)
+                index = trace.length();
+            String line = trace.substring(lastIndex, index);
+            lastIndex = index + 1;
+
+            index = line.indexOf("(");
+            if (index > -1) {
+                line = line.substring(0, index);
+            }
+            // Usually the construction of the exception is removed
+            // however if running with the JIT, it may not be removed
+            if (line.indexOf("java.lang.Throwable") > -1)
+                continue;
+            sb.append(line);
+            sb.append('\n');
+        }
+        return sb.toString();
+    }
+
+    /**
+     * java.lang.Throwable#printStackTrace()
+     */
+    public void test_printStackTrace() {
+        // Test for method void java.lang.Throwable.printStackTrace()
+        Throwable x = new ClassNotFoundException("A Test Message");
+        ByteArrayOutputStream bao = new ByteArrayOutputStream();
+        PrintStream ps = new PrintStream(bao);
+        PrintStream err = System.err;
+        System.setErr(ps);
+        x.printStackTrace();
+        System.setErr(err);
+        ps.close();
+        String s = new String(bao.toByteArray(), 0, bao.size());
+        assertTrue("Incorrect stackTrace printed:\n" + s, s != null
+                && s.length() > 400);
+    }
+
+    /**
+     * java.lang.Throwable#printStackTrace(java.io.PrintStream)
+     */
+    public void test_printStackTraceLjava_io_PrintStream() {
+        // Test for method void
+        // java.lang.Throwable.printStackTrace(java.io.PrintStream)
+        ByteArrayOutputStream bao = new ByteArrayOutputStream();
+        PrintStream ps = new PrintStream(bao);
+        Throwable x = new java.net.UnknownHostException("A Message");
+        x.printStackTrace(ps);
+        ps.close();
+        String s = new String(bao.toByteArray(), 0, bao.size());
+        assertTrue("Incorrect stackTrace printed:\n" + s, s != null
+                && s.length() > 400);
+    }
+
+    /**
+     * java.lang.Throwable#printStackTrace(java.io.PrintWriter)
+     */
+    public void test_printStackTraceLjava_io_PrintWriter() {
+        // Test for method void
+        // java.lang.Throwable.printStackTrace(java.io.PrintWriter)
+        // SM
+        ByteArrayOutputStream bao = new ByteArrayOutputStream();
+        PrintWriter pw = new PrintWriter(bao);
+        Throwable x = new java.net.UnknownHostException("A Message");
+        x.printStackTrace(pw);
+        pw.close();
+        String s = new String(bao.toByteArray(), 0, bao.size());
+        assertTrue("Incorrect stackTrace printed:\n" + s, s != null
+                && s.length() > 400);
+    }
+
+    /**
+     * java.lang.Throwable#toString()
+     */
+    public void test_toString() {
+        Throwable e = new Throwable("Throw");
+        assertEquals("java.lang.Throwable: Throw", e.toString());
+
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/TypeNotPresentExceptionTest.java b/luni/src/test/java/tests/api/java/lang/TypeNotPresentExceptionTest.java
new file mode 100644
index 0000000..4b93ab6
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/TypeNotPresentExceptionTest.java
@@ -0,0 +1,54 @@
+/* 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.lang;
+
+import junit.framework.TestCase;
+
+public class TypeNotPresentExceptionTest extends TestCase {
+
+    /**
+     * java.lang.TypeNotPresentException.TypeNotPresentException(String, Throwable)
+     */
+    public void test_constructorLjava_lang_StringLjava_lang_Throwable() {
+        TypeNotPresentException e = new TypeNotPresentException(null, null);
+        assertNotNull(e);
+        String m = e.getMessage();
+        assertNotNull(m);
+
+        e = new TypeNotPresentException(getClass().getName(), null);
+        assertNotNull(e);
+        m = e.getMessage();
+        assertNotNull(m);
+
+        NullPointerException npe = new NullPointerException();
+        e = new TypeNotPresentException(getClass().getName(), npe);
+        assertNotNull(e.getMessage());
+        assertSame(npe, e.getCause());
+    }
+
+    /**
+     * java.lang.TypeNotPresentException.typeName()
+     */
+    public void test_typeName() {
+        TypeNotPresentException e = new TypeNotPresentException(null, null);
+        assertNull(e.typeName());
+
+        e = new TypeNotPresentException(getClass().getName(), null);
+        assertEquals(getClass().getName(), e.typeName());
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/lang/UnknownErrorTest.java b/luni/src/test/java/tests/api/java/lang/UnknownErrorTest.java
new file mode 100644
index 0000000..b6e3406
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/UnknownErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class UnknownErrorTest extends TestCase {
+
+    /**
+     * java.lang.UnknownError#UnknownError()
+     */
+    public void test_Constructor() {
+        UnknownError e = new UnknownError();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.UnknownError#UnknownError(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        UnknownError e = new UnknownError("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/UnsatisfiedLinkErrorTest.java b/luni/src/test/java/tests/api/java/lang/UnsatisfiedLinkErrorTest.java
new file mode 100644
index 0000000..c3e2c9b
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/UnsatisfiedLinkErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class UnsatisfiedLinkErrorTest extends TestCase {
+
+    /**
+     * java.lang.UnsatisfiedLinkError#UnsatisfiedLinkError()
+     */
+    public void test_Constructor() {
+        UnsatisfiedLinkError e = new UnsatisfiedLinkError();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.UnsatisfiedLinkError#UnsatisfiedLinkError(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        UnsatisfiedLinkError e = new UnsatisfiedLinkError("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/UnsupportedClassVersionErrorTest.java b/luni/src/test/java/tests/api/java/lang/UnsupportedClassVersionErrorTest.java
new file mode 100644
index 0000000..1b606ba
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/UnsupportedClassVersionErrorTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.lang;
+
+import junit.framework.TestCase;
+
+public class UnsupportedClassVersionErrorTest extends TestCase {
+    /**
+     * 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.
+     */
+
+    /**
+     * java.lang.UnsupportedClassVersionError#UnsupportedClassVersionError()
+     */
+    public void test_UnsupportedClassVersionError() {
+        UnsupportedClassVersionError error = new UnsupportedClassVersionError();
+        assertNotNull(error);
+        assertNull(error.getMessage());
+    }
+
+    /**
+     * 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/tests/api/java/lang/UnsupportedOperationExceptionTest.java b/luni/src/test/java/tests/api/java/lang/UnsupportedOperationExceptionTest.java
new file mode 100644
index 0000000..6d52e7f
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/UnsupportedOperationExceptionTest.java
@@ -0,0 +1,100 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class UnsupportedOperationExceptionTest extends TestCase {
+
+    /**
+     * java.lang.UnsupportedOperationException#UnsupportedOperationException()
+     */
+    public void test_Constructor() {
+        UnsupportedOperationException e = new UnsupportedOperationException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.UnsupportedOperationException#UnsupportedOperationException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        UnsupportedOperationException e = new UnsupportedOperationException("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * {@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());
+    }
+
+    /**
+     * {@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());
+    }
+
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        SerializationTest.verifySelf(new UnsupportedOperationException());
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        SerializationTest.verifyGolden(this,
+                new UnsupportedOperationException());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/VerifyErrorTest.java b/luni/src/test/java/tests/api/java/lang/VerifyErrorTest.java
new file mode 100644
index 0000000..9de5e19
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/VerifyErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+public class VerifyErrorTest extends TestCase {
+
+    /**
+     * java.lang.VerifyError#VerifyError()
+     */
+    public void test_Constructor() {
+        VerifyError e = new VerifyError();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.VerifyError#VerifyError(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        VerifyError e = new VerifyError("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/VirtualMachineErrorTest.java b/luni/src/test/java/tests/api/java/lang/VirtualMachineErrorTest.java
new file mode 100644
index 0000000..a49e481
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/VirtualMachineErrorTest.java
@@ -0,0 +1,45 @@
+/*
+ *  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.lang;
+
+import junit.framework.TestCase;
+
+@SuppressWarnings("serial")
+public class VirtualMachineErrorTest extends TestCase {
+
+    /**
+     * java.lang.VirtualMachineError#VirtualMachineError()
+     */
+    public void test_Constructor() {
+        VirtualMachineError e = new VirtualMachineError() {
+        };
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * java.lang.VirtualMachineError#VirtualMachineError(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        VirtualMachineError e = new VirtualMachineError("fixture") {
+        };
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/MalformedParameterizedTypeExceptionTest.java b/luni/src/test/java/tests/api/java/lang/reflect/MalformedParameterizedTypeExceptionTest.java
new file mode 100644
index 0000000..91342dc
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/reflect/MalformedParameterizedTypeExceptionTest.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 tests.api.java.lang.reflect;
+
+import java.lang.reflect.MalformedParameterizedTypeException;
+import junit.framework.TestCase;
+
+public class MalformedParameterizedTypeExceptionTest extends TestCase {
+
+    /**
+     * java.lang.reflect.MalformedParameterizedTypeException#
+     * MalformedParameterizedTypeException()
+     */
+    public void testMalformedParameterizedTypeException() {
+        MalformedParameterizedTypeException e = new MalformedParameterizedTypeException();
+        assertNotNull(e);
+        assertNull(e.getMessage());
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/ModifierTest.java b/luni/src/test/java/tests/api/java/lang/reflect/ModifierTest.java
new file mode 100644
index 0000000..6e844f6
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/reflect/ModifierTest.java
@@ -0,0 +1,435 @@
+/*
+ *  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.lang.reflect;
+
+import java.lang.reflect.Modifier;
+
+public class ModifierTest extends junit.framework.TestCase {
+
+    private static final int ALL_FLAGS = 0x7FF;
+
+    /**
+     * java.lang.reflect.Modifier#Modifier()
+     */
+    public void test_Constructor() {
+        // Test for method java.lang.reflect.Modifier()
+        new Modifier();
+    }
+
+    /**
+     * java.lang.reflect.Modifier#isAbstract(int)
+     */
+    public void test_isAbstractI() {
+        // Test for method boolean java.lang.reflect.Modifier.isAbstract(int)
+        assertTrue("ABSTRACT returned false", Modifier.isAbstract(ALL_FLAGS));
+        assertTrue("ABSTRACT returned false", Modifier
+                .isAbstract(Modifier.ABSTRACT));
+        assertTrue("Non-ABSTRACT returned true", !Modifier
+                .isAbstract(Modifier.TRANSIENT));
+    }
+
+    /**
+     * java.lang.reflect.Modifier#isFinal(int)
+     */
+    public void test_isFinalI() {
+        // Test for method boolean java.lang.reflect.Modifier.isFinal(int)
+        assertTrue("FINAL returned false", Modifier.isFinal(ALL_FLAGS));
+        assertTrue("FINAL returned false", Modifier.isFinal(Modifier.FINAL));
+        assertTrue("Non-FINAL returned true", !Modifier
+                .isFinal(Modifier.TRANSIENT));
+    }
+
+    /**
+     * java.lang.reflect.Modifier#isInterface(int)
+     */
+    public void test_isInterfaceI() {
+        // Test for method boolean java.lang.reflect.Modifier.isInterface(int)
+        assertTrue("INTERFACE returned false", Modifier.isInterface(ALL_FLAGS));
+        assertTrue("INTERFACE returned false", Modifier
+                .isInterface(Modifier.INTERFACE));
+        assertTrue("Non-INTERFACE returned true", !Modifier
+                .isInterface(Modifier.TRANSIENT));
+    }
+
+    /**
+     * java.lang.reflect.Modifier#isNative(int)
+     */
+    public void test_isNativeI() {
+        // Test for method boolean java.lang.reflect.Modifier.isNative(int)
+        assertTrue("NATIVE returned false", Modifier.isNative(ALL_FLAGS));
+        assertTrue("NATIVE returned false", Modifier.isNative(Modifier.NATIVE));
+        assertTrue("Non-NATIVE returned true", !Modifier
+                .isNative(Modifier.TRANSIENT));
+    }
+
+    /**
+     * java.lang.reflect.Modifier#isPrivate(int)
+     */
+    public void test_isPrivateI() {
+        // Test for method boolean java.lang.reflect.Modifier.isPrivate(int)
+        assertTrue("PRIVATE returned false", Modifier.isPrivate(ALL_FLAGS));
+        assertTrue("PRIVATE returned false", Modifier
+                .isPrivate(Modifier.PRIVATE));
+        assertTrue("Non-PRIVATE returned true", !Modifier
+                .isPrivate(Modifier.TRANSIENT));
+    }
+
+    /**
+     * java.lang.reflect.Modifier#isProtected(int)
+     */
+    public void test_isProtectedI() {
+        // Test for method boolean java.lang.reflect.Modifier.isProtected(int)
+        assertTrue("PROTECTED returned false", Modifier.isProtected(ALL_FLAGS));
+        assertTrue("PROTECTED returned false", Modifier
+                .isProtected(Modifier.PROTECTED));
+        assertTrue("Non-PROTECTED returned true", !Modifier
+                .isProtected(Modifier.TRANSIENT));
+    }
+
+    /**
+     * java.lang.reflect.Modifier#isPublic(int)
+     */
+    public void test_isPublicI() {
+        // Test for method boolean java.lang.reflect.Modifier.isPublic(int)
+        assertTrue("PUBLIC returned false", Modifier.isPublic(ALL_FLAGS));
+        assertTrue("PUBLIC returned false", Modifier.isPublic(Modifier.PUBLIC));
+        assertTrue("Non-PUBLIC returned true", !Modifier
+                .isPublic(Modifier.TRANSIENT));
+    }
+
+    /**
+     * java.lang.reflect.Modifier#isStatic(int)
+     */
+    public void test_isStaticI() {
+        // Test for method boolean java.lang.reflect.Modifier.isStatic(int)
+        assertTrue("STATIC returned false", Modifier.isStatic(ALL_FLAGS));
+        assertTrue("STATIC returned false", Modifier.isStatic(Modifier.STATIC));
+        assertTrue("Non-STATIC returned true", !Modifier
+                .isStatic(Modifier.TRANSIENT));
+    }
+
+    /**
+     * java.lang.reflect.Modifier#isStrict(int)
+     */
+    public void test_isStrictI() {
+        // Test for method boolean java.lang.reflect.Modifier.isStrict(int)
+        assertTrue("STRICT returned false", Modifier.isStrict(Modifier.STRICT));
+        assertTrue("Non-STRICT returned true", !Modifier
+                .isStrict(Modifier.TRANSIENT));
+    }
+
+    /**
+     * java.lang.reflect.Modifier#isSynchronized(int)
+     */
+    public void test_isSynchronizedI() {
+        // Test for method boolean
+        // java.lang.reflect.Modifier.isSynchronized(int)
+        assertTrue("Synchronized returned false", Modifier
+                .isSynchronized(ALL_FLAGS));
+        assertTrue("Non-Synchronized returned true", !Modifier
+                .isSynchronized(Modifier.VOLATILE));
+    }
+
+    /**
+     * java.lang.reflect.Modifier#isTransient(int)
+     */
+    public void test_isTransientI() {
+        // Test for method boolean java.lang.reflect.Modifier.isTransient(int)
+        assertTrue("Transient returned false", Modifier.isTransient(ALL_FLAGS));
+        assertTrue("Transient returned false", Modifier
+                .isTransient(Modifier.TRANSIENT));
+        assertTrue("Non-Transient returned true", !Modifier
+                .isTransient(Modifier.VOLATILE));
+    }
+
+    /**
+     * java.lang.reflect.Modifier#isVolatile(int)
+     */
+    public void test_isVolatileI() {
+        // Test for method boolean java.lang.reflect.Modifier.isVolatile(int)
+        assertTrue("Volatile returned false", Modifier.isVolatile(ALL_FLAGS));
+        assertTrue("Volatile returned false", Modifier
+                .isVolatile(Modifier.VOLATILE));
+        assertTrue("Non-Volatile returned true", !Modifier
+                .isVolatile(Modifier.TRANSIENT));
+    }
+
+    /**
+     * java.lang.reflect.Modifier#toString(int)
+     */
+    public void test_toStringI() {
+        // Test for method java.lang.String
+        // java.lang.reflect.Modifier.toString(int)
+        assertTrue("Returned incorrect string value: "
+                + Modifier.toString(java.lang.reflect.Modifier.PUBLIC
+                + java.lang.reflect.Modifier.ABSTRACT), Modifier
+                .toString(
+                        java.lang.reflect.Modifier.PUBLIC
+                                + java.lang.reflect.Modifier.ABSTRACT).equals(
+                        "public abstract"));
+
+        int i = 0xFFF;
+        String modification = "public protected private abstract static final transient "
+                + "volatile synchronized native strictfp interface";
+        assertTrue("Returned incorrect string value", Modifier.toString(i)
+                .equals(modification));
+    }
+
+    public void test_Constants_Value() {
+        assertEquals(1024, Modifier.ABSTRACT);
+        assertEquals(16, Modifier.FINAL);
+        assertEquals(512, Modifier.INTERFACE);
+        assertEquals(256, Modifier.NATIVE);
+        assertEquals(2, Modifier.PRIVATE);
+        assertEquals(4, Modifier.PROTECTED);
+        assertEquals(1, Modifier.PUBLIC);
+        assertEquals(8, Modifier.STATIC);
+        assertEquals(2048, Modifier.STRICT);
+        assertEquals(32, Modifier.SYNCHRONIZED);
+        assertEquals(128, Modifier.TRANSIENT);
+        assertEquals(64, Modifier.VOLATILE);
+    }
+
+    abstract class AbstractClazz {
+    }
+
+    final class FinalClazz {
+    }
+
+    static class StaticClazz {
+    }
+
+    interface InterfaceClazz {
+    }
+
+    public class PublicClazz {
+    }
+
+    protected class ProtectedClazz {
+    }
+
+    private class PrivateClazz {
+    }
+
+    public abstract class PublicAbstractClazz {
+    }
+
+    protected abstract class ProtectedAbstractClazz {
+    }
+
+    private abstract class PrivateAbstractClazz {
+    }
+
+    public final class PublicFinalClazz {
+    }
+
+    protected final class ProtectedFinalClazz {
+    }
+
+    private final class PrivateFinalClazz {
+    }
+
+    public static class PublicStaticClazz {
+    }
+
+    protected static class ProtectedStaticClazz {
+    }
+
+    private static class PrivateStaticClazz {
+    }
+
+    public interface PublicInterface {
+    }
+
+    protected interface ProtectedInterface {
+    }
+
+    private interface PrivateInterface {
+    }
+
+    static abstract class StaticAbstractClazz {
+    }
+
+    public static abstract class PublicStaticAbstractClazz {
+    }
+
+    protected static abstract class ProtectedStaticAbstractClazz {
+    }
+
+    private static abstract class PrivateStaticAbstractClazz {
+    }
+
+    static final class StaticFinalClazz {
+    }
+
+    public static final class PublicStaticFinalClazz {
+    }
+
+    protected static final class ProtectedStaticFinalClazz {
+    }
+
+    private static final class PrivateStaticFinalClazz {
+    }
+
+    static interface StaticInterface {
+    }
+
+    public static interface PublicStaticInterface {
+    }
+
+    protected static interface ProtectedStaticInterface {
+    }
+
+    private static interface PrivateStaticInterface {
+    }
+
+    static abstract interface StaticAbstractInterface {
+    }
+
+    public static abstract interface PublicStaticAbstractInterface {
+    }
+
+    protected static abstract interface ProtectedStaticAbstractInterface {
+    }
+
+    private static abstract interface PrivateStaticAbstractInterface {
+    }
+
+    public void test_Class_Modifier() {
+        assertEquals(Modifier.ABSTRACT, AbstractClazz.class.getModifiers());
+        assertEquals(Modifier.FINAL, FinalClazz.class.getModifiers());
+        assertEquals(Modifier.STATIC, StaticClazz.class.getModifiers());
+        assertEquals(Modifier.INTERFACE + Modifier.STATIC + Modifier.ABSTRACT,
+                InterfaceClazz.class.getModifiers());
+
+        assertEquals(Modifier.PUBLIC, PublicClazz.class.getModifiers());
+        assertEquals(Modifier.PROTECTED, ProtectedClazz.class.getModifiers());
+        assertEquals(Modifier.PRIVATE, PrivateClazz.class.getModifiers());
+
+        assertEquals(Modifier.PUBLIC + Modifier.ABSTRACT,
+                PublicAbstractClazz.class.getModifiers());
+        assertEquals(Modifier.PROTECTED + Modifier.ABSTRACT,
+                ProtectedAbstractClazz.class.getModifiers());
+        assertEquals(Modifier.PRIVATE + Modifier.ABSTRACT,
+                PrivateAbstractClazz.class.getModifiers());
+
+        assertEquals(Modifier.PUBLIC + Modifier.FINAL, PublicFinalClazz.class
+                .getModifiers());
+        assertEquals(Modifier.PROTECTED + Modifier.FINAL,
+                ProtectedFinalClazz.class.getModifiers());
+        assertEquals(Modifier.PRIVATE + Modifier.FINAL, PrivateFinalClazz.class
+                .getModifiers());
+
+        assertEquals(Modifier.PUBLIC + Modifier.STATIC, PublicStaticClazz.class
+                .getModifiers());
+        assertEquals(Modifier.PROTECTED + Modifier.STATIC,
+                ProtectedStaticClazz.class.getModifiers());
+        assertEquals(Modifier.PRIVATE + Modifier.STATIC,
+                PrivateStaticClazz.class.getModifiers());
+
+        assertEquals(Modifier.PUBLIC + Modifier.INTERFACE + Modifier.STATIC
+                + Modifier.ABSTRACT, PublicInterface.class.getModifiers());
+        assertEquals(Modifier.STATIC + Modifier.FINAL, StaticFinalClazz.class
+                .getModifiers());
+        assertEquals(Modifier.PRIVATE + Modifier.INTERFACE + Modifier.STATIC
+                + Modifier.ABSTRACT, PrivateInterface.class.getModifiers());
+
+        assertEquals(Modifier.STATIC + Modifier.ABSTRACT,
+                StaticAbstractClazz.class.getModifiers());
+        assertEquals(Modifier.PUBLIC + Modifier.STATIC + Modifier.ABSTRACT,
+                PublicStaticAbstractClazz.class.getModifiers());
+        assertEquals(Modifier.PROTECTED + Modifier.STATIC + Modifier.ABSTRACT,
+                ProtectedStaticAbstractClazz.class.getModifiers());
+        assertEquals(Modifier.PRIVATE + Modifier.STATIC + Modifier.ABSTRACT,
+                PrivateStaticAbstractClazz.class.getModifiers());
+
+        assertEquals(Modifier.STATIC + Modifier.FINAL, StaticFinalClazz.class
+                .getModifiers());
+        assertEquals(Modifier.PUBLIC + Modifier.STATIC + Modifier.FINAL,
+                PublicStaticFinalClazz.class.getModifiers());
+        assertEquals(Modifier.PROTECTED + Modifier.STATIC + Modifier.FINAL,
+                ProtectedStaticFinalClazz.class.getModifiers());
+        assertEquals(Modifier.PRIVATE + Modifier.STATIC + Modifier.FINAL,
+                PrivateStaticFinalClazz.class.getModifiers());
+
+        assertEquals(Modifier.INTERFACE + Modifier.STATIC + Modifier.ABSTRACT,
+                StaticInterface.class.getModifiers());
+        assertEquals(Modifier.PUBLIC + Modifier.INTERFACE + Modifier.STATIC
+                + Modifier.ABSTRACT, PublicStaticInterface.class.getModifiers());
+        assertEquals(Modifier.PROTECTED + Modifier.INTERFACE + Modifier.STATIC
+                + Modifier.ABSTRACT, ProtectedStaticInterface.class
+                .getModifiers());
+        assertEquals(Modifier.PRIVATE + Modifier.INTERFACE + Modifier.STATIC
+                + Modifier.ABSTRACT, PrivateStaticInterface.class
+                .getModifiers());
+
+        assertEquals(Modifier.INTERFACE + Modifier.STATIC + Modifier.ABSTRACT,
+                StaticAbstractInterface.class.getModifiers());
+        assertEquals(Modifier.PUBLIC + Modifier.INTERFACE + Modifier.STATIC
+                + Modifier.ABSTRACT, PublicStaticAbstractInterface.class
+                .getModifiers());
+        assertEquals(Modifier.PROTECTED + Modifier.INTERFACE + Modifier.STATIC
+                + Modifier.ABSTRACT, ProtectedStaticAbstractInterface.class
+                .getModifiers());
+        assertEquals(Modifier.PRIVATE + Modifier.INTERFACE + Modifier.STATIC
+                + Modifier.ABSTRACT, PrivateStaticAbstractInterface.class
+                .getModifiers());
+    }
+
+    static abstract class MethodClass {
+
+        public abstract void publicAbstractMethod();
+
+        public static void publicStaticMethod() {
+        }
+
+        public final void publicFinalMethod() {
+        }
+
+        public static final void publicStaticFinalMethod() {
+        }
+    }
+
+    public void test_Method_Modifier() throws Exception {
+        assertEquals(Modifier.PUBLIC + Modifier.ABSTRACT, MethodClass.class
+                .getMethod("publicAbstractMethod", new Class[0]).getModifiers());
+        assertEquals(Modifier.PUBLIC + Modifier.STATIC, MethodClass.class
+                .getMethod("publicStaticMethod", new Class[0]).getModifiers());
+
+        assertEquals(Modifier.PUBLIC + Modifier.FINAL, MethodClass.class
+                .getMethod("publicFinalMethod", new Class[0]).getModifiers());
+
+        assertEquals(Modifier.PUBLIC + Modifier.STATIC + Modifier.FINAL,
+                MethodClass.class.getMethod("publicStaticFinalMethod",
+                        new Class[0]).getModifiers());
+    }
+
+    /**
+     * 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() {
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/UndeclaredThrowableExceptionTest.java b/luni/src/test/java/tests/api/java/lang/reflect/UndeclaredThrowableExceptionTest.java
new file mode 100644
index 0000000..b5ad350
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/lang/reflect/UndeclaredThrowableExceptionTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.lang.reflect;
+
+import java.lang.reflect.UndeclaredThrowableException;
+
+import junit.framework.TestCase;
+
+public class UndeclaredThrowableExceptionTest extends TestCase {
+
+    /**
+     * {@link java.lang.reflect.UndeclaredThrowableException#UndeclaredThrowableException(java.lang.Throwable)}
+     */
+    public void test_UndeclaredThrowableException_LThrowable() {
+        UndeclaredThrowableException e = new UndeclaredThrowableException(
+                (Exception) null);
+        assertNotNull(e);
+        assertNull(e.getCause());
+
+    }
+
+    /**
+     * {@link java.lang.reflect.UndeclaredThrowableException#UndeclaredThrowableException(java.lang.Throwable, java.lang.String)}
+     */
+    public void test_UndeclaredThrowableException_LThrowable_LString() {
+        UndeclaredThrowableException e = new UndeclaredThrowableException(null,
+                "SomeMsg");
+        assertNotNull(e);
+        assertNull(e.getCause());
+        assertEquals("Wrong message", "SomeMsg", e.getMessage());
+    }
+
+    /**
+     * {@link java.lang.reflect.UndeclaredThrowableException#getUndeclaredThrowable()}
+     */
+    public void test_getUndeclaredThrowable() {
+        UndeclaredThrowableException e = new UndeclaredThrowableException(null);
+        assertNotNull(e);
+        assertNull(e.getUndeclaredThrowable());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/AuthenticatorTest.java b/luni/src/test/java/tests/api/java/net/AuthenticatorTest.java
new file mode 100644
index 0000000..3c5f92b
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/AuthenticatorTest.java
@@ -0,0 +1,206 @@
+/* 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.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Authenticator;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.PasswordAuthentication;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.net.Authenticator.RequestorType;
+
+import junit.framework.TestCase;
+import tests.support.Support_PortManager;
+
+public class AuthenticatorTest extends TestCase {
+
+    /**
+     * java.net.Authenticator.RequestorType#valueOf(String)
+     */
+    public void test_RequestorType_valueOfLjava_lang_String() throws Exception {
+        assertEquals(RequestorType.PROXY, Authenticator.RequestorType
+                .valueOf("PROXY"));
+        assertEquals(RequestorType.SERVER, Authenticator.RequestorType
+                .valueOf("SERVER"));
+        try {
+            RequestorType rt = Authenticator.RequestorType.valueOf("BADNAME");
+            fail("Must throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // correct
+        }
+        // Some old RIs throw IllegalArgumentException 
+        // Latest RIs throw NullPointerException.
+        try {
+            Authenticator.RequestorType.valueOf(null);
+            fail("Must throw an exception");
+        } catch (NullPointerException e) {
+            // May be caused by some compilers' code
+        } catch (IllegalArgumentException e) {
+            // other compilers will throw this
+        }
+    }
+
+    /**
+     * java.net.Authenticator.RequestorType#values()
+     */
+    public void test_RequestorType_values() throws Exception {
+        RequestorType[] rt = RequestorType.values();
+        assertEquals(RequestorType.PROXY, rt[0]);
+        assertEquals(RequestorType.SERVER, rt[1]);
+    }
+
+    /**
+     * java.net.Authenticator#requestPasswordAuthentication(java.net.InetAddress, int, String, String, String)
+     */
+    public void test_requestPasswordAuthentication_InetAddress_int_String_String_String() throws Exception {
+        // Regression test for Harmony-2413
+        MockAuthenticator mock = new MockAuthenticator();
+        InetAddress addr = InetAddress.getLocalHost();
+        Authenticator.setDefault(mock);
+        Authenticator.requestPasswordAuthentication(addr, -1, "http", "promt", "HTTP");
+        assertEquals(mock.getRequestorType(), RequestorType.SERVER);
+    }
+
+    /**
+     * java.net.Authenticator#requestPasswordAuthentication(String, java.net.InetAddress, int, String, String, String)
+     */
+    public void test_requestPasswordAuthentication_String_InetAddress_int_String_String_String() throws Exception {
+        // Regression test for Harmony-2413
+        MockAuthenticator mock = new MockAuthenticator();
+        InetAddress addr = InetAddress.getLocalHost();
+        Authenticator.setDefault(mock);
+        Authenticator.requestPasswordAuthentication("test_host", addr, -1, "http", "promt", "HTTP");
+        assertEquals(mock.getRequestorType(), RequestorType.SERVER);
+    }
+
+    /**
+     * java.net.Authenticator#
+     * requestPasswordAuthentication_String_InetAddress_int_String_String_String_URL_Authenticator_RequestorType()
+     */
+    public void test_requestPasswordAuthentication_String_InetAddress_int_String_String_String_URL_Authenticator_RequestorType()
+            throws UnknownHostException, MalformedURLException {
+        MockAuthenticator mock = new MockAuthenticator();
+        URL url = new URL("http://127.0.0.1");
+        Authenticator.requestPasswordAuthentication("localhost", InetAddress
+                .getByName("127.0.0.1"), 80, "HTTP", "", "", url,
+                RequestorType.PROXY);
+        assertNull(mock.getRequestingURL());
+        assertNull(mock.getRequestorType());
+    }
+
+    /**
+     * java.net.Authenticator#getRequestingURL()
+     */
+    public void test_getRequestingURL() throws Exception {
+        MockAuthenticator mock = new MockAuthenticator();
+        assertNull(mock.getRequestingURL());
+    }
+
+    /**
+     * java.net.Authenticator#getRequestorType()
+     */
+    public void test_getRequestorType() throws Exception {
+        MockAuthenticator mock = new MockAuthenticator();
+        assertNull(mock.getRequestorType());
+    }
+
+    /**
+     * java.net.Authenticator#setDefault(java.net.Authenticator)
+     */
+    public void test_setDefault() {
+        final int port = Support_PortManager.getNextPort();
+        final Object lock = new Object();
+        final int[] result = new int[1];
+        Thread t = new Thread(new Runnable() {
+            public void run() {
+                try {
+                    ServerSocket ss = null;
+                    synchronized (lock) {
+                        ss = new ServerSocket(port);
+                        lock.notifyAll();
+                    }
+                    Socket s = ss.accept();
+                    InputStream in = s.getInputStream();
+                    in.read(new byte[1024]);
+                    OutputStream out = s.getOutputStream();
+                    out
+                            .write("HTTP/1.1 401 Unauthorized\r\nWWW-Authenticate:Basic realm=\"something\"\r\n\r\n"
+                                    .getBytes("ISO8859_1"));
+                    Thread.sleep(500);
+                    out.close();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        });
+        synchronized (lock) {
+            t.start();
+            try {
+                lock.wait();
+            } catch (InterruptedException e) {
+                // ignored
+            }
+        }
+        Authenticator.setDefault(new Authenticator() {
+            protected PasswordAuthentication getPasswordAuthentication() {
+                synchronized (lock) {
+                    result[0] = 1;
+                }
+                return null;
+            }
+        });
+        Authenticator.setDefault(new Authenticator() {
+            protected PasswordAuthentication getPasswordAuthentication() {
+                synchronized (lock) {
+                    result[0] = 2;
+                }
+                return null;
+            }
+        });
+        try {
+            new URL("http://localhost:" + port).openStream();
+        } catch (IOException e) {
+            // ignored
+        }
+        synchronized (lock) {
+            assertEquals("wrong authenticator: " + result[0], 2, result[0]);
+        }
+    }
+
+    /*
+     * Mock Authernticator for test
+     */
+    class MockAuthenticator extends java.net.Authenticator {
+        public MockAuthenticator() {
+            super();
+        }
+
+        public URL getRequestingURL() {
+            return super.getRequestingURL();
+        }
+
+        public Authenticator.RequestorType getRequestorType() {
+            return super.getRequestorType();
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/BindExceptionTest.java b/luni/src/test/java/tests/api/java/net/BindExceptionTest.java
new file mode 100644
index 0000000..e1eb401
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/BindExceptionTest.java
@@ -0,0 +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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES 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.BindException;
+
+public class BindExceptionTest extends junit.framework.TestCase {
+
+    /**
+     * java.net.BindException#BindException()
+     */
+    public void test_Constructor() {
+        // Test for method java.net.BindException()
+        try {
+            throw new BindException();
+        } catch (BindException e) {
+            return;
+        } catch (Exception e) {
+            fail("Exception during BindException test" + e.toString());
+        }
+        fail("Failed to generate exception");
+    }
+
+    /**
+     * java.net.BindException#BindException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        // Test for method java.net.BindException(java.lang.String)
+        try {
+            throw new BindException("Some error message");
+        } catch (BindException e) {
+            return;
+        } catch (Exception e) {
+            fail("Exception during BindException test : " + e.getMessage());
+        }
+        fail("Failed to generate exception");
+    }
+
+    /**
+     * 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() {
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/ConnectExceptionTest.java b/luni/src/test/java/tests/api/java/net/ConnectExceptionTest.java
new file mode 100644
index 0000000..12d37e3
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/ConnectExceptionTest.java
@@ -0,0 +1,36 @@
+/*
+ *  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.ConnectException;
+import java.net.InetAddress;
+import java.net.Socket;
+
+import tests.support.Support_PortManager;
+
+public class ConnectExceptionTest extends junit.framework.TestCase {
+
+    /**
+     * java.net.ConnectException#ConnectException()
+     * java.net.ConnectException#ConnectException(java.lang.String)
+     */
+    public void test_Constructor() {
+        assertNull("Wrong message", new ConnectException().getMessage());
+        assertEquals("Wrong message", "message", new ConnectException("message").getMessage());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/CookieHandlerTest.java b/luni/src/test/java/tests/api/java/net/CookieHandlerTest.java
new file mode 100644
index 0000000..9f1f4fe
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/CookieHandlerTest.java
@@ -0,0 +1,62 @@
+/* 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.io.IOException;
+import java.net.CookieHandler;
+import java.net.NetPermission;
+import java.net.URI;
+import java.security.Permission;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+public class CookieHandlerTest extends TestCase {
+
+    /**
+     * java.net.CookieHandler#getDefault()
+     */
+    public void test_GetDefault() {
+        assertNull(CookieHandler.getDefault());
+    }
+
+    /**
+     * java.net.CookieHandler#setDefault(CookieHandler)
+     */
+    public void test_SetDefault_java_net_cookieHandler() {
+        MockCookieHandler rc1 = new MockCookieHandler();
+        MockCookieHandler rc2 = new MockCookieHandler();
+        CookieHandler.setDefault(rc1);
+        assertSame(CookieHandler.getDefault(), rc1);
+        CookieHandler.setDefault(rc2);
+        assertSame(CookieHandler.getDefault(), rc2);
+        CookieHandler.setDefault(null);
+        assertNull(CookieHandler.getDefault());
+    }
+
+    class MockCookieHandler extends CookieHandler {
+
+        public Map get(URI uri, Map requestHeaders) throws IOException {
+            return null;
+        }
+
+        public void put(URI uri, Map responseHeaders) throws IOException {
+            // empty
+        }
+
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/CookieManagerTest.java b/luni/src/test/java/tests/api/java/net/CookieManagerTest.java
new file mode 100644
index 0000000..26124aa
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/CookieManagerTest.java
@@ -0,0 +1,301 @@
+/* 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.io.IOException;
+import java.net.CookieManager;
+import java.net.CookiePolicy;
+import java.net.CookieStore;
+import java.net.HttpCookie;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import junit.framework.TestCase;
+
+public class CookieManagerTest extends TestCase {
+
+    private static void checkValidParams4Get(URI uri,
+            Map<String, List<String>> map) throws IOException {
+        CookieManager manager = new CookieManager();
+        try {
+            manager.get(uri, map);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+    }
+
+    private static void checkValidParams4Put(URI uri,
+            Map<String, List<String>> map) throws IOException {
+        CookieManager manager = new CookieManager();
+        try {
+            manager.put(uri, map);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+    }
+
+    /**
+     * {@link java.net.CookieManager#get(java.net.URI, java.util.Map)} &
+     * {@link java.net.CookieManager#put(java.net.URI, java.util.Map)}
+     * IllegalArgumentException
+     * @since 1.6
+     */
+    public void test_Put_Get_LURI_LMap_exception() throws IOException,
+            URISyntaxException {
+        // get
+        checkValidParams4Get(new URI(""), null);
+        checkValidParams4Get(new URI("http://www.test.com"), null);
+        checkValidParams4Get(null, null);
+        checkValidParams4Get(null, new HashMap<String, List<String>>());
+
+        // put
+        checkValidParams4Put(new URI(""), null);
+        checkValidParams4Put(new URI("http://www.test.com"), null);
+        checkValidParams4Put(null, null);
+        checkValidParams4Put(null, new HashMap<String, List<String>>());
+    }
+
+    private static Map<String, List<String>> addCookie(String[][] cookies) {
+        Map<String, List<String>> responseHeaders = new TreeMap<String, List<String>>();
+        for (int i = 0; i < cookies.length; i++) {
+            List<String> fields = new ArrayList<String>();
+            for (int j = 1; j < cookies[i].length; j += 2) {
+                fields.add(cookies[i][j]);
+            }
+            responseHeaders.put(cookies[i][0], fields);
+        }
+        return responseHeaders;
+    }
+
+    private static CookieManager store(String[][] cookies,
+            Map<String, List<String>> responseHeaders, CookiePolicy policy)
+            throws IOException, URISyntaxException {
+        CookieManager manager = new CookieManager(null, policy);
+        // Put all cookies into manager
+        for (int i = 0; i < cookies.length; i++) {
+            for (int j = 2; j < cookies[i].length; j += 2) {
+                URI uri = new URI(cookies[i][j]);
+                manager.put(uri, responseHeaders);
+            }
+        }
+        return manager;
+    }
+
+    /**
+     * {@link java.net.CookieManager#get(java.net.URI, java.util.Map)} &
+     * {@link java.net.CookieManager#put(java.net.URI, java.util.Map)}
+     * @since 1.6
+     */
+    public void test_Put_Get_LURI_LMap() throws IOException, URISyntaxException {
+        // cookie-key | (content, URI)...
+        String[][] cookies = {
+                { "Set-cookie",
+                        "Set-cookie:PREF=test;path=/;domain=.b.c;", "http://a.b.c/",
+                        "Set-cookie:PREF1=test2;path=/;domain=.beg.com;", "http://a.b.c/" },
+
+                { "Set-cookie2",
+                        "Set-cookie2:NAME1=VALUE1;path=/te;domain=.b.c;", "http://a.b.c/test" },
+
+                { "Set-cookie",
+                        "Set-cookie2:NAME=VALUE;path=/;domain=.beg.com;", "http://a.beg.com/test",
+                        "Set-cookie2:NAME1=VALUE1;path=/;domain=.beg.com;", "http://a.beg.com/test" },
+
+                { "Set-cookie2",
+                        "Set-cookie3:NAME=VALUE;path=/;domain=.test.org;", "http://a.test.org/test" },
+
+                { null,
+                        "Set-cookie3:NAME=VALUE;path=/te;domain=.test.org;", "http://a.test.org/test" },
+
+                { "Set-cookie2",
+                        "lala", "http://a.test.org/test" }
+
+        };
+
+        // requires path of cookie is the prefix of uri
+        // domain of cookie must match that of uri
+        Map<String, List<String>> responseHeaders = addCookie(new String[][] {
+                cookies[0], cookies[1] });
+        CookieManager manager = store(
+                new String[][] { cookies[0], cookies[1] }, responseHeaders,
+                null);
+
+        HashMap<String, List<String>> dummyMap = new HashMap<String, List<String>>();
+        Map<String, List<String>> map = manager.get(new URI("http://a.b.c/"),
+                dummyMap);
+
+        assertEquals(1, map.size());
+        List<String> list = map.get("Cookie");
+        assertEquals(1, list.size());
+
+        // requires path of cookie is the prefix of uri
+        map = manager.get(new URI("http://a.b.c/te"), dummyMap);
+        list = map.get("Cookie");
+        assertEquals(2, list.size());
+
+        // If all cookies are of version 1, then $version=1 will be added
+        // ,no matter the value cookie-key
+        responseHeaders = addCookie(new String[][] { cookies[2] });
+        manager = store(new String[][] { cookies[2] }, responseHeaders, null);
+        map = manager.get(new URI("http://a.beg.com/test"), dummyMap);
+        list = map.get("Cookie");
+        assertEquals("$Version=\"1\"", list.get(0));
+        assertEquals(3, list.size());
+
+        // cookie-key will not have effect on determining cookie version
+        responseHeaders = addCookie(new String[][] { cookies[3] });
+        manager = store(new String[][] { cookies[3] }, responseHeaders, null);
+        map = manager.get(new URI("http://a.test.org/"), responseHeaders);
+        list = map.get("Cookie");
+        assertEquals(1, list.size());
+        assertEquals("Set-cookie3:NAME=VALUE", list.get(0));
+
+        // When key is null, no cookie can be stored/retrieved, even if policy =
+        // ACCEPT_ALL
+        responseHeaders = addCookie(new String[][] { cookies[4] });
+        manager = store(new String[][] { cookies[4] }, responseHeaders,
+                CookiePolicy.ACCEPT_ALL);
+        map = manager.get(new URI("http://a.test.org/"), responseHeaders);
+        list = map.get("Cookie");
+        assertEquals(0, list.size());
+
+        // All cookies will be rejected if policy == ACCEPT_NONE
+        responseHeaders = addCookie(new String[][] { cookies[3] });
+        manager = store(new String[][] { cookies[3] }, responseHeaders,
+                CookiePolicy.ACCEPT_NONE);
+        map = manager.get(new URI("http://a.test.org/"), responseHeaders);
+        list = map.get("Cookie");
+        assertEquals(0, list.size());
+
+        responseHeaders = addCookie(new String[][] { cookies[5] });
+        manager = store(new String[][] { cookies[5] }, responseHeaders,
+                CookiePolicy.ACCEPT_ALL);
+        list = map.get("Cookie");
+        assertEquals(0, list.size());
+
+        try {
+            map.put(null, null);
+            fail("Should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+
+    }
+
+    /**
+     * {@link java.net.CookieManager#CookieManager()}
+     * @since 1.6
+     */
+    public void test_CookieManager() {
+        CookieManager cookieManager = new CookieManager();
+        assertNotNull(cookieManager);
+        assertNotNull(cookieManager.getCookieStore());
+    }
+
+    /**
+     * {@link java.net.CookieManager#CookieManager(java.net.CookieStore, java.net.CookiePolicy)}
+     * @since 1.6
+     */
+    public void testCookieManager_LCookieStore_LCookiePolicy() {
+        class DummyStore implements CookieStore {
+            public String getName() {
+                return "A dummy store";
+            }
+
+            public void add(URI uri, HttpCookie cookie) {
+                // expected
+            }
+
+            public List<HttpCookie> get(URI uri) {
+                return null;
+            }
+
+            public List<HttpCookie> getCookies() {
+                return null;
+            }
+
+            public List<URI> getURIs() {
+                return null;
+            }
+
+            public boolean remove(URI uri, HttpCookie cookie) {
+                return false;
+            }
+
+            public boolean removeAll() {
+                return false;
+            }
+        }
+        CookieStore store = new DummyStore();
+        CookieManager cookieManager = new CookieManager(store,
+                CookiePolicy.ACCEPT_ALL);
+        assertEquals("A dummy store", ((DummyStore) cookieManager
+                .getCookieStore()).getName());
+        assertSame(store, cookieManager.getCookieStore());
+    }
+
+    /**
+     * {@link java.net.CookieManager#setCookiePolicy(java.net.CookiePolicy)}
+     * @since 1.6
+     */
+    public void test_SetCookiePolicy_LCookiePolicy() throws URISyntaxException,
+            IOException {
+
+        // Policy = ACCEPT_NONE
+        CookieManager manager = new CookieManager();
+        manager.setCookiePolicy(CookiePolicy.ACCEPT_NONE);
+        Map<String, List<String>> responseHeaders = new TreeMap<String, List<String>>();
+        URI uri = new URI("http://a.b.c");
+        manager.put(uri, responseHeaders);
+        Map<String, List<String>> map = manager.get(uri,
+                new HashMap<String, List<String>>());
+
+        assertEquals(1, map.size());
+        assertTrue(map.get("Cookie").isEmpty());
+        Object key = map.keySet().toArray()[0];
+        assertNotNull(key);
+        assertEquals("Cookie", key);
+
+        // Policy = ACCEPT_ALL
+        manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
+        responseHeaders = new TreeMap<String, List<String>>();
+        ArrayList<String> list = new ArrayList<String>();
+        list.add("test=null");
+        responseHeaders.put("Set-cookie", list);
+        manager.put(new URI("http://b.c.d"), responseHeaders);
+        map = manager.get(uri, new HashMap<String, List<String>>());
+        assertEquals(1, map.size());
+    }
+
+    /**
+     * {@link java.net.CookieManager#getCookieStore()}
+     * @since 1.6
+     */
+    public void test_GetCookieStore() {
+        CookieManager cookieManager = new CookieManager();
+        CookieStore store = cookieManager.getCookieStore();
+        assertNotNull(store);
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/net/CookiePolicyTest.java b/luni/src/test/java/tests/api/java/net/CookiePolicyTest.java
new file mode 100644
index 0000000..b88d356
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/CookiePolicyTest.java
@@ -0,0 +1,112 @@
+/* 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.CookiePolicy;
+import java.net.HttpCookie;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import junit.framework.TestCase;
+
+public class CookiePolicyTest extends TestCase {
+
+    /**
+     * java.net.CookiePolicy#shouldAccept(java.net.URI,
+     *java.net.HttpCookie).
+     * @since 1.6
+     */
+    public void test_ShouldAccept_LURI_LHttpCookie() throws URISyntaxException {
+        HttpCookie cookie = new HttpCookie("Harmony_6", "ongoing");
+        URI uri = new URI("");
+        try {
+            CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(null, cookie);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(uri, null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(null, null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        // Policy: ACCEPT_ALL, always returns true
+        boolean accept = CookiePolicy.ACCEPT_ALL.shouldAccept(null, cookie);
+        assertTrue(accept);
+
+        accept = CookiePolicy.ACCEPT_ALL.shouldAccept(null, null);
+        assertTrue(accept);
+
+        accept = CookiePolicy.ACCEPT_ALL.shouldAccept(uri, null);
+        assertTrue(accept);
+
+        // Policy: ACCEPT_NONE, always returns false
+        accept = CookiePolicy.ACCEPT_NONE.shouldAccept(null, cookie);
+        assertFalse(accept);
+
+        accept = CookiePolicy.ACCEPT_NONE.shouldAccept(null, null);
+        assertFalse(accept);
+
+        accept = CookiePolicy.ACCEPT_NONE.shouldAccept(uri, null);
+        assertFalse(accept);
+
+        // Policy: ACCEPT_ORIGINAL_SERVER
+        accept = CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(uri, cookie);
+        assertFalse(accept);
+
+        cookie.setDomain(".b.c");
+        accept = CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(new URI(
+                "schema://a.b.c"), cookie);
+        assertTrue(accept);
+
+        cookie.setDomain(".b.c");
+        accept = CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(new URI(
+                "s://a.b.c.d"), cookie);
+        assertFalse(accept);
+
+        cookie.setDomain("b.c");
+        accept = CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(new URI(
+                "s://a.b.c.d"), cookie);
+        assertFalse(accept);
+
+        cookie.setDomain("a.b.c.d");
+        accept = CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(new URI(
+                "s://a.b.c.d"), cookie);
+        assertTrue(accept);
+
+        cookie.setDomain(".");
+        accept = CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(new URI(
+                "s://a.b.c.d"), cookie);
+        assertFalse(accept);
+
+        cookie.setDomain("");
+        accept = CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(new URI(
+                "s://a.b.c.d"), cookie);
+        assertFalse(accept);
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/net/CookieStoreTest.java b/luni/src/test/java/tests/api/java/net/CookieStoreTest.java
new file mode 100644
index 0000000..9ca718f
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/CookieStoreTest.java
@@ -0,0 +1,404 @@
+/* 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.CookieManager;
+import java.net.CookieStore;
+import java.net.HttpCookie;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.RandomAccess;
+
+import junit.framework.TestCase;
+
+public class CookieStoreTest extends TestCase {
+
+    private CookieManager cookieManager;
+
+    private CookieStore cookieStore;
+
+    /**
+     * java.net.CookieStore#add(URI, HttpCookie)
+     * @since 1.6
+     */
+    public void test_add_LURI_LHttpCookie() throws URISyntaxException {
+        URI uri = new URI("http://harmony.test.unit.org");
+        HttpCookie cookie = new HttpCookie("name1", "value1");
+        cookie.setDiscard(true);
+        try {
+            cookieStore.add(null, cookie);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            cookieStore.add(uri, null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            cookieStore.add(null, null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        cookieStore.add(uri, cookie);
+        List<HttpCookie> list = cookieStore.get(uri);
+        assertEquals(1, list.size());
+        assertTrue(list.contains(cookie));
+
+        HttpCookie cookie2 = new HttpCookie("  NaME1   ", "  TESTVALUE1   ");
+        cookieStore.add(uri, cookie2);
+        list = cookieStore.get(uri);
+        assertEquals(1, list.size());
+        assertEquals("  TESTVALUE1   ", list.get(0).getValue());
+        assertTrue(list.contains(cookie2));
+
+        // domain and path attributes works
+        HttpCookie anotherCookie = new HttpCookie("name1", "value1");
+        anotherCookie.setDomain("domain");
+        anotherCookie.setPath("Path");
+        cookieStore.add(uri, anotherCookie);
+        list = cookieStore.get(uri);
+        assertEquals(2, list.size());
+        assertNull(list.get(0).getDomain());
+        assertEquals("domain", list.get(1).getDomain());
+        assertEquals("Path", list.get(1).getPath());
+
+        URI uri2 = new URI("http://.test.unit.org");
+        HttpCookie cookie3 = new HttpCookie("NaME2", "VALUE2");
+        cookieStore.add(uri2, cookie3);
+        list = cookieStore.get(uri2);
+        assertEquals(1, list.size());
+        assertEquals("VALUE2", list.get(0).getValue());
+        list = cookieStore.getCookies();
+        assertEquals(3, list.size());
+
+        // expired cookie won't be selected.
+        HttpCookie cookie4 = new HttpCookie("cookie4", "value4");
+        cookie4.setMaxAge(-2);
+        assertTrue(cookie4.hasExpired());
+        cookieStore.add(uri2, cookie4);
+        list = cookieStore.getCookies();
+        assertEquals(3, list.size());
+        assertFalse(cookieStore.remove(uri2, cookie4));
+
+        cookie4.setMaxAge(3000);
+        cookie4.setDomain("domain");
+        cookie4.setPath("path");
+        cookieStore.add(uri2, cookie4);
+        list = cookieStore.get(uri2);
+        assertEquals(2, list.size());
+
+        cookieStore.add(uri, cookie4);
+        list = cookieStore.get(uri);
+        assertEquals(3, list.size());
+        list = cookieStore.get(uri2);
+        assertEquals(2, list.size());
+        list = cookieStore.getCookies();
+        assertEquals(4, list.size());
+
+        URI baduri = new URI("bad_url");
+        HttpCookie cookie6 = new HttpCookie("cookie5", "value5");
+        cookieStore.add(baduri, cookie6);
+        list = cookieStore.get(baduri);
+        assertTrue(list.contains(cookie6));
+    }
+
+    /**
+     * java.net.CookieStore#get(URI)
+     * @since 1.6
+     */
+    public void test_get_LURI() throws URISyntaxException {
+        try {
+            cookieStore.get(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        URI uri1 = new URI("http://get.uri1.test.org");
+        List<HttpCookie> list = cookieStore.get(uri1);
+        assertTrue(list.isEmpty());
+        assertTrue(list instanceof ArrayList);
+
+        HttpCookie cookie1 = new HttpCookie("cookie_name1", "cookie_value1");
+        HttpCookie cookie2 = new HttpCookie("cookie_name2", "cookie_value2");
+        cookieStore.add(uri1, cookie1);
+        cookieStore.add(uri1, cookie2);
+        URI uri2 = new URI("http://get.uri2.test.org");
+        HttpCookie cookie3 = new HttpCookie("cookie_name3", "cookie_value3");
+        cookieStore.add(uri2, cookie3);
+        list = cookieStore.get(uri1);
+        assertEquals(2, list.size());
+        list = cookieStore.get(uri2);
+        assertEquals(1, list.size());
+
+        // domain-match cookies also be selected.
+        HttpCookie cookie4 = new HttpCookie("cookie_name4", "cookie_value4");
+        cookie4.setDomain(".uri1.test.org");
+        cookieStore.add(uri2, cookie4);
+        list = cookieStore.get(uri1);
+        assertEquals(3, list.size());
+
+        cookieStore.add(uri1, cookie4);
+        list = cookieStore.get(uri1);
+        assertEquals(3, list.size());
+        list = cookieStore.get(uri2);
+        assertEquals(2, list.size());
+
+        // expired cookie won't be selected.
+        HttpCookie cookie5 = new HttpCookie("cookie_name5", "cookie_value5");
+        cookie5.setMaxAge(-333);
+        assertTrue(cookie5.hasExpired());
+        cookieStore.add(uri1, cookie5);
+        list = cookieStore.get(uri1);
+        assertEquals(3, list.size());
+        assertFalse(cookieStore.remove(uri1, cookie5));
+        list = cookieStore.getCookies();
+        assertEquals(4, list.size());
+
+        cookie4.setMaxAge(-123);
+        list = cookieStore.get(uri1);
+        assertEquals(2, list.size());
+        list = cookieStore.getCookies();
+        assertEquals(3, list.size());
+        // expired cookies are also deleted even if it domain-matches the URI
+        HttpCookie cookie6 = new HttpCookie("cookie_name6", "cookie_value6");
+        cookie6.setMaxAge(-2);
+        cookie6.setDomain(".uri1.test.org");
+        cookieStore.add(uri2, cookie6);
+        list = cookieStore.get(uri1);
+        assertEquals(2, list.size());
+        assertFalse(cookieStore.remove(null, cookie6));
+
+        URI uri3 = new URI("http://get.uri3.test.org");
+        assertTrue(cookieStore.get(uri3).isEmpty());
+        URI baduri = new URI("invalid_uri");
+        assertTrue(cookieStore.get(baduri).isEmpty());
+    }
+
+    /**
+     * java.net.CookieStore#getCookies()
+     * @since 1.6
+     */
+    public void test_getCookies() throws URISyntaxException {
+        List<HttpCookie> list = cookieStore.getCookies();
+        assertTrue(list.isEmpty());
+        assertTrue(list instanceof RandomAccess);
+
+        HttpCookie cookie1 = new HttpCookie("cookie_name", "cookie_value");
+        URI uri1 = new URI("http://getcookies1.test.org");
+        cookieStore.add(uri1, cookie1);
+        list = cookieStore.getCookies();
+        assertTrue(list.contains(cookie1));
+
+        HttpCookie cookie2 = new HttpCookie("cookie_name2", "cookie_value2");
+        URI uri2 = new URI("http://getcookies2.test.org");
+        cookieStore.add(uri2, cookie2);
+        list = cookieStore.getCookies();
+        assertEquals(2, list.size());
+        assertTrue(list.contains(cookie1));
+        assertTrue(list.contains(cookie2));
+
+        // duplicated cookie won't be selected.
+        cookieStore.add(uri2, cookie1);
+        list = cookieStore.getCookies();
+        assertEquals(2, list.size());
+        // expired cookie won't be selected.
+        HttpCookie cookie3 = new HttpCookie("cookie_name3", "cookie_value3");
+        cookie3.setMaxAge(-1357);
+        cookieStore.add(uri1, cookie3);
+        list = cookieStore.getCookies();
+        assertEquals(2, list.size());
+
+        try {
+            list.add(new HttpCookie("readOnlyName", "readOnlyValue"));
+            fail("should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+
+        try {
+            list.remove(new HttpCookie("readOnlyName", "readOnlyValue"));
+            fail("should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.net.CookieStore#getURIs()
+     * @since 1.6
+     */
+    public void test_getURIs() throws URISyntaxException {
+        List<URI> list = cookieStore.getURIs();
+        assertTrue(list.isEmpty());
+        assertTrue(list instanceof ArrayList);
+
+        URI uri1 = new URI("http://geturis1.test.com");
+        HttpCookie cookie1 = new HttpCookie("cookie_name1", "cookie_value1");
+        cookieStore.add(uri1, cookie1);
+        list = cookieStore.getURIs();
+        assertEquals("geturis1.test.com", list.get(0).getHost());
+
+        HttpCookie cookie2 = new HttpCookie("cookie_name2", "cookie_value2");
+        cookieStore.add(uri1, cookie2);
+        list = cookieStore.getURIs();
+        assertEquals(1, list.size());
+
+        URI uri2 = new URI("http://geturis2.test.com");
+        cookieStore.add(uri2, cookie2);
+        list = cookieStore.getURIs();
+        assertEquals(2, list.size());
+        assertTrue(list.contains(uri1));
+        assertTrue(list.contains(uri2));
+    }
+
+    /**
+     * java.net.CookieStore#remove(URI, HttpCookie)
+     * @since 1.6
+     */
+    public void test_remove_LURI_LHttpCookie() throws URISyntaxException {
+        URI uri1 = new URI("http://remove1.test.com");
+        HttpCookie cookie1 = new HttpCookie("cookie_name1", "cookie_value1");
+        try {
+            cookieStore.remove(uri1, null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        assertFalse(cookieStore.remove(uri1, cookie1));
+        assertFalse(cookieStore.remove(null, cookie1));
+
+        cookieStore.add(uri1, cookie1);
+        URI uri2 = new URI("http://remove2.test.com");
+        HttpCookie cookie2 = new HttpCookie("cookie_name2", "cookie_value2");
+        cookieStore.add(uri2, cookie2);
+        assertTrue(cookieStore.remove(uri1, cookie1));
+        assertFalse(cookieStore.remove(uri1, cookie1));
+        assertEquals(2, cookieStore.getURIs().size());
+        assertEquals(1, cookieStore.getCookies().size());
+        assertTrue(cookieStore.remove(uri2, cookie2));
+        assertFalse(cookieStore.remove(uri2, cookie2));
+        assertEquals(2, cookieStore.getURIs().size());
+        assertEquals(0, cookieStore.getCookies().size());
+
+        assertTrue(cookieStore.removeAll());
+        cookieStore.add(uri1, cookie1);
+        cookieStore.add(uri2, cookie2);
+        HttpCookie cookie3 = new HttpCookie("cookie_name3", "cookie_value3");
+        assertFalse(cookieStore.remove(null, cookie3));
+        assertTrue(cookieStore.remove(null, cookie1));
+        assertFalse(cookieStore.remove(null, cookie1));
+        assertEquals(2, cookieStore.getURIs().size());
+        assertEquals(1, cookieStore.getCookies().size());
+        assertTrue(cookieStore.remove(null, cookie2));
+        assertFalse(cookieStore.remove(null, cookie2));
+        assertEquals(2, cookieStore.getURIs().size());
+        assertEquals(0, cookieStore.getCookies().size());
+
+        cookieStore.removeAll();
+        // expired cookies can also be deleted.
+        cookie2.setMaxAge(-34857);
+        cookieStore.add(uri2, cookie2);
+        assertTrue(cookieStore.remove(uri2, cookie2));
+        assertFalse(cookieStore.remove(uri2, cookie2));
+        assertEquals(0, cookieStore.getCookies().size());
+
+        cookie2.setMaxAge(34857);
+        cookieStore.add(uri1, cookie1);
+        cookieStore.add(uri2, cookie1);
+        cookieStore.add(uri2, cookie2);
+        assertTrue(cookieStore.remove(uri1, cookie1));
+        assertFalse(cookieStore.remove(uri1, cookie1));
+        assertFalse(cookieStore.get(uri2).contains(cookie1));
+        assertTrue(cookieStore.get(uri2).contains(cookie2));
+        assertEquals(0, cookieStore.get(uri1).size());
+        cookieStore.remove(uri2, cookie2);
+
+        cookieStore.removeAll();
+        cookieStore.add(uri2, cookie2);
+        cookieStore.add(uri1, cookie1);
+        assertEquals(2, cookieStore.getCookies().size());
+        assertTrue(cookieStore.remove(uri2, cookie1));
+        assertFalse(cookieStore.remove(uri2, cookie1));
+        assertEquals(2, cookieStore.getURIs().size());
+        assertEquals(1, cookieStore.getCookies().size());
+        assertTrue(cookieStore.getCookies().contains(cookie2));
+
+        cookieStore.removeAll();
+        URI uri3 = new URI("http://remove3.test.com");
+        URI uri4 = new URI("http://test.com");
+        HttpCookie cookie4 = new HttpCookie("cookie_name4", "cookie_value4");
+        cookie4.setDomain(".test.com");
+        cookie2.setMaxAge(-34857);
+        cookie3.setMaxAge(-22);
+        cookie4.setMaxAge(-45);
+        cookieStore.add(uri1, cookie1);
+        cookieStore.add(uri2, cookie2);
+        cookieStore.add(uri3, cookie3);
+        cookieStore.add(uri4, cookie4);
+        assertEquals(0, cookieStore.get(uri2).size());
+        assertFalse(cookieStore.remove(uri2, cookie2));
+        assertTrue(cookieStore.remove(uri3, cookie3));
+        assertFalse(cookieStore.remove(uri4, cookie4));
+    }
+
+    /**
+     * java.net.CookieStore#test_removeAll()
+     * @since 1.6
+     */
+    public void test_removeAll() throws URISyntaxException {
+        // Spec says returns true if this store changed as a result of the call.
+        // But RI always return true.
+        assertTrue(cookieStore.removeAll());
+
+        URI uri1 = new URI("http://removeAll1.test.com");
+        HttpCookie cookie1 = new HttpCookie("cookie_name1", "cookie_value1");
+        cookieStore.add(uri1, cookie1);
+        URI uri2 = new URI("http://removeAll2.test.com");
+        HttpCookie cookie2 = new HttpCookie("cookie_name2", "cookie_value2");
+        cookieStore.add(uri2, cookie2);
+
+        assertTrue(cookieStore.removeAll());
+        assertTrue(cookieStore.getURIs().isEmpty());
+        assertTrue(cookieStore.getCookies().isEmpty());
+
+        assertTrue(cookieStore.removeAll());
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        cookieManager = new CookieManager();
+        cookieStore = cookieManager.getCookieStore();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        cookieManager = null;
+        cookieStore = null;
+        super.tearDown();
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/net/DatagramPacketTest.java b/luni/src/test/java/tests/api/java/net/DatagramPacketTest.java
new file mode 100644
index 0000000..e6ced7e
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/DatagramPacketTest.java
@@ -0,0 +1,338 @@
+/*
+ *  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.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+
+import tests.support.Support_Configuration;
+
+public class DatagramPacketTest extends junit.framework.TestCase {
+
+    volatile boolean started = false;
+
+    /**
+     * java.net.DatagramPacket#DatagramPacket(byte[], int)
+     */
+    public void test_Constructor$BI() {
+        DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5);
+        assertEquals("Created incorrect packet", "Hello", new String(dp
+                .getData(), 0, dp.getData().length));
+        assertEquals("Wrong length", 5, dp.getLength());
+
+        // Regression for HARMONY-890
+        dp = new DatagramPacket(new byte[942], 4);
+        assertEquals(-1, dp.getPort());
+        try {
+            dp.getSocketAddress();
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.net.DatagramPacket#DatagramPacket(byte[], int, int)
+     */
+    public void test_Constructor$BII() {
+        DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 2, 3);
+        assertEquals("Created incorrect packet", "Hello", new String(dp
+                .getData(), 0, dp.getData().length));
+        assertEquals("Wrong length", 3, dp.getLength());
+        assertEquals("Wrong offset", 2, dp.getOffset());
+    }
+
+    /**
+     * java.net.DatagramPacket#DatagramPacket(byte[], int, int,
+     *java.net.InetAddress, int)
+     */
+    public void test_Constructor$BIILjava_net_InetAddressI() throws IOException {
+        DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 2, 3,
+                InetAddress.getLocalHost(), 0);
+        assertEquals("Wrong host", InetAddress.getLocalHost(), dp.getAddress());
+        assertEquals("Wrong port", 0, dp.getPort());
+        assertEquals("Wrong length", 3, dp.getLength());
+        assertEquals("Wrong offset", 2, dp.getOffset());
+    }
+
+    /**
+     * java.net.DatagramPacket#DatagramPacket(byte[], int,
+     *java.net.InetAddress, int)
+     */
+    public void test_Constructor$BILjava_net_InetAddressI() throws IOException {
+        DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5,
+                InetAddress.getLocalHost(), 0);
+        assertEquals("Wrong address", InetAddress.getLocalHost(), dp
+                .getAddress());
+        assertEquals("Wrong port", 0, dp.getPort());
+        assertEquals("Wrong length", 5, dp.getLength());
+    }
+
+    /**
+     * java.net.DatagramPacket#getAddress()
+     */
+    public void test_getAddress() throws IOException {
+        DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5,
+                InetAddress.getLocalHost(), 0);
+        assertEquals("Incorrect address returned", InetAddress.getLocalHost(),
+                dp.getAddress());
+    }
+
+    /**
+     * java.net.DatagramPacket#getData()
+     */
+    public void test_getData() {
+        DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5);
+        assertEquals("Incorrect length returned", "Hello", new String(dp
+                .getData(), 0, dp.getData().length));
+    }
+
+    /**
+     * java.net.DatagramPacket#getLength()
+     */
+    public void test_getLength() {
+        DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5);
+        assertEquals("Incorrect length returned", 5, dp.getLength());
+    }
+
+    /**
+     * java.net.DatagramPacket#getOffset()
+     */
+    public void test_getOffset() {
+        DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 3, 2);
+        assertEquals("Incorrect length returned", 3, dp.getOffset());
+    }
+
+    /**
+     * java.net.DatagramPacket#getPort()
+     */
+    public void test_getPort() throws IOException {
+        DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5,
+                InetAddress.getLocalHost(), 1000);
+        assertEquals("Incorrect port returned", 1000, dp.getPort());
+
+        final InetAddress localhost = InetAddress.getLocalHost();
+        DatagramSocket socket = new DatagramSocket(0, localhost);
+        final int port = socket.getLocalPort();
+
+        socket.setSoTimeout(3000);
+        DatagramPacket packet = new DatagramPacket(new byte[] { 1, 2, 3, 4, 5,
+                6 }, 6, localhost, port);
+        socket.send(packet);
+        socket.receive(packet);
+        socket.close();
+        assertTrue("datagram received wrong port: " + packet.getPort(), packet
+                .getPort() == port);
+    }
+
+    /**
+     * java.net.DatagramPacket#setAddress(java.net.InetAddress)
+     */
+    public void test_setAddressLjava_net_InetAddress() throws IOException {
+        InetAddress ia = InetAddress.getByName("127.0.0.1");
+        DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5,
+                InetAddress.getLocalHost(), 0);
+        dp.setAddress(ia);
+        assertEquals("Incorrect address returned", ia, dp.getAddress());
+    }
+
+    /**
+     * java.net.DatagramPacket#setData(byte[], int, int)
+     */
+    public void test_setData$BII() {
+        DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5);
+        dp.setData("Wagga Wagga".getBytes(), 2, 3);
+        assertEquals("Incorrect data set", "Wagga Wagga", new String(dp
+                .getData()));
+    }
+
+    /**
+     * java.net.DatagramPacket#setData(byte[])
+     */
+    public void test_setData$B() {
+        DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5);
+        dp.setData("Ralph".getBytes());
+        assertEquals("Incorrect data set", "Ralph", new String(dp.getData(), 0,
+                dp.getData().length));
+    }
+
+    /**
+     * java.net.DatagramPacket#setLength(int)
+     */
+    public void test_setLengthI() {
+        DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5);
+        dp.setLength(1);
+        assertEquals("Failed to set packet length", 1, dp.getLength());
+    }
+
+    /**
+     * java.net.DatagramPacket#setPort(int)
+     */
+    public void test_setPortI() throws Exception {
+        DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5,
+                InetAddress.getLocalHost(), 1000);
+        dp.setPort(2000);
+        assertEquals("Port not set", 2000, dp.getPort());
+    }
+
+    /**
+     * java.net.DatagramPacket#DatagramPacket(byte[], int,
+     *java.net.SocketAddress)
+     */
+    public void test_Constructor$BILjava_net_SocketAddress() throws IOException {
+        @SuppressWarnings("serial")
+        class UnsupportedSocketAddress extends SocketAddress {
+
+            public UnsupportedSocketAddress() {
+            }
+        }
+
+        // Unsupported SocketAddress subclass
+        byte buf[] = new byte[1];
+        try {
+            new DatagramPacket(buf, 1, new UnsupportedSocketAddress());
+            fail("No exception when constructing using unsupported SocketAddress subclass");
+        } catch (IllegalArgumentException ex) {
+            // Expected
+        }
+
+        // Case were we try to pass in null
+        try {
+            new DatagramPacket(buf, 1, null);
+            fail("No exception when constructing address using null");
+        } catch (IllegalArgumentException ex) {
+            // Expected
+        }
+
+        // Now validate we can construct
+        InetSocketAddress theAddress = new InetSocketAddress(InetAddress
+                .getLocalHost(), 2067);
+        DatagramPacket thePacket = new DatagramPacket(buf, 1, theAddress);
+        assertEquals("Socket address not set correctly (1)", theAddress,
+                thePacket.getSocketAddress());
+        assertEquals("Socket address not set correctly (2)", theAddress,
+                new InetSocketAddress(thePacket.getAddress(), thePacket
+                        .getPort()));
+    }
+
+    /**
+     * java.net.DatagramPacket#DatagramPacket(byte[], int, int,
+     *java.net.SocketAddress)
+     */
+    public void test_Constructor$BIILjava_net_SocketAddress()
+            throws IOException {
+        @SuppressWarnings("serial")
+        class UnsupportedSocketAddress extends SocketAddress {
+
+            public UnsupportedSocketAddress() {
+            }
+        }
+
+        // Unsupported SocketAddress subclass
+        byte buf[] = new byte[2];
+        try {
+            new DatagramPacket(buf, 1, 1, new UnsupportedSocketAddress());
+            fail("No exception when constructing using unsupported SocketAddress subclass");
+        } catch (IllegalArgumentException ex) {
+            // Expected
+        }
+
+        // Case were we try to pass in null
+        try {
+            new DatagramPacket(buf, 1, 1, null);
+            fail("No exception when constructing address using null");
+        } catch (IllegalArgumentException ex) {
+            // Expected
+        }
+
+        // now validate we can construct
+        InetSocketAddress theAddress = new InetSocketAddress(InetAddress
+                .getLocalHost(), 2067);
+        DatagramPacket thePacket = new DatagramPacket(buf, 1, 1, theAddress);
+        assertEquals("Socket address not set correctly (1)", theAddress,
+                thePacket.getSocketAddress());
+        assertEquals("Socket address not set correctly (2)", theAddress,
+                new InetSocketAddress(thePacket.getAddress(), thePacket
+                        .getPort()));
+        assertEquals("Offset not set correctly", 1, thePacket.getOffset());
+    }
+
+    /**
+     * java.net.DatagramPacket#getSocketAddress()
+     */
+    public void test_getSocketAddress() throws IOException {
+        byte buf[] = new byte[1];
+        DatagramPacket thePacket = new DatagramPacket(buf, 1);
+
+        // Validate get returns the value we set
+        InetSocketAddress theAddress = new InetSocketAddress(InetAddress
+                .getLocalHost(), 0);
+        thePacket = new DatagramPacket(buf, 1);
+        thePacket.setSocketAddress(theAddress);
+        assertEquals("Socket address not set correctly (1)", theAddress,
+                thePacket.getSocketAddress());
+    }
+
+    /**
+     * java.net.DatagramPacket#setSocketAddress(java.net.SocketAddress)
+     */
+    public void test_setSocketAddressLjava_net_SocketAddress()
+            throws IOException {
+
+        @SuppressWarnings("serial")
+        class UnsupportedSocketAddress extends SocketAddress {
+
+            public UnsupportedSocketAddress() {
+            }
+        }
+
+        // Unsupported SocketAddress subclass
+        byte buf[] = new byte[1];
+        DatagramPacket thePacket = new DatagramPacket(buf, 1);
+        try {
+            thePacket.setSocketAddress(new UnsupportedSocketAddress());
+            fail("No exception when setting address using unsupported SocketAddress subclass");
+        } catch (IllegalArgumentException ex) {
+            // Expected
+        }
+
+        // Case were we try to pass in null
+        thePacket = new DatagramPacket(buf, 1);
+        try {
+            thePacket.setSocketAddress(null);
+            fail("No exception when setting address using null");
+        } catch (IllegalArgumentException ex) {
+            // Expected
+        }
+
+        // Now validate we can set it correctly
+        InetSocketAddress theAddress = new InetSocketAddress(InetAddress
+                .getLocalHost(), 2049);
+        thePacket = new DatagramPacket(buf, 1);
+        thePacket.setSocketAddress(theAddress);
+        assertEquals("Socket address not set correctly (1)", theAddress,
+                thePacket.getSocketAddress());
+        assertEquals("Socket address not set correctly (2)", theAddress,
+                new InetSocketAddress(thePacket.getAddress(), thePacket
+                        .getPort()));
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/DatagramSocketImplTest.java b/luni/src/test/java/tests/api/java/net/DatagramSocketImplTest.java
new file mode 100644
index 0000000..57cafbf
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/DatagramSocketImplTest.java
@@ -0,0 +1,152 @@
+/*
+ *  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.io.FileDescriptor;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocketImpl;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketAddress;
+import java.net.SocketException;
+
+public class DatagramSocketImplTest extends junit.framework.TestCase {
+    /**
+     * java.net.DatagramSocketImpl#DatagramSocketImpl()
+     */
+    public void test_Constructor() throws Exception {
+        // regression test for Harmony-1117
+        MockDatagramSocketImpl impl = new MockDatagramSocketImpl();
+        assertNull(impl.getFileDescriptor());
+    }
+
+
+    public void test_connect() throws Exception {
+        MockDatagramSocketImpl impl = new MockDatagramSocketImpl();
+        InetAddress localhost = InetAddress.getByName("localhost"); //$NON-NLS-1$
+        // connect do nothing, so will not throw exception
+        impl.test_connect(localhost, 0);
+        impl.test_connect(localhost, -1);
+        impl.test_connect(null, -1);
+        // disconnect
+        impl.test_disconnect();
+    }
+}
+
+class MockDatagramSocketImpl extends DatagramSocketImpl {
+
+    @Override
+    public FileDescriptor getFileDescriptor() {
+        return super.getFileDescriptor();
+    }
+
+    @Override
+    protected void bind(int port, InetAddress addr) throws SocketException {
+        // empty
+    }
+
+    @Override
+    protected void close() {
+        // empty
+    }
+
+    @Override
+    protected void create() throws SocketException {
+        // empty
+    }
+
+    public Object getOption(int optID) throws SocketException {
+        return null;
+    }
+
+    @Override
+    protected byte getTTL() throws IOException {
+        return 0;
+    }
+
+    @Override
+    protected int getTimeToLive() throws IOException {
+        return 0;
+    }
+
+    @Override
+    protected void join(InetAddress addr) throws IOException {
+        // empty
+    }
+
+    @Override
+    protected void joinGroup(SocketAddress addr, NetworkInterface netInterface)
+            throws IOException {
+        // empty
+    }
+
+    @Override
+    protected void leave(InetAddress addr) throws IOException {
+        // empty
+    }
+
+    @Override
+    protected void leaveGroup(SocketAddress addr, NetworkInterface netInterface)
+            throws IOException {
+        // empty
+    }
+
+    @Override
+    protected int peek(InetAddress sender) throws IOException {
+        return 0;
+    }
+
+    @Override
+    protected int peekData(DatagramPacket pack) throws IOException {
+        return 0;
+    }
+
+    @Override
+    protected void receive(DatagramPacket pack) throws IOException {
+        // empty
+    }
+
+    @Override
+    protected void send(DatagramPacket pack) throws IOException {
+        // empty
+
+    }
+
+    public void setOption(int optID, Object val) throws SocketException {
+        // empty
+    }
+
+    @Override
+    protected void setTTL(byte ttl) throws IOException {
+        // empty
+    }
+
+    @Override
+    protected void setTimeToLive(int ttl) throws IOException {
+        // empty
+    }
+
+    public void test_connect(InetAddress inetAddr, int port) throws SocketException {
+        super.connect(inetAddr, port);
+    }
+
+    public void test_disconnect() {
+        super.disconnect();
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/DatagramSocketTest.java b/luni/src/test/java/tests/api/java/net/DatagramSocketTest.java
new file mode 100644
index 0000000..74c9042
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/DatagramSocketTest.java
@@ -0,0 +1,1668 @@
+/*
+ *  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.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.BindException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.DatagramSocketImpl;
+import java.net.DatagramSocketImplFactory;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
+import java.net.PortUnreachableException;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.Date;
+
+import tests.support.Support_Configuration;
+import tests.support.Support_PortManager;
+
+public class DatagramSocketTest extends junit.framework.TestCase {
+
+    java.net.DatagramSocket ds;
+
+    java.net.DatagramPacket dp;
+
+    DatagramSocket sds = null;
+
+    String retval;
+
+    String testString = "Test String";
+
+    boolean interrupted;
+
+    class DatagramServer extends Thread {
+
+        public DatagramSocket ms;
+
+        boolean running = true;
+
+        public volatile byte[] rbuf = new byte[512];
+
+        volatile DatagramPacket rdp = null;
+
+        public void run() {
+            try {
+                while (running) {
+                    try {
+                        ms.receive(rdp);
+                        // echo the packet back
+                        ms.send(rdp);
+                    } catch (java.io.InterruptedIOException e) {
+                        Thread.yield();
+                    }
+                    ;
+                }
+                ;
+            } catch (java.io.IOException e) {
+                System.out.println("DatagramServer server failed: " + e);
+            } finally {
+                ms.close();
+            }
+        }
+
+        public void stopServer() {
+            running = false;
+        }
+
+        public DatagramServer(int aPort, InetAddress address)
+                throws IOException {
+            rbuf = new byte[512];
+            rbuf[0] = -1;
+            rdp = new DatagramPacket(rbuf, rbuf.length);
+            ms = new DatagramSocket(aPort, address);
+            ms.setSoTimeout(2000);
+        }
+    }
+
+    /**
+     * java.net.DatagramSocket#DatagramSocket()
+     */
+    public void test_Constructor() throws SocketException {
+        new DatagramSocket();
+    }
+
+    /**
+     * java.net.DatagramSocket#DatagramSocket(int)
+     */
+    public void test_ConstructorI() throws SocketException {
+        DatagramSocket ds = new DatagramSocket(0);
+        ds.close();
+    }
+
+    /**
+     * java.net.DatagramSocket#DatagramSocket(int, java.net.InetAddress)
+     */
+    public void test_ConstructorILjava_net_InetAddress() throws IOException {
+        DatagramSocket ds = new DatagramSocket(0, InetAddress.getLocalHost());
+        assertTrue("Created socket with incorrect port", ds.getLocalPort() != 0);
+        assertEquals("Created socket with incorrect address", InetAddress
+                .getLocalHost(), ds.getLocalAddress());
+    }
+
+    /**
+     * java.net.DatagramSocket#close()
+     */
+    public void test_close() throws UnknownHostException, SocketException {
+        DatagramSocket ds = new DatagramSocket(0);
+        DatagramPacket dp = new DatagramPacket("Test String".getBytes(), 11,
+                InetAddress.getLocalHost(), 0);
+        ds.close();
+        try {
+            ds.send(dp);
+            fail("Data sent after close");
+        } catch (IOException e) {
+            // Expected
+        }
+    }
+
+    public void test_connectLjava_net_InetAddressI() throws Exception {
+        DatagramSocket ds = new DatagramSocket();
+        InetAddress inetAddress = InetAddress.getLocalHost();
+        ds.connect(inetAddress, 0);
+        assertEquals("Incorrect InetAddress", inetAddress, ds.getInetAddress());
+        assertEquals("Incorrect Port", 0, ds.getPort());
+        ds.disconnect();
+
+        ds = new java.net.DatagramSocket();
+        inetAddress = InetAddress.getByName("FE80:0000:0000:0000:020D:60FF:FE0F:A776%4");
+        int portNumber = Support_PortManager.getNextPortForUDP();
+        ds.connect(inetAddress, portNumber);
+        assertTrue("Incorrect InetAddress", ds.getInetAddress().equals(inetAddress));
+        assertTrue("Incorrect Port", ds.getPort() == portNumber);
+        ds.disconnect();
+
+        // Create a connected datagram socket to test
+        // PlainDatagramSocketImpl.peek()
+        InetAddress localHost = InetAddress.getLocalHost();
+        ds = new DatagramSocket();
+        int port = ds.getLocalPort();
+        ds.connect(localHost, port);
+        DatagramPacket send = new DatagramPacket(new byte[10], 10, localHost,
+                port);
+        ds.send(send);
+        DatagramPacket receive = new DatagramPacket(new byte[20], 20);
+        ds.setSoTimeout(2000);
+        ds.receive(receive);
+        ds.close();
+        assertTrue("Wrong size: " + receive.getLength(),
+                receive.getLength() == 10);
+        assertTrue("Wrong receiver", receive.getAddress().equals(localHost));
+
+        class DatagramServer extends Thread {
+
+            public DatagramSocket ms;
+
+            boolean running = true;
+
+            public byte[] rbuf = new byte[512];
+
+            DatagramPacket rdp = null;
+
+            public void run() {
+                try {
+                    while (running) {
+                        try {
+                            ms.receive(rdp);
+                            // echo the packet back
+                            ms.send(rdp);
+                        } catch (java.io.InterruptedIOException e) {
+                            Thread.yield();
+                        }
+                        ;
+                    }
+                    ;
+                } catch (java.io.IOException e) {
+                    System.out.println("Multicast server failed: " + e);
+                } finally {
+                    ms.close();
+                }
+            }
+
+            public void stopServer() {
+                running = false;
+            }
+
+            public DatagramServer(int aPort, InetAddress address)
+                    throws java.io.IOException {
+                rbuf = new byte[512];
+                rbuf[0] = -1;
+                rdp = new DatagramPacket(rbuf, rbuf.length);
+                ms = new DatagramSocket(aPort, address);
+                ms.setSoTimeout(2000);
+            }
+        }
+
+        // validate that we get the PortUnreachable exception if we try to
+        // send a dgram to a server that is not running and then do a recv
+        try {
+            ds = new java.net.DatagramSocket();
+            inetAddress = InetAddress.getLocalHost();
+            portNumber = Support_PortManager.getNextPortForUDP();
+            ds.connect(inetAddress, portNumber);
+            send = new DatagramPacket(new byte[10], 10);
+            ds.send(send);
+            receive = new DatagramPacket(new byte[20], 20);
+            ds.setSoTimeout(10000);
+            ds.receive(receive);
+            ds.close();
+            fail("No PortUnreachableException when connected at native level on recv ");
+        } catch (PortUnreachableException e) {
+            // Expected
+        }
+
+        // validate that we can send/receive with datagram sockets connected at
+        // the native level
+        DatagramServer server = null;
+        int[] ports = Support_PortManager.getNextPortsForUDP(3);
+        int serverPortNumber = ports[0];
+
+        localHost = InetAddress.getLocalHost();
+        ds = new DatagramSocket(ports[1]);
+        DatagramSocket ds2 = new DatagramSocket(ports[2]);
+
+        server = new DatagramServer(serverPortNumber, localHost);
+        server.start();
+        Thread.sleep(1000);
+
+        port = ds.getLocalPort();
+        ds.connect(localHost, serverPortNumber);
+
+        final byte[] sendBytes = { 'T', 'e', 's', 't', 0 };
+        send = new DatagramPacket(sendBytes, sendBytes.length);
+        ds.send(send);
+        receive = new DatagramPacket(new byte[20], 20);
+        ds.setSoTimeout(2000);
+        ds.receive(receive);
+        ds.close();
+        assertTrue("Wrong size data received: " + receive.getLength(), receive
+                .getLength() == sendBytes.length);
+        assertTrue("Wrong data received"
+                + new String(receive.getData(), 0, receive.getLength()) + ":"
+                + new String(sendBytes), new String(receive.getData(), 0,
+                receive.getLength()).equals(new String(sendBytes)));
+        assertTrue("Wrong receiver:" + receive.getAddress() + ":" + localHost,
+                receive.getAddress().equals(localHost));
+
+        if (server != null) {
+            server.stopServer();
+        }
+
+        // validate that we can disconnect
+        try {
+            ds = new java.net.DatagramSocket();
+            inetAddress = InetAddress.getLocalHost();
+            portNumber = Support_PortManager.getNextPortForUDP();
+            ds.connect(inetAddress, portNumber);
+            ds.disconnect();
+            ds.close();
+        } catch (PortUnreachableException e) {
+            // Expected
+        }
+
+        // validate that once connected we cannot send to another address
+        try {
+            ds = new java.net.DatagramSocket();
+            inetAddress = InetAddress.getLocalHost();
+            portNumber = Support_PortManager.getNextPortForUDP();
+            ds.connect(inetAddress, portNumber);
+            send = new DatagramPacket(new byte[10], 10, inetAddress,
+                    portNumber + 1);
+            ds.send(send);
+            ds.close();
+            fail("No Exception when trying to send to a different address on a connected socket ");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        // validate that we can connect, then disconnect, then connect then
+        // send/recv
+        server = null;
+        ports = Support_PortManager.getNextPortsForUDP(3);
+        serverPortNumber = ports[0];
+
+        localHost = InetAddress.getLocalHost();
+        ds = new DatagramSocket(ports[1]);
+        ds2 = new DatagramSocket(ports[2]);
+
+        server = new DatagramServer(serverPortNumber, localHost);
+        server.start();
+        Thread.sleep(1000);
+
+        port = ds.getLocalPort();
+        ds.connect(localHost, serverPortNumber + 1);
+        ds.disconnect();
+        ds.connect(localHost, serverPortNumber);
+
+        send = new DatagramPacket(sendBytes, sendBytes.length);
+        ds.send(send);
+        receive = new DatagramPacket(new byte[20], 20);
+        ds.setSoTimeout(2000);
+        ds.receive(receive);
+        ds.close();
+        assertTrue("connect/disconnect/connect - Wrong size data received: "
+                + receive.getLength(), receive.getLength() == sendBytes.length);
+        assertTrue("connect/disconnect/connect - Wrong data received"
+                + new String(receive.getData(), 0, receive.getLength()) + ":"
+                + new String(sendBytes), new String(receive.getData(), 0,
+                receive.getLength()).equals(new String(sendBytes)));
+        assertTrue("connect/disconnect/connect - Wrong receiver:"
+                + receive.getAddress() + ":" + localHost, receive.getAddress()
+                .equals(localHost));
+
+        if (server != null) {
+            server.stopServer();
+        }
+
+        // validate that we can connect/disconnect then send/recv to any address
+        server = null;
+        ports = Support_PortManager.getNextPortsForUDP(3);
+        serverPortNumber = ports[0];
+
+        localHost = InetAddress.getLocalHost();
+        ds = new DatagramSocket(ports[1]);
+        ds2 = new DatagramSocket(ports[2]);
+
+        server = new DatagramServer(serverPortNumber, localHost);
+        server.start();
+        Thread.sleep(1000);
+
+        port = ds.getLocalPort();
+        ds.connect(localHost, serverPortNumber + 1);
+        ds.disconnect();
+
+        send = new DatagramPacket(sendBytes, sendBytes.length, localHost,
+                serverPortNumber);
+        ds.send(send);
+        receive = new DatagramPacket(new byte[20], 20);
+        ds.setSoTimeout(2000);
+        ds.receive(receive);
+        ds.close();
+        assertTrue("connect/disconnect - Wrong size data received: "
+                + receive.getLength(), receive.getLength() == sendBytes.length);
+        assertTrue("connect/disconnect - Wrong data received"
+                + new String(receive.getData(), 0, receive.getLength()) + ":"
+                + new String(sendBytes), new String(receive.getData(), 0,
+                receive.getLength()).equals(new String(sendBytes)));
+        assertTrue("connect/disconnect - Wrong receiver:"
+                + receive.getAddress() + ":" + localHost, receive.getAddress()
+                .equals(localHost));
+
+        if (server != null) {
+            server.stopServer();
+        }
+
+        // validate that we can connect on an allready connected socket and then
+        // send/recv
+        server = null;
+        ports = Support_PortManager.getNextPortsForUDP(3);
+        serverPortNumber = ports[0];
+
+        localHost = InetAddress.getLocalHost();
+        ds = new DatagramSocket(ports[1]);
+        ds2 = new DatagramSocket(ports[2]);
+
+        server = new DatagramServer(serverPortNumber, localHost);
+        server.start();
+        Thread.sleep(1000);
+
+        port = ds.getLocalPort();
+        ds.connect(localHost, serverPortNumber + 1);
+        ds.connect(localHost, serverPortNumber);
+
+        send = new DatagramPacket(sendBytes, sendBytes.length);
+        ds.send(send);
+        receive = new DatagramPacket(new byte[20], 20);
+        ds.setSoTimeout(2000);
+        ds.receive(receive);
+        ds.close();
+        assertTrue("connect/connect - Wrong size data received: "
+                + receive.getLength(), receive.getLength() == sendBytes.length);
+        assertTrue("connect/connect - Wrong data received"
+                + new String(receive.getData(), 0, receive.getLength()) + ":"
+                + new String(sendBytes), new String(receive.getData(), 0,
+                receive.getLength()).equals(new String(sendBytes)));
+        assertTrue("connect/connect - Wrong receiver:" + receive.getAddress()
+                + ":" + localHost, receive.getAddress().equals(localHost));
+
+        if (server != null) {
+            server.stopServer();
+        }
+
+        // test for when we fail to connect at the native level. Even though we
+        // fail at the native level there is no way to return an exception so
+        // there should be no exception
+        ds = new java.net.DatagramSocket();
+        byte[] addressBytes = { 0, 0, 0, 0 };
+        inetAddress = InetAddress.getByAddress(addressBytes);
+        portNumber = Support_PortManager.getNextPortForUDP();
+        ds.connect(inetAddress, portNumber);
+
+        if ("true".equals(System.getProperty("run.ipv6tests"))) {
+            System.out
+                    .println("Running test_connectLjava_net_InetAddressI(DatagramSocketTest) with IPv6 address");
+
+            ds = new java.net.DatagramSocket();
+            byte[] addressTestBytes = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                    0, 0, 0 };
+            inetAddress = InetAddress.getByAddress(addressTestBytes);
+            portNumber = Support_PortManager.getNextPortForUDP();
+            ds.connect(inetAddress, portNumber);
+        }
+    }
+
+    public void test_disconnect() throws Exception {
+        DatagramSocket ds = new DatagramSocket();
+        InetAddress inetAddress = InetAddress.getLocalHost();
+        ds.connect(inetAddress, 0);
+        ds.disconnect();
+        assertNull("Incorrect InetAddress", ds.getInetAddress());
+        assertEquals("Incorrect Port", -1, ds.getPort());
+
+        ds = new DatagramSocket();
+        inetAddress = InetAddress.getByName("FE80:0000:0000:0000:020D:60FF:FE0F:A776%4");
+        ds.connect(inetAddress, 0);
+        ds.disconnect();
+        assertNull("Incorrect InetAddress", ds.getInetAddress());
+        assertEquals("Incorrect Port", -1, ds.getPort());
+    }
+
+    /**
+     * java.net.DatagramSocket#getInetAddress()
+     */
+    public void test_getInetAddress() {
+        assertTrue("Used to test", true);
+    }
+
+    public void test_getLocalAddress() throws Exception {
+        // Test for method java.net.InetAddress
+        // java.net.DatagramSocket.getLocalAddress()
+        int portNumber = Support_PortManager.getNextPortForUDP();
+        InetAddress local = InetAddress.getLocalHost();
+        ds = new java.net.DatagramSocket(portNumber, local);
+        assertEquals(InetAddress.getByName(InetAddress.getLocalHost().getHostName()), ds.getLocalAddress());
+
+        // now check behavior when the ANY address is returned
+        DatagramSocket s = new DatagramSocket(0);
+        assertTrue("ANY address not IPv6: " + s.getLocalSocketAddress(), s.getLocalAddress() instanceof Inet6Address);
+        s.close();
+    }
+
+    /**
+     * java.net.DatagramSocket#getLocalPort()
+     */
+    public void test_getLocalPort() throws SocketException {
+        DatagramSocket ds = new DatagramSocket();
+        assertTrue("Returned incorrect port", ds.getLocalPort() != 0);
+    }
+
+    /**
+     * java.net.DatagramSocket#getPort()
+     */
+    public void test_getPort() throws IOException {
+        DatagramSocket theSocket = new DatagramSocket();
+        assertEquals("Expected -1 for remote port as not connected", -1,
+                theSocket.getPort());
+
+        // Now connect the socket and validate that we get the right port
+        int portNumber = 49152; // any valid port, even if it is unreachable
+        theSocket.connect(InetAddress.getLocalHost(), portNumber);
+        assertEquals("getPort returned wrong value", portNumber, theSocket
+                .getPort());
+    }
+
+    public void test_getReceiveBufferSize() throws Exception {
+        DatagramSocket ds = new DatagramSocket();
+        ds.setReceiveBufferSize(130);
+        assertTrue("Incorrect buffer size", ds.getReceiveBufferSize() >= 130);
+    }
+
+    public void test_getSendBufferSize() throws Exception {
+        int portNumber = Support_PortManager.getNextPortForUDP();
+        ds = new java.net.DatagramSocket(portNumber);
+        ds.setSendBufferSize(134);
+        assertTrue("Incorrect buffer size", ds.getSendBufferSize() >= 134);
+    }
+
+    public void test_getSoTimeout() throws Exception {
+        DatagramSocket ds = new DatagramSocket();
+        ds.setSoTimeout(100);
+        assertEquals("Returned incorrect timeout", 100, ds.getSoTimeout());
+    }
+
+    public void test_receiveLjava_net_DatagramPacket() throws IOException {
+        // Test for method void
+        // java.net.DatagramSocket.receive(java.net.DatagramPacket)
+
+        receive_oversize_java_net_DatagramPacket();
+        final int[] ports = Support_PortManager.getNextPortsForUDP(2);
+        final int portNumber = ports[0];
+
+        class TestDGRcv implements Runnable {
+            public void run() {
+                InetAddress localHost = null;
+                try {
+                    localHost = InetAddress.getLocalHost();
+                    Thread.sleep(1000);
+                    DatagramSocket sds = new DatagramSocket(ports[1]);
+                    DatagramPacket rdp = new DatagramPacket("Test String"
+                            .getBytes(), 11, localHost, portNumber);
+                    sds.send(rdp);
+                    sds.close();
+                } catch (Exception e) {
+                    System.err.println("host " + localHost + " port "
+                            + portNumber + " failed to send data: " + e);
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        try {
+            new Thread(new TestDGRcv(), "DGSender").start();
+            ds = new java.net.DatagramSocket(portNumber);
+            ds.setSoTimeout(6000);
+            byte rbuf[] = new byte[1000];
+            DatagramPacket rdp = new DatagramPacket(rbuf, rbuf.length);
+
+            ds.receive(rdp);
+            ds.close();
+            assertTrue("Send/Receive failed to return correct data: "
+                    + new String(rbuf, 0, 11), new String(rbuf, 0, 11)
+                    .equals("Test String"));
+        } finally {
+            ds.close();
+        }
+
+        try {
+            interrupted = false;
+            final DatagramSocket ds = new DatagramSocket();
+            ds.setSoTimeout(12000);
+            Runnable runnable = new Runnable() {
+                public void run() {
+                    try {
+                        ds.receive(new DatagramPacket(new byte[1], 1));
+                    } catch (InterruptedIOException e) {
+                        interrupted = true;
+                    } catch (IOException e) {
+                    }
+                }
+            };
+            Thread thread = new Thread(runnable, "DatagramSocket.receive1");
+            thread.start();
+            try {
+                do {
+                    Thread.sleep(500);
+                } while (!thread.isAlive());
+            } catch (InterruptedException e) {
+            }
+            ds.close();
+            int c = 0;
+            do {
+                try {
+                    Thread.sleep(500);
+                } catch (InterruptedException e) {
+                }
+                if (interrupted) {
+                    fail("received interrupt");
+                }
+                if (++c > 4) {
+                    fail("read call did not exit");
+                }
+            } while (thread.isAlive());
+
+            interrupted = false;
+            int[] ports1 = Support_PortManager.getNextPortsForUDP(2);
+            final int portNum = ports[0];
+            final DatagramSocket ds2 = new DatagramSocket(ports[1]);
+            ds2.setSoTimeout(12000);
+            Runnable runnable2 = new Runnable() {
+                public void run() {
+                    try {
+                        ds2.receive(new DatagramPacket(new byte[1], 1,
+                                InetAddress.getLocalHost(), portNum));
+                    } catch (InterruptedIOException e) {
+                        interrupted = true;
+                    } catch (IOException e) {
+                    }
+                }
+            };
+            Thread thread2 = new Thread(runnable2, "DatagramSocket.receive2");
+            thread2.start();
+            try {
+                do {
+                    Thread.sleep(500);
+                } while (!thread2.isAlive());
+            } catch (InterruptedException e) {
+            }
+            ds2.close();
+            int c2 = 0;
+            do {
+                try {
+                    Thread.sleep(500);
+                } catch (InterruptedException e) {
+                }
+                if (interrupted) {
+                    fail("receive2 was interrupted");
+                }
+                if (++c2 > 4) {
+                    fail("read2 call did not exit");
+                }
+            } while (thread2.isAlive());
+
+            interrupted = false;
+            DatagramSocket ds3 = new DatagramSocket();
+            ds3.setSoTimeout(500);
+            Date start = new Date();
+            try {
+                ds3.receive(new DatagramPacket(new byte[1], 1));
+            } catch (InterruptedIOException e) {
+                interrupted = true;
+            }
+            ds3.close();
+            assertTrue("receive not interrupted", interrupted);
+            int delay = (int) (new Date().getTime() - start.getTime());
+            assertTrue("timeout too soon: " + delay, delay >= 490);
+        } catch (IOException e) {
+            fail("Unexpected IOException : " + e.getMessage());
+        }
+
+    }
+
+    /**
+     * Tests receive() method in various combinations with
+     * DatagramPacket#getLength() and DatagramPacket#getLength(). This is
+     * regression test for HARMONY-2276.
+     *
+     * @throws IOException
+     *             if some I/O error occured
+     */
+    // public void test2276() throws IOException {
+    // final String ADDRESS = "239.255.2.3";
+    // final int PORT = Support_PortManager.getNextPortForUDP();
+    // InetAddress group = InetAddress.getByName(ADDRESS);
+    // MulticastSocket socket = new MulticastSocket(PORT);
+    // byte[] recvData = new byte[100];
+    // DatagramPacket recvDatagram = new DatagramPacket(recvData,
+    // recvData.length);
+    //
+    // String message = "Hello, world!";
+    // String longerMessage = message + " again.";
+    // String veryLongMessage = longerMessage + " Forever!";
+    //
+    // socket.joinGroup(group);
+    // socket.setSoTimeout(5000); // prevent eternal block in
+    // // socket.receive()
+    // // send & recieve packet
+    // byte[] sendData = message.getBytes();
+    // DatagramPacket sendDatagram = new DatagramPacket(sendData, 0,
+    // sendData.length, group, PORT);
+    // socket.send(sendDatagram);
+    // socket.receive(recvDatagram);
+    // String recvMessage = new String(recvData, 0, recvDatagram.getLength());
+    // assertEquals(message, recvMessage);
+    //
+    // // send & receive longer packet
+    // sendData = longerMessage.getBytes();
+    // sendDatagram = new DatagramPacket(sendData, 0, sendData.length,
+    // group, PORT);
+    // socket.send(sendDatagram);
+    // socket.receive(recvDatagram);
+    // recvMessage = new String(recvData, 0, recvDatagram.getLength());
+    // assertEquals(longerMessage, recvMessage);
+    //
+    // // tricky case, added to test compatibility with RI;
+    // // depends on the previous test case
+    // sendData = veryLongMessage.getBytes();
+    // sendDatagram = new DatagramPacket(sendData, 0, sendData.length, group,
+    // PORT);
+    // socket.send(sendDatagram);
+    // recvDatagram.setLength(recvDatagram.getLength()); // !!!
+    // socket.receive(recvDatagram);
+    // recvMessage = new String(recvData, 0, recvDatagram.getLength());
+    // assertEquals(longerMessage, recvMessage);
+    //
+    // // tests if received packet is truncated after length was set to 1
+    // sendData = message.getBytes();
+    // sendDatagram = new DatagramPacket(sendData, 0, sendData.length,
+    // group, PORT);
+    // socket.send(sendDatagram);
+    // recvDatagram.setLength(1);
+    // socket.receive(recvDatagram);
+    // assertEquals("Received message was not truncated", 1,
+    // recvDatagram.getLength());
+    // assertSame("Received message is invalid", sendData[0], recvData[0]);
+    //
+    // socket.leaveGroup(group);
+    // socket.close();
+    // }
+
+    /**
+     * java.net.DatagramSocket#send(java.net.DatagramPacket)
+     */
+    public void test_sendLjava_net_DatagramPacket() throws Exception {
+        // Test for method void
+        // java.net.DatagramSocket.send(java.net.DatagramPacket)
+        int[] ports = Support_PortManager.getNextPortsForUDP(2);
+        final int portNumber = ports[0];
+
+        class TestDGSend implements Runnable {
+            Thread pThread;
+
+            public TestDGSend(Thread t) {
+                pThread = t;
+            }
+
+            public void run() {
+                try {
+                    byte[] rbuf = new byte[1000];
+
+                    sds = new DatagramSocket(portNumber);
+                    DatagramPacket sdp = new DatagramPacket(rbuf, rbuf.length);
+                    sds.setSoTimeout(6000);
+                    sds.receive(sdp);
+                    retval = new String(rbuf, 0, testString.length());
+                    pThread.interrupt();
+                } catch (java.io.InterruptedIOException e) {
+                    System.out.println("Recv operation timed out");
+                    pThread.interrupt();
+                    ds.close();
+                    return;
+                } catch (Exception e) {
+                    System.out
+                            .println("Failed to establish Dgram server: " + e);
+                }
+            }
+        }
+        try {
+            new Thread(new TestDGSend(Thread.currentThread()), "DGServer")
+                    .start();
+            ds = new java.net.DatagramSocket(ports[1]);
+            dp = new DatagramPacket(testString.getBytes(), testString.length(),
+                    InetAddress.getLocalHost(), portNumber);
+            // Wait to allow send to occur
+            try {
+                Thread.sleep(500);
+                ds.send(dp);
+                Thread.sleep(5000);
+            } catch (InterruptedException e) {
+                ds.close();
+                assertTrue("Incorrect data sent: " + retval, retval
+                        .equals(testString));
+            }
+        } finally {
+            ds.close();
+        }
+        // Regression for HARMONY-1118
+        class testDatagramSocket extends DatagramSocket {
+            public testDatagramSocket(DatagramSocketImpl impl) {
+                super(impl);
+            }
+        }
+        class testDatagramSocketImpl extends DatagramSocketImpl {
+            protected void create() throws SocketException {
+            }
+
+            protected void bind(int arg0, InetAddress arg1)
+                    throws SocketException {
+            }
+
+            protected void send(DatagramPacket arg0) throws IOException {
+            }
+
+            protected int peek(InetAddress arg0) throws IOException {
+                return 0;
+            }
+
+            protected int peekData(DatagramPacket arg0) throws IOException {
+                return 0;
+            }
+
+            protected void receive(DatagramPacket arg0) throws IOException {
+            }
+
+            protected void setTTL(byte arg0) throws IOException {
+            }
+
+            protected byte getTTL() throws IOException {
+                return 0;
+            }
+
+            protected void setTimeToLive(int arg0) throws IOException {
+            }
+
+            protected int getTimeToLive() throws IOException {
+                return 0;
+            }
+
+            protected void join(InetAddress arg0) throws IOException {
+            }
+
+            protected void leave(InetAddress arg0) throws IOException {
+            }
+
+            protected void joinGroup(SocketAddress arg0, NetworkInterface arg1)
+                    throws IOException {
+            }
+
+            protected void leaveGroup(SocketAddress arg0, NetworkInterface arg1)
+                    throws IOException {
+            }
+
+            protected void close() {
+            }
+
+            public void setOption(int arg0, Object arg1) throws SocketException {
+            }
+
+            public Object getOption(int arg0) throws SocketException {
+                return null;
+            }
+        }
+
+        // Regression test for Harmony-2938
+        InetAddress i = InetAddress.getByName("127.0.0.1");
+        DatagramSocket d = new DatagramSocket(0, i);
+        try {
+            d.send(new DatagramPacket(new byte[] { 1 }, 1));
+            fail("should throw NPE.");
+        } catch (NullPointerException e) {
+            // expected;
+        } finally {
+            d.close();
+        }
+
+        // Regression test for Harmony-6413
+        InetSocketAddress addr = InetSocketAddress.createUnresolved(
+                "localhost", 0);
+        try {
+            DatagramPacket dp = new DatagramPacket(new byte[272], 3, addr);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    /**
+     * If the InetAddress of DatagramPacket is null, DatagramSocket.send(DatagramPacket)
+     * should throw NullPointer Exception.
+     *
+     * java.net.DatagramSocket#send(java.net.DatagramPacket)
+     */
+    public void test_sendLjava_net_DatagramPacket2() throws IOException {
+        int udp_port = 20000;
+        int send_port = 23000;
+        DatagramSocket udpSocket = new DatagramSocket(udp_port);
+        byte[] data = { 65 };
+        DatagramPacket sendPacket = new DatagramPacket(data, data.length, null, send_port);
+        try {
+            udpSocket.send(sendPacket);
+            fail("Should throw SocketException");
+        } catch (NullPointerException e) {
+            // Expected
+        } finally {
+            udpSocket.close();
+        }
+
+    }
+
+    public void test_setSendBufferSizeI() throws Exception {
+        int portNumber = Support_PortManager.getNextPortForUDP();
+        ds = new java.net.DatagramSocket(portNumber);
+        ds.setSendBufferSize(134);
+        assertTrue("Incorrect buffer size", ds.getSendBufferSize() >= 134);
+    }
+
+    public void test_setReceiveBufferSizeI() throws Exception {
+        int portNumber = Support_PortManager.getNextPortForUDP();
+        ds = new java.net.DatagramSocket(portNumber);
+        ds.setReceiveBufferSize(130);
+        assertTrue("Incorrect buffer size", ds.getReceiveBufferSize() >= 130);
+    }
+
+    public void test_setSoTimeoutI() throws Exception {
+        DatagramSocket ds = new DatagramSocket();
+        ds.setSoTimeout(100);
+        assertTrue("Set incorrect timeout", ds.getSoTimeout() >= 100);
+    }
+
+    public void test_ConstructorLjava_net_DatagramSocketImpl() {
+        class SimpleTestDatagramSocket extends DatagramSocket {
+            public SimpleTestDatagramSocket(DatagramSocketImpl impl) {
+                super(impl);
+            }
+        }
+
+        try {
+            new SimpleTestDatagramSocket((DatagramSocketImpl) null);
+            fail("exception expected");
+        } catch (NullPointerException ex) {
+            // expected
+        }
+    }
+
+    /**
+     * java.net.DatagramSocket#DatagramSocket(java.net.SocketAddress)
+     */
+    public void test_ConstructorLjava_net_SocketAddress() throws Exception {
+        class UnsupportedSocketAddress extends SocketAddress {
+
+            public UnsupportedSocketAddress() {
+            }
+        }
+
+        DatagramSocket ds = new DatagramSocket(new InetSocketAddress(
+                InetAddress.getLocalHost(), 0));
+        assertTrue(ds.getBroadcast());
+        assertTrue("Created socket with incorrect port", ds.getLocalPort() != 0);
+        assertEquals("Created socket with incorrect address", InetAddress
+                .getLocalHost(), ds.getLocalAddress());
+
+        try {
+            ds = new java.net.DatagramSocket(new UnsupportedSocketAddress());
+            fail("No exception when constructing datagramSocket with unsupported SocketAddress type");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        // regression for HARMONY-894
+        ds = new DatagramSocket((SocketAddress) null);
+        assertTrue(ds.getBroadcast());
+    }
+
+    /**
+     * java.net.DatagramSocket#bind(java.net.SocketAddress)
+     */
+    public void test_bindLjava_net_SocketAddress() throws Exception {
+        class mySocketAddress extends SocketAddress {
+
+            public mySocketAddress() {
+            }
+        }
+
+        DatagramServer server = null;
+
+        // now create a socket that is not bound and then bind it
+        int[] ports = Support_PortManager.getNextPortsForUDP(3);
+        int portNumber = ports[0];
+        int serverPortNumber = ports[1];
+        DatagramSocket theSocket = new DatagramSocket(new InetSocketAddress(
+                InetAddress.getLocalHost(), portNumber));
+
+        // validate that the localSocketAddress reflects the address we
+        // bound to
+        assertTrue(
+                "Local address not correct after bind:"
+                        + theSocket.getLocalSocketAddress().toString()
+                        + "Expected: "
+                        + (new InetSocketAddress(InetAddress.getLocalHost(),
+                        portNumber)).toString(), theSocket
+                .getLocalSocketAddress().equals(
+                        new InetSocketAddress(InetAddress
+                                .getLocalHost(), portNumber)));
+
+        // now make sure that datagrams sent from this socket appear to come
+        // from the address we bound to
+        InetAddress localHost = InetAddress.getLocalHost();
+        portNumber = ports[2];
+        DatagramSocket ds = new DatagramSocket(null);
+        ds.bind(new InetSocketAddress(localHost, portNumber));
+
+        server = new DatagramServer(serverPortNumber, localHost);
+        server.start();
+        Thread.sleep(1000);
+
+        ds.connect(new InetSocketAddress(localHost, serverPortNumber));
+
+        byte[] sendBytes = { 'T', 'e', 's', 't', 0 };
+        DatagramPacket send = new DatagramPacket(sendBytes, sendBytes.length);
+        ds.send(send);
+        Thread.sleep(1000);
+        ds.close();
+        assertTrue("Address in packet sent does not match address bound to:"
+                + server.rdp.getAddress() + ":" + server.rdp.getPort() + ":"
+                + localHost + ":" + portNumber, (server.rdp.getAddress()
+                .equals(localHost))
+                && (server.rdp.getPort() == portNumber));
+
+        // validate if we pass in null that it picks an address for us and
+        // all is ok
+        theSocket = new DatagramSocket(null);
+        theSocket.bind(null);
+        assertNotNull("Bind with null did not work", theSocket
+                .getLocalSocketAddress());
+        theSocket.close();
+
+        // now check the error conditions
+
+        // Address we cannot bind to
+        theSocket = new DatagramSocket(null);
+        try {
+            theSocket.bind(new InetSocketAddress(InetAddress
+                    .getByAddress(Support_Configuration.nonLocalAddressBytes),
+                    Support_PortManager.getNextPortForUDP()));
+            fail("No exception when binding to bad address");
+        } catch (SocketException ex) {
+        }
+        theSocket.close();
+
+        // Address that we have allready bound to
+        ports = Support_PortManager.getNextPortsForUDP(2);
+        theSocket = new DatagramSocket(null);
+        DatagramSocket theSocket2 = new DatagramSocket(ports[0]);
+        try {
+            InetSocketAddress theAddress = new InetSocketAddress(InetAddress
+                    .getLocalHost(), ports[1]);
+            theSocket.bind(theAddress);
+            theSocket2.bind(theAddress);
+            fail("No exception binding to address that is not available");
+        } catch (SocketException ex) {
+        }
+        theSocket.close();
+        theSocket2.close();
+
+        // unsupported SocketAddress subclass
+        theSocket = new DatagramSocket(null);
+        try {
+            theSocket.bind(new mySocketAddress());
+            fail("No exception when binding using unsupported SocketAddress subclass");
+        } catch (IllegalArgumentException ex) {
+        }
+        theSocket.close();
+
+        if (server != null) {
+            server.stopServer();
+        }
+    }
+
+    /**
+     * java.net.DatagramSocket#connect(java.net.SocketAddress)
+     */
+    public void test_connectLjava_net_SocketAddress() throws Exception {
+
+        // validate that we get the PortUnreachable exception if we try to
+        // send a dgram to a server that is not running and then do a recv
+        try {
+            ds = new java.net.DatagramSocket();
+            InetAddress inetAddress = InetAddress.getLocalHost();
+            int portNumber = Support_PortManager.getNextPortForUDP();
+            ds.connect(new InetSocketAddress(inetAddress, portNumber));
+            DatagramPacket send = new DatagramPacket(new byte[10], 10);
+            ds.send(send);
+            DatagramPacket receive = new DatagramPacket(new byte[20], 20);
+            ds.setSoTimeout(10000);
+            ds.receive(receive);
+            ds.close();
+            fail("No PortUnreachableException when connected at native level on recv ");
+        } catch (PortUnreachableException e) {
+            // Expected
+        }
+
+        // validate that we can send/receive with datagram sockets connected at
+        // the native level
+        DatagramServer server = null;
+        int[] ports = Support_PortManager.getNextPortsForUDP(3);
+        int serverPortNumber = ports[0];
+
+        InetAddress localHost = InetAddress.getLocalHost();
+        DatagramSocket ds = new DatagramSocket(ports[1]);
+        DatagramSocket ds2 = new DatagramSocket(ports[2]);
+
+        server = new DatagramServer(serverPortNumber, localHost);
+        server.start();
+        Thread.sleep(1000);
+
+        int port = ds.getLocalPort();
+        ds.connect(new InetSocketAddress(localHost, serverPortNumber));
+
+        final byte[] sendBytes = { 'T', 'e', 's', 't', 0 };
+        DatagramPacket send = new DatagramPacket(sendBytes, sendBytes.length);
+        ds.send(send);
+        DatagramPacket receive = new DatagramPacket(new byte[20], 20);
+        ds.setSoTimeout(2000);
+        ds.receive(receive);
+        ds.close();
+        assertTrue("Wrong size data received: " + receive.getLength(), receive
+                .getLength() == sendBytes.length);
+        assertTrue("Wrong data received"
+                + new String(receive.getData(), 0, receive.getLength()) + ":"
+                + new String(sendBytes), new String(receive.getData(), 0,
+                receive.getLength()).equals(new String(sendBytes)));
+        assertTrue("Wrong receiver:" + receive.getAddress() + ":" + localHost,
+                receive.getAddress().equals(localHost));
+
+        if (server != null) {
+            server.stopServer();
+        }
+
+        // validate that we can disconnect
+        try {
+            ds = new java.net.DatagramSocket();
+            InetAddress inetAddress = InetAddress.getLocalHost();
+            int portNumber = Support_PortManager.getNextPortForUDP();
+            ds.connect(new InetSocketAddress(inetAddress, portNumber));
+            ds.disconnect();
+            ds.close();
+        } catch (PortUnreachableException e) {
+            // Expected
+        }
+
+        // validate that once connected we cannot send to another address
+        try {
+            ds = new java.net.DatagramSocket();
+            InetAddress inetAddress = InetAddress.getLocalHost();
+            int portNumber = Support_PortManager.getNextPortForUDP();
+            ds.connect(new InetSocketAddress(inetAddress, portNumber));
+            DatagramPacket senddp = new DatagramPacket(new byte[10], 10,
+                    inetAddress, portNumber + 1);
+            ds.send(senddp);
+            ds.close();
+            fail("No Exception when trying to send to a different address on a connected socket ");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        // validate that we can connect, then disconnect, then connect then
+        // send/recv
+        server = null;
+        ports = Support_PortManager.getNextPortsForUDP(3);
+        serverPortNumber = ports[0];
+
+        localHost = InetAddress.getLocalHost();
+        ds = new DatagramSocket(ports[1]);
+        ds2 = new DatagramSocket(ports[2]);
+
+        server = new DatagramServer(serverPortNumber, localHost);
+        server.start();
+        Thread.sleep(1000);
+
+        port = ds.getLocalPort();
+        ds.connect(new InetSocketAddress(localHost, serverPortNumber + 1));
+        ds.disconnect();
+        ds.connect(new InetSocketAddress(localHost, serverPortNumber));
+
+        send = new DatagramPacket(sendBytes, sendBytes.length);
+        ds.send(send);
+        receive = new DatagramPacket(new byte[20], 20);
+        ds.setSoTimeout(2000);
+        ds.receive(receive);
+        ds.close();
+        assertTrue("connect/disconnect/connect - Wrong size data received: "
+                + receive.getLength(), receive.getLength() == sendBytes.length);
+        assertTrue("connect/disconnect/connect - Wrong data received"
+                + new String(receive.getData(), 0, receive.getLength()) + ":"
+                + new String(sendBytes), new String(receive.getData(), 0,
+                receive.getLength()).equals(new String(sendBytes)));
+        assertTrue("connect/disconnect/connect - Wrong receiver:"
+                + receive.getAddress() + ":" + localHost, receive.getAddress()
+                .equals(localHost));
+
+        if (server != null) {
+            server.stopServer();
+        }
+
+        // validate that we can connect/disconnect then send/recv to any address
+        server = null;
+        ports = Support_PortManager.getNextPortsForUDP(3);
+        serverPortNumber = ports[0];
+
+        localHost = InetAddress.getLocalHost();
+        ds = new DatagramSocket(ports[1]);
+        ds2 = new DatagramSocket(ports[2]);
+
+        server = new DatagramServer(serverPortNumber, localHost);
+        server.start();
+        Thread.sleep(1000);
+
+        port = ds.getLocalPort();
+        ds.connect(new InetSocketAddress(localHost, serverPortNumber + 1));
+        ds.disconnect();
+
+        send = new DatagramPacket(sendBytes, sendBytes.length, localHost,
+                serverPortNumber);
+        ds.send(send);
+        receive = new DatagramPacket(new byte[20], 20);
+        ds.setSoTimeout(2000);
+        ds.receive(receive);
+        ds.close();
+        assertTrue("connect/disconnect - Wrong size data received: "
+                + receive.getLength(), receive.getLength() == sendBytes.length);
+        assertTrue("connect/disconnect - Wrong data received"
+                + new String(receive.getData(), 0, receive.getLength()) + ":"
+                + new String(sendBytes), new String(receive.getData(), 0,
+                receive.getLength()).equals(new String(sendBytes)));
+        assertTrue("connect/disconnect - Wrong receiver:"
+                + receive.getAddress() + ":" + localHost, receive.getAddress()
+                .equals(localHost));
+
+        if (server != null) {
+            server.stopServer();
+        }
+
+        // validate that we can connect on an allready connected socket and then
+        // send/recv
+        server = null;
+        ports = Support_PortManager.getNextPortsForUDP(3);
+        serverPortNumber = ports[0];
+
+        localHost = InetAddress.getLocalHost();
+        ds = new DatagramSocket(ports[1]);
+        ds2 = new DatagramSocket(ports[2]);
+
+        server = new DatagramServer(serverPortNumber, localHost);
+        server.start();
+        Thread.sleep(1000);
+
+        port = ds.getLocalPort();
+        ds.connect(new InetSocketAddress(localHost, serverPortNumber + 1));
+        ds.connect(new InetSocketAddress(localHost, serverPortNumber));
+
+        byte[] sendTestBytes = { 'T', 'e', 's', 't', 0 };
+        send = new DatagramPacket(sendTestBytes, sendTestBytes.length);
+        ds.send(send);
+        DatagramPacket receivedp = new DatagramPacket(new byte[20], 20);
+        ds.setSoTimeout(2000);
+        ds.receive(receivedp);
+        ds.close();
+        assertTrue("connect/connect - Wrong size data received: "
+                + receivedp.getLength(),
+                receivedp.getLength() == sendTestBytes.length);
+        assertTrue("connect/connect - Wrong data received"
+                + new String(receivedp.getData(), 0, receivedp.getLength())
+                + ":" + new String(sendTestBytes), new String(receivedp
+                .getData(), 0, receivedp.getLength()).equals(new String(
+                sendTestBytes)));
+        assertTrue("connect/connect - Wrong receiver:" + receivedp.getAddress()
+                + ":" + localHost, receivedp.getAddress().equals(localHost));
+
+        if (server != null) {
+            server.stopServer();
+        }
+
+        // test for when we fail to connect at the native level. It seems to
+        // fail for the any address so we use this. Now to be compatible we
+        // don't throw the exception but eat it and then act as if we were
+        // connected at the Java level.
+        try {
+            ds = new java.net.DatagramSocket();
+            byte[] addressBytes = { 0, 0, 0, 0 };
+            InetAddress inetAddress = InetAddress.getByAddress(addressBytes);
+            int portNumber = Support_PortManager.getNextPortForUDP();
+            InetAddress localHostIA = InetAddress.getLocalHost();
+            ds.connect(new InetSocketAddress(inetAddress, portNumber));
+            assertTrue("Is not connected after connect to inaddr any", ds
+                    .isConnected());
+            byte[] sendBytesArray = { 'T', 'e', 's', 't', 0 };
+            DatagramPacket senddp = new DatagramPacket(sendBytesArray,
+                    sendBytesArray.length, localHostIA, portNumber);
+            ds.send(senddp);
+            fail("No exception when trying to connect at native level with bad address (exception from send)  ");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.net.DatagramSocket#isBound()
+     */
+    public void test_isBound() throws Exception {
+        InetAddress addr = InetAddress.getLocalHost();
+        int[] ports = Support_PortManager.getNextPortsForUDP(3);
+        int port = ports[0];
+
+        DatagramSocket theSocket = new DatagramSocket(ports[1]);
+        assertTrue("Socket indicated  not bound when it should be (1)",
+                theSocket.isBound());
+        theSocket.close();
+
+        theSocket = new DatagramSocket(new InetSocketAddress(addr, port));
+        assertTrue("Socket indicated  not bound when it should be (2)",
+                theSocket.isBound());
+        theSocket.close();
+
+        theSocket = new DatagramSocket(null);
+        assertFalse("Socket indicated  bound when it should not be (1)",
+                theSocket.isBound());
+        theSocket.close();
+
+        // connect causes implicit bind
+        theSocket = new DatagramSocket(null);
+        theSocket.connect(new InetSocketAddress(addr, port));
+        assertTrue("Socket indicated not bound when it should be (3)",
+                theSocket.isBound());
+        theSocket.close();
+
+        // now test when we bind explicitely
+        InetSocketAddress theLocalAddress = new InetSocketAddress(InetAddress
+                .getLocalHost(), ports[2]);
+        theSocket = new DatagramSocket(null);
+        assertFalse("Socket indicated bound when it should not be (2)",
+                theSocket.isBound());
+        theSocket.bind(theLocalAddress);
+        assertTrue("Socket indicated not bound when it should be (4)",
+                theSocket.isBound());
+        theSocket.close();
+        assertTrue("Socket indicated not bound when it should be (5)",
+                theSocket.isBound());
+    }
+
+    /**
+     * java.net.DatagramSocket#isConnected()
+     */
+    public void test_isConnected() throws Exception {
+        InetAddress addr = InetAddress.getLocalHost();
+        int[] ports = Support_PortManager.getNextPortsForUDP(4);
+        int port = ports[0];
+
+        // base test
+        DatagramSocket theSocket = new DatagramSocket(ports[1]);
+        assertFalse("Socket indicated connected when it should not be",
+                theSocket.isConnected());
+        theSocket.connect(new InetSocketAddress(addr, port));
+        assertTrue("Socket indicated  not connected when it should be",
+                theSocket.isConnected());
+
+        // reconnect the socket and make sure we get the right answer
+        theSocket.connect(new InetSocketAddress(addr, ports[2]));
+        assertTrue("Socket indicated  not connected when it should be",
+                theSocket.isConnected());
+
+        // now disconnect the socket and make sure we get the right answer
+        theSocket.disconnect();
+        assertFalse("Socket indicated connected when it should not be",
+                theSocket.isConnected());
+        theSocket.close();
+
+        // now check behavior when socket is closed when connected
+        theSocket = new DatagramSocket(ports[3]);
+        theSocket.connect(new InetSocketAddress(addr, port));
+        theSocket.close();
+        assertTrue("Socket indicated  not connected when it should be",
+                theSocket.isConnected());
+    }
+
+    /**
+     * java.net.DatagramSocket#getRemoteSocketAddress()
+     */
+    public void test_getRemoteSocketAddress() throws Exception {
+        int[] ports = Support_PortManager.getNextPortsForUDP(3);
+        int sport = ports[0];
+        int portNumber = ports[1];
+        DatagramSocket s = new DatagramSocket(new InetSocketAddress(InetAddress
+                .getLocalHost(), portNumber));
+        s.connect(new InetSocketAddress(InetAddress.getLocalHost(), sport));
+        assertTrue("Returned incorrect InetSocketAddress(1):"
+                + s.getLocalSocketAddress().toString(),
+                s.getRemoteSocketAddress()
+                        .equals(
+                                new InetSocketAddress(InetAddress
+                                        .getLocalHost(), sport)));
+        s.close();
+
+        // now create one that is not connected and validate that we get the
+        // right answer
+        DatagramSocket theSocket = new DatagramSocket(null);
+        portNumber = ports[2];
+        theSocket.bind(new InetSocketAddress(InetAddress.getLocalHost(),
+                portNumber));
+        assertNull("Returned incorrect InetSocketAddress -unconnected socket:"
+                + "Expected: NULL", theSocket.getRemoteSocketAddress());
+
+        // now connect and validate we get the right answer
+        theSocket.connect(new InetSocketAddress(InetAddress.getLocalHost(),
+                sport));
+        assertTrue("Returned incorrect InetSocketAddress(2):"
+                + theSocket.getRemoteSocketAddress().toString(),
+                theSocket.getRemoteSocketAddress()
+                        .equals(
+                                new InetSocketAddress(InetAddress
+                                        .getLocalHost(), sport)));
+        theSocket.close();
+    }
+
+    public void test_getLocalSocketAddress_late_bind() throws Exception {
+        // An unbound socket should return null as its local address.
+        DatagramSocket theSocket = new DatagramSocket((SocketAddress) null);
+        assertNull(theSocket.getLocalSocketAddress());
+
+        // now bind the socket and make sure we get the right answer
+        int portNumber = Support_PortManager.getNextPortForUDP();
+        InetSocketAddress localAddress = new InetSocketAddress(InetAddress.getLocalHost(), portNumber);
+        theSocket.bind(localAddress);
+        assertEquals(localAddress, theSocket.getLocalSocketAddress());
+        theSocket.close();
+    }
+
+    public void test_getLocalSocketAddress_unbound() throws Exception {
+        int portNumber = Support_PortManager.getNextPortForUDP();
+        InetSocketAddress localAddress1 = new InetSocketAddress(InetAddress.getLocalHost(), portNumber);
+        DatagramSocket s = new DatagramSocket(localAddress1);
+        assertEquals(localAddress1, s.getLocalSocketAddress());
+        s.close();
+
+        InetSocketAddress remoteAddress = (InetSocketAddress) s.getRemoteSocketAddress();
+        assertNull(remoteAddress);
+    }
+
+    public void test_getLocalSocketAddress_ANY() throws Exception {
+        DatagramSocket s = new DatagramSocket(0);
+        try {
+            assertTrue("ANY address not IPv6: " + s.getLocalSocketAddress(),
+                    ((InetSocketAddress) s.getLocalSocketAddress()).getAddress() instanceof Inet6Address);
+        } finally {
+            s.close();
+        }
+    }
+
+    public void test_setReuseAddressZ() throws Exception {
+        // test case were we set it to false
+        DatagramSocket theSocket1 = null;
+        DatagramSocket theSocket2 = null;
+        try {
+            InetSocketAddress theAddress = new InetSocketAddress(InetAddress.getLocalHost(), Support_PortManager.getNextPortForUDP());
+            theSocket1 = new DatagramSocket(null);
+            theSocket2 = new DatagramSocket(null);
+            theSocket1.setReuseAddress(false);
+            theSocket2.setReuseAddress(false);
+            theSocket1.bind(theAddress);
+            theSocket2.bind(theAddress);
+            fail("No exception when trying to connect to do duplicate socket bind with re-useaddr set to false");
+        } catch (BindException expected) {
+        }
+        if (theSocket1 != null) {
+            theSocket1.close();
+        }
+        if (theSocket2 != null) {
+            theSocket2.close();
+        }
+
+        // test case were we set it to true
+        InetSocketAddress theAddress = new InetSocketAddress(InetAddress.getLocalHost(), Support_PortManager.getNextPortForUDP());
+        theSocket1 = new DatagramSocket(null);
+        theSocket2 = new DatagramSocket(null);
+        theSocket1.setReuseAddress(true);
+        theSocket2.setReuseAddress(true);
+        theSocket1.bind(theAddress);
+        theSocket2.bind(theAddress);
+
+        if (theSocket1 != null) {
+            theSocket1.close();
+        }
+        if (theSocket2 != null) {
+            theSocket2.close();
+        }
+
+        // test the default case which we expect to be the same on all
+        // platforms
+        try {
+            theAddress = new InetSocketAddress(InetAddress.getLocalHost(), Support_PortManager.getNextPortForUDP());
+            theSocket1 = new DatagramSocket(null);
+            theSocket2 = new DatagramSocket(null);
+            theSocket1.bind(theAddress);
+            theSocket2.bind(theAddress);
+            fail("No exception when trying to connect to do duplicate socket bind with re-useaddr left as default");
+        } catch (BindException expected) {
+        }
+        if (theSocket1 != null) {
+            theSocket1.close();
+        }
+        if (theSocket2 != null) {
+            theSocket2.close();
+        }
+    }
+
+    public void test_getReuseAddress() throws Exception {
+        DatagramSocket theSocket = new DatagramSocket();
+        theSocket.setReuseAddress(true);
+        assertTrue("getReuseAddress false when it should be true", theSocket.getReuseAddress());
+        theSocket.setReuseAddress(false);
+        assertFalse("getReuseAddress true when it should be False", theSocket.getReuseAddress());
+    }
+
+    public void test_setBroadcastZ() throws Exception {
+        int[] ports = Support_PortManager.getNextPortsForUDP(3);
+        DatagramSocket theSocket = new DatagramSocket(ports[0]);
+        theSocket.setBroadcast(false);
+        byte theBytes[] = { -1, -1, -1, -1 };
+
+        // validate we cannot connect to the broadcast address when
+        // setBroadcast is false
+        try {
+            theSocket.connect(new InetSocketAddress(InetAddress.getByAddress(theBytes), ports[1]));
+            assertFalse("No exception when connecting to broadcast address with setBroadcast(false)", theSocket.getBroadcast());
+        } catch (Exception ex) {
+        }
+
+        // now validate that we can connect to the broadcast address when
+        // setBroadcast is true
+        theSocket.setBroadcast(true);
+        theSocket.connect(new InetSocketAddress(InetAddress.getByAddress(theBytes), ports[2]));
+    }
+
+    public void test_getBroadcast() throws Exception {
+        DatagramSocket theSocket = new DatagramSocket();
+        theSocket.setBroadcast(true);
+        assertTrue("getBroadcast false when it should be true", theSocket.getBroadcast());
+        theSocket.setBroadcast(false);
+        assertFalse("getBroadcast true when it should be False", theSocket.getBroadcast());
+    }
+
+    public void test_setTrafficClassI() throws Exception {
+        int IPTOS_LOWCOST = 0x2;
+        int IPTOS_RELIABILTY = 0x4;
+        int IPTOS_THROUGHPUT = 0x8;
+        int IPTOS_LOWDELAY = 0x10;
+        int[] ports = Support_PortManager.getNextPortsForUDP(2);
+
+        new InetSocketAddress(InetAddress.getLocalHost(), ports[0]);
+        DatagramSocket theSocket = new DatagramSocket(ports[1]);
+
+        // validate that value set must be between 0 and 255
+        try {
+            theSocket.setTrafficClass(256);
+            fail("No exception when traffic class set to 256");
+        } catch (IllegalArgumentException e) {
+        }
+
+        try {
+            theSocket.setTrafficClass(-1);
+            fail("No exception when traffic class set to -1");
+        } catch (IllegalArgumentException e) {
+        }
+
+        // now validate that we can set it to some good values
+        theSocket.setTrafficClass(IPTOS_LOWCOST);
+        theSocket.setTrafficClass(IPTOS_THROUGHPUT);
+    }
+
+    public void test_getTrafficClass() throws Exception {
+        int IPTOS_LOWCOST = 0x2;
+        int IPTOS_RELIABILTY = 0x4;
+        int IPTOS_THROUGHPUT = 0x8;
+        int IPTOS_LOWDELAY = 0x10;
+        int[] ports = Support_PortManager.getNextPortsForUDP(2);
+
+        new InetSocketAddress(InetAddress.getLocalHost(), ports[0]);
+        DatagramSocket theSocket = new DatagramSocket(ports[1]);
+
+        /*
+         * we cannot actually check that the values are set as if a platform
+         * does not support the option then it may come back unset even
+         * though we set it so just get the value to make sure we can get it
+         */
+        int trafficClass = theSocket.getTrafficClass();
+    }
+
+    public void test_isClosed() throws Exception {
+        DatagramSocket theSocket = new DatagramSocket();
+
+        // validate isClosed returns expected values
+        assertFalse("Socket should indicate it is not closed(1):", theSocket
+                .isClosed());
+        theSocket.close();
+        assertTrue("Socket should indicate it is not closed(1):", theSocket
+                .isClosed());
+
+        InetSocketAddress theAddress = new InetSocketAddress(InetAddress
+                .getLocalHost(), Support_PortManager.getNextPortForUDP());
+        theSocket = new DatagramSocket(theAddress);
+        assertFalse("Socket should indicate it is not closed(2):", theSocket
+                .isClosed());
+        theSocket.close();
+        assertTrue("Socket should indicate it is not closed(2):", theSocket
+                .isClosed());
+    }
+
+    /**
+     * java.net.DatagramSocket#getChannel()
+     */
+    public void test_getChannel() throws SocketException {
+        assertNull(new DatagramSocket().getChannel());
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() {
+        retval = "Bogus retval";
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    protected void tearDown() {
+        try {
+            ds.close();
+            sds.close();
+        } catch (Exception e) {
+        }
+    }
+
+    protected void receive_oversize_java_net_DatagramPacket() {
+        final int[] ports = Support_PortManager.getNextPortsForUDP(2);
+        final int portNumber = ports[0];
+
+        class TestDGRcvOver implements Runnable {
+            public void run() {
+                InetAddress localHost = null;
+                try {
+                    localHost = InetAddress.getLocalHost();
+                    Thread.sleep(1000);
+                    DatagramSocket sds = new DatagramSocket(ports[1]);
+                    DatagramPacket rdp = new DatagramPacket("0123456789"
+                            .getBytes(), 10, localHost, portNumber);
+                    sds.send(rdp);
+                    sds.close();
+                } catch (Exception e) {
+                    System.err.println("host " + localHost + " port "
+                            + portNumber + " failed to send oversize data: "
+                            + e);
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        try {
+            new Thread(new TestDGRcvOver(), "DGSenderOver").start();
+            ds = new java.net.DatagramSocket(portNumber);
+            ds.setSoTimeout(6000);
+            byte rbuf[] = new byte[5];
+            DatagramPacket rdp = new DatagramPacket(rbuf, rbuf.length);
+            ;
+            ds.receive(rdp);
+            ds.close();
+            assertTrue("Send/Receive oversize failed to return correct data: "
+                    + new String(rbuf, 0, 5), new String(rbuf, 0, 5)
+                    .equals("01234"));
+        } catch (Exception e) {
+            System.err.println("Exception during send test: " + e);
+            e.printStackTrace();
+            fail("port " + portNumber + " Exception: " + e
+                    + " during oversize send test");
+        } finally {
+            ds.close();
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/HttpCookieTest.java b/luni/src/test/java/tests/api/java/net/HttpCookieTest.java
new file mode 100644
index 0000000..621e3f4
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/HttpCookieTest.java
@@ -0,0 +1,956 @@
+/*
+ * 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.HttpCookie;
+import java.util.List;
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+public class HttpCookieTest extends TestCase {
+    private Locale locale;
+
+    /**
+     * java.net.HttpCookie(String, String).
+     * @since 1.6
+     */
+    public void test_HttpCookie_LString_LString() {
+        assertNotNull(new HttpCookie("harmony_6", "test,sem"));
+        assertNotNull(new HttpCookie("harmony_6", null));
+        assertNotNull(new HttpCookie("harmony    ", null));
+        assertEquals("harmony", new HttpCookie("harmony ", null).getName());
+
+        constructHttpCookie("", null);
+
+        String value = "value";
+        constructHttpCookie("", value);
+
+        constructHttpCookie("harmony,", value);
+        constructHttpCookie("harmony;", value);
+        constructHttpCookie("$harmony", value);
+        constructHttpCookie("n\tame", value);
+        constructHttpCookie("n\rame", value);
+        constructHttpCookie("n\r\name", value);
+        constructHttpCookie("Comment", value);
+        constructHttpCookie("CommentURL", value);
+        constructHttpCookie("Domain", value);
+        constructHttpCookie("Discard", value);
+        constructHttpCookie("Max-Age", value);
+        constructHttpCookie("  Path     ", value);
+        constructHttpCookie("Port  ", value);
+        constructHttpCookie("SeCure", value);
+        constructHttpCookie("VErsion", value);
+        constructHttpCookie("expires", value);
+        constructHttpCookie("na\u0085me", value);
+        constructHttpCookie("\u2028me", value);
+        constructHttpCookie("na\u2029me", value);
+
+        try {
+            new HttpCookie(null, value);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            new HttpCookie("\u007f", value);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        HttpCookie cookie = new HttpCookie("harmony!", null);
+        assertEquals("harmony!", cookie.getName());
+
+        cookie = new HttpCookie("harmon$y", null);
+        assertEquals("harmon$y", cookie.getName());
+
+    }
+
+    private static void constructHttpCookie(String name, String value) {
+        try {
+            new HttpCookie(name, value);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.net.HttpCookie#domainMatches(String, String).
+     * @since 1.6
+     */
+    public void test_DomainMatches() {
+
+        /*
+         * Rule 1: A host isn't in a domain (RFC 2965 sec. 3.3.2) if: The value
+         * for the Domain attribute contains no embedded dots, and the value is
+         * not .local.
+         */
+        boolean match = HttpCookie.domainMatches("hostname", "hostname");
+        assertFalse(match);
+
+        match = HttpCookie.domainMatches(".com", "test.com");
+        assertFalse(match);
+
+        match = HttpCookie.domainMatches(".com.", "test.com");
+        assertFalse(match);
+
+        // During comparison, host name is transformed to effective host name
+        // first.
+        match = HttpCookie.domainMatches(".local", "hostname");
+        assertTrue(match);
+
+        /*
+         * Rule 3: The request-host is a HDN (not IP address) and has the form
+         * HD, where D is the value of the Domain attribute, and H is a string
+         * that contains one or more dots.
+         */
+        match = HttpCookie.domainMatches(".c.d", "a.b.c.d");
+        assertFalse(match);
+
+        match = HttpCookie.domainMatches(".foo.com", "y.x.foo.com");
+        assertFalse(match);
+
+        match = HttpCookie.domainMatches(".foo.com", "x.foo.com");
+        assertTrue(match);
+
+        match = HttpCookie.domainMatches(".local", "hostname.local");
+        assertTrue(match);
+
+        match = HttpCookie.domainMatches(".ajax.com", "a.ajax.com");
+        assertTrue(match);
+
+        match = HttpCookie.domainMatches(".ajax.com", "a.AJAX.com");
+        assertTrue(match);
+
+        match = HttpCookie.domainMatches("...", "test...");
+        assertTrue(match);
+
+        match = HttpCookie.domainMatches(".ajax.com", "b.a.AJAX.com");
+        assertFalse(match);
+
+        match = HttpCookie.domainMatches(".a", "b.a");
+        assertFalse(match);
+
+        // when either parameter is null
+        match = HttpCookie.domainMatches(".ajax.com", null);
+        assertFalse(match);
+
+        match = HttpCookie.domainMatches(null, null);
+        assertFalse(match);
+
+        match = HttpCookie.domainMatches(null, "b.a.AJAX.com");
+        assertFalse(match);
+
+        // TODO RI bug? The effective hostname is hostname.local which is string
+        // equal with hostname.local. So they should be domain match.
+        match = HttpCookie.domainMatches("hostname.local", "hostname");
+        assertTrue(match);
+    }
+
+    /**
+     * java.net.HttpCookie#getVersion(), setVersion(int).
+     * @since 1.6
+     */
+    public void test_Get_SetVersion() {
+        HttpCookie cookie = new HttpCookie("name", "value");
+        assertEquals(1, cookie.getVersion());
+        cookie.setVersion(0);
+        assertEquals(0, cookie.getVersion());
+        cookie.setVersion(1);
+        assertEquals(1, cookie.getVersion());
+
+        try {
+            cookie.setVersion(-1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            cookie.setVersion(2);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.net.HttpCookie#getValue(), setValue(String)
+     * @since 1.6
+     */
+    public void test_Get_SetValue() {
+        HttpCookie cookie = new HttpCookie("name", "value");
+        assertEquals("value", cookie.getValue());
+        cookie.setValue("newValue");
+        assertEquals("newValue", cookie.getValue());
+
+        cookie.setValue(null);
+        assertNull(cookie.getValue());
+
+        cookie.setValue("na\u64DEme");
+        assertEquals("na\u64DEme", cookie.getValue());
+        cookie.setVersion(0);
+        cookie.setValue("{(new value, 11)}");
+        assertEquals("{(new value, 11)}", cookie.getValue());
+    }
+
+    /**
+     * java.net.HttpCookie#getName()
+     * @since 1.6
+     */
+    public void test_GetName() {
+        HttpCookie cookie = new HttpCookie("testName", "value");
+        assertEquals("testName", cookie.getName());
+    }
+
+    /**
+     * java.net.HttpCookie#getSecure(), setSecure(boolean)
+     * @since 1.6
+     */
+    public void test_Get_SetSecure() {
+        HttpCookie cookie = new HttpCookie("testName", "value");
+        assertFalse(cookie.getSecure());
+        cookie.setVersion(0);
+        assertFalse(cookie.getSecure());
+
+        cookie.setSecure(true);
+        assertTrue(cookie.getSecure());
+        cookie.setSecure(false);
+        cookie.setVersion(1);
+        assertFalse(cookie.getSecure());
+    }
+
+    /**
+     * java.net.HttpCookie#getPath(), setPath(String)
+     * @since 1.6
+     */
+    public void test_Get_SetPath() {
+        HttpCookie cookie = new HttpCookie("name", "test new value");
+        assertNull(cookie.getPath());
+
+        cookie.setPath("{}()  test,; 43!@");
+        assertEquals("{}()  test,; 43!@", cookie.getPath());
+
+        cookie.setPath(" test");
+        assertEquals(" test", cookie.getPath());
+
+        cookie.setPath("\u63DF\u64DE");
+        cookie.setDomain("test");
+        assertEquals("\u63DF\u64DE", cookie.getPath());
+    }
+
+    /**
+     * java.net.HttpCookie#getMaxAge(), setMaxAge(long)
+     * @since 1.6
+     */
+    public void test_Get_SetMaxAge() {
+        HttpCookie cookie = new HttpCookie("name", "test new value");
+        assertEquals(-1, cookie.getMaxAge());
+
+        cookie.setMaxAge(Long.MAX_VALUE);
+        assertEquals(Long.MAX_VALUE, cookie.getMaxAge());
+
+        cookie.setMaxAge(Long.MIN_VALUE);
+        cookie.setDiscard(false);
+        assertEquals(Long.MIN_VALUE, cookie.getMaxAge());
+    }
+
+    /**
+     * java.net.HttpCookie#getDomain(), setDomain(String)
+     * @since 1.6
+     */
+    public void test_Get_SetDomain() {
+        HttpCookie cookie = new HttpCookie("name", "test new value");
+        assertNull(cookie.getDomain());
+
+        cookie.setDomain("a.b.d.c.com.");
+        assertEquals("a.b.d.c.com.", cookie.getDomain());
+
+        cookie.setDomain("   a.b.d.c.com.  ");
+        assertEquals("   a.b.d.c.com.  ", cookie.getDomain());
+
+        cookie.setPath("temp/subTemp");
+        cookie.setDomain("xy.foo.bar.de.edu");
+        assertEquals("xy.foo.bar.de.edu", cookie.getDomain());
+    }
+
+    /**
+     * java.net.HttpCookie#getPortlist(), setPortlist(String)
+     * @since 1.6
+     */
+    public void test_Get_SetPortlist() {
+        HttpCookie cookie = new HttpCookie("cookieName", "cookieName value");
+        assertNull(cookie.getPortlist());
+
+        cookie.setPortlist("80,23,20");
+        assertEquals("80,23,20", cookie.getPortlist());
+        cookie.setPortlist("abcdefg1234567");
+        cookie.setValue("cookie value again");
+        assertEquals("abcdefg1234567", cookie.getPortlist());
+    }
+
+    /**
+     * java.net.HttpCookie#getDiscard(), setDiscard(boolean)
+     * @since 1.6
+     */
+    public void test_Get_SetDiscard() {
+        HttpCookie cookie = new HttpCookie("cookie'sName",
+                "cookie's Test value");
+        assertFalse(cookie.getDiscard());
+
+        cookie.setDiscard(true);
+        assertTrue(cookie.getDiscard());
+        cookie.setDiscard(false);
+        cookie.setMaxAge(-1);
+        assertFalse(cookie.getDiscard());
+    }
+
+    /**
+     * java.net.HttpCookie#getCommentURL(), setCommentURL(String)
+     * @since 1.6
+     */
+    public void test_Get_SetCommentURL() {
+        HttpCookie cookie = new HttpCookie("cookie'\"sName",
+                "cookie's Test value");
+        assertNull(cookie.getCommentURL());
+
+        cookie.setCommentURL("http://www.test.com");
+        assertEquals("http://www.test.com", cookie.getCommentURL());
+
+        cookie.setCommentURL("schema://harmony.test.org");
+        cookie.setComment("just a comment");
+        assertEquals("schema://harmony.test.org", cookie.getCommentURL());
+    }
+
+    /**
+     * java.net.HttpCookie#getComment(), setComment(String)
+     * @since 1.6
+     */
+    public void test_Get_SetComment() {
+        HttpCookie cookie = new HttpCookie("cookie'\"sName?",
+                "cookie's Test??!@# value");
+        assertNull(cookie.getComment());
+
+        cookie.setComment("");
+        assertEquals("", cookie.getComment());
+
+        cookie.setComment("cookie''s @#$!&*()");
+        cookie.setVersion(0);
+        assertEquals("cookie''s @#$!&*()", cookie.getComment());
+    }
+
+    /**
+     * java.net.HttpCookie#hasExpired()
+     * @since 1.6
+     */
+    public void test_HasExpired() {
+        HttpCookie cookie = new HttpCookie("cookie'\"sName123456",
+                "cookie's Test?()!@# value");
+        assertFalse(cookie.hasExpired());
+
+        cookie.setMaxAge(0);
+        assertTrue(cookie.hasExpired());
+
+        cookie.setMaxAge(Long.MAX_VALUE);
+        cookie.setVersion(0);
+        assertFalse(cookie.hasExpired());
+
+        cookie.setMaxAge(Long.MIN_VALUE);
+        cookie.setDiscard(false);
+        assertTrue(cookie.hasExpired());
+
+        cookie.setDiscard(true);
+        cookie.setMaxAge(-1);
+        assertFalse(cookie.hasExpired());
+    }
+
+    /**
+     * java.net.HttpCookie#equals()
+     * @since 1.6
+     */
+    public void test_Equals() {
+        Object obj = new Object();
+        HttpCookie cookie = new HttpCookie("test", "testValue");
+        HttpCookie cookie2 = new HttpCookie("TesT", "TEstValue");
+
+        assertFalse(cookie.equals(obj));
+        assertFalse(cookie.equals(null));
+        assertTrue(cookie2.equals(cookie));
+        assertTrue(cookie.equals(cookie2));
+        assertTrue(cookie.equals(cookie));
+
+        cookie.setDomain("  test");
+        cookie2.setDomain("test");
+        assertFalse(cookie.equals(cookie2));
+        cookie.setDomain("TEST");
+        assertTrue(cookie.equals(cookie2));
+
+        cookie.setPath("temp\\e");
+        assertFalse(cookie.equals(cookie2));
+        cookie2.setPath("temp\\E");
+        assertFalse(cookie.equals(cookie2));
+
+        cookie.setDiscard(true);
+        cookie.setMaxAge(-1234);
+        cookie2.setPath("temp\\e");
+        assertTrue(cookie.equals(cookie2));
+    }
+
+    /**
+     * java.net.HttpCookie#clone()
+     * @since 1.6
+     */
+    public void test_Clone() {
+        HttpCookie cookie = new HttpCookie("test", "testValue");
+        cookie.setMaxAge(33l);
+        cookie.setComment("test comment");
+        HttpCookie cloneCookie = (HttpCookie) cookie.clone();
+        assertNotSame(cloneCookie, cookie);
+        assertEquals("test", cloneCookie.getName());
+        assertEquals(33l, cloneCookie.getMaxAge());
+        assertEquals("test comment", cloneCookie.getComment());
+    }
+
+    /**
+     * java.net.HttpCookie#toString()
+     * @since 1.6
+     */
+    public void test_ToString() {
+        HttpCookie cookie = new HttpCookie("test", "testValue");
+        cookie.setComment("ABCd");
+        cookie.setCommentURL("\u63DF");
+        cookie.setDomain(".B.com");
+        cookie.setDiscard(true);
+        cookie.setMaxAge(Integer.MAX_VALUE);
+        cookie.setPath("temp/22RuTh");
+        cookie.setPortlist("80.562Ab");
+        cookie.setSecure(true);
+        cookie.setVersion(1);
+
+        assertEquals(
+                "test=\"testValue\";$Path=\"temp/22RuTh\";$Domain=\".b.com\";$Port=\"80.562Ab\"",
+                cookie.toString());
+
+        cookie.setPath(null);
+        assertEquals(
+                "test=\"testValue\";$Domain=\".b.com\";$Port=\"80.562Ab\"",
+                cookie.toString());
+        cookie.setComment(null);
+        assertEquals(
+                "test=\"testValue\";$Domain=\".b.com\";$Port=\"80.562Ab\"",
+                cookie.toString());
+        cookie.setPortlist(null);
+        assertEquals("test=\"testValue\";$Domain=\".b.com\"", cookie.toString());
+        cookie.setDomain(null);
+        assertEquals("test=\"testValue\"", cookie.toString());
+
+        cookie.setVersion(0);
+        cookie.setPortlist("80,8000");
+        assertEquals("test=testValue", cookie.toString());
+    }
+
+    /**
+     * java.net.HttpCookie#hashCode()
+     * @since 1.6
+     */
+    public void test_HashCode() {
+        HttpCookie cookie = new HttpCookie("nAmW_1", "value_1");
+        assertEquals(-1052814577, cookie.hashCode());
+
+        cookie.setDomain("a.b.c.de");
+        assertEquals(1222695220, cookie.hashCode());
+
+        cookie.setPath("3kmxiq;1");
+        assertEquals(-675006347, cookie.hashCode());
+        cookie.setPath("3KmxiQ;1");
+        assertEquals(989616181, cookie.hashCode());
+
+        cookie.setValue("Vw0,22_789");
+        assertEquals(989616181, cookie.hashCode());
+        cookie.setComment("comment");
+        assertEquals(989616181, cookie.hashCode());
+
+        cookie.setDomain("");
+        assertEquals(-1285893616, cookie.hashCode());
+    }
+
+    /**
+     * java.net.HttpCookie#parse(String) for exception cases
+     * @since 1.6
+     */
+    public void test_Parse_exception() {
+        try {
+            HttpCookie.parse(null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        /*
+         * Please note that Netscape draft specification does not fully conform
+         * to the HTTP header format. Netscape draft does not specify whether
+         * multiple cookies may be sent in one header. Hence, comma character
+         * may be present in unquoted cookie value or unquoted parameter value.
+         * Refer to <a
+         * href="http://jakarta.apache.org/commons/httpclient/apidocs/org/apache/commons/httpclient/cookie/NetscapeDraftSpec.html#parse(java.lang.String,%20int,%20java.lang.String,%20boolean,%20java.lang.String)">
+         * http://jakarta.apache.org/commons/httpclient/apidocs/org/apache/commons/httpclient/cookie/NetscapeDraftSpec.html#parse(java.lang.String,%20int,%20java.lang.String,%20boolean,%20java.lang.String)
+         * </a>
+         */
+        // violates the cookie specification's syntax
+        checkInvalidCookie("invalid cookie name");
+        checkInvalidCookie("Set-Cookie2:");
+        checkInvalidCookie("name");
+        checkInvalidCookie("$name=");
+        checkInvalidCookie("Set-Cookie2:$name=");
+        checkInvalidCookie("Set-Cookie:$");
+        checkInvalidCookie("Set-Cookie");
+        checkInvalidCookie("Set-Cookie2:test==wwlala;Discard;Patth=/temp");
+        checkInvalidCookie("Set-Cookie2:test==wwlala;Version=2");
+
+        // cookie name contains llegal characters
+        checkInvalidCookie("Set-Cookie:n,ame=");
+        checkInvalidCookie("Set-Cookie2:n\name=");
+        checkInvalidCookie("Set-Cookie2:n,ame=");
+        checkInvalidCookie("Set-Cookie2:n\tame=");
+        checkInvalidCookie("Set-Cookie2:n\rame=");
+        checkInvalidCookie("Set-Cookie2:n\r\name=");
+        checkInvalidCookie("Set-Cookie2:na\u0085me=");
+        checkInvalidCookie("Set-Cookie2:na\u2028me=");
+        checkInvalidCookie("Set-Cookie2:na\u2029me=");
+        checkInvalidCookie("Set-Cookie2:=");
+        checkInvalidCookie("Set-Cookie2:name=tes,t");
+
+        // 'CommentURL' is one of the tokens reserved, case-insensitive
+        checkInvalidCookie("Set-Cookie2:COmmentURL=\"lala\"");
+
+        // check value
+        checkInvalidCookie("Set-Cookie2:val,ue");
+        checkInvalidCookie("Set-Cookie2:name=test;comMent=sent,ence");
+        checkInvalidCookie("Set-Cookie2:name=test;comMentUrL=u,rl");
+        checkInvalidCookie("Set-Cookie2:name=test;Discard=fa,lse");
+        checkInvalidCookie("Set-Cookie2:name=test;Disc,ard");
+        checkInvalidCookie("Set-Cookie2:name=test;Domain=u,rl");
+        checkInvalidCookie("Set-Cookie2:name=test;Path=pa,th");
+        checkInvalidCookie("Set-Cookie2:name=test;Secure=se,cure");
+        checkInvalidCookie("Set-Cookie2:name=test;se,cure");
+        checkInvalidCookie("Set-Cookie2:name=test;Max-Age=se,cure");
+        checkInvalidCookie("Set-Cookie2:name=test;Max-Age=");
+        checkInvalidCookie("Set-Cookie2:name=test;Max-Age=max-age");
+        checkInvalidCookie("Set-Cookie2:name=test;Max-Age=1000.0");
+        checkInvalidCookie("Set-Cookie2:name=test;Version=trivail");
+        checkInvalidCookie("Set-Cookie2:name=test;vErsion=1000.0");
+        checkInvalidCookie("Set-Cookie2:name=test;vErsion=1000");
+    }
+
+    /**
+     * java.net.HttpCookie#parse(String) for locales other than
+     * Locale.ENGLISH.
+     * @since 1.6
+     */
+    public void test_Parse_locale() {
+        Locale.setDefault(Locale.FRENCH);
+        List<HttpCookie> list = HttpCookie
+                .parse("Set-Cookie:name=test;expires=Thu, 30-Oct-2008 19:14:07 GMT;");
+        HttpCookie cookie = list.get(0);
+        assertEquals(0, cookie.getMaxAge());
+        assertTrue(cookie.hasExpired());
+
+        Locale.setDefault(Locale.GERMAN);
+        list = HttpCookie
+                .parse("Set-Cookie:name=test;expires=Sun, 30-Oct-2005 19:14:07 GMT;");
+        cookie = list.get(0);
+        assertEquals(0, cookie.getMaxAge());
+        assertTrue(cookie.hasExpired());
+
+        Locale.setDefault(Locale.KOREA);
+        list = HttpCookie
+                .parse("Set-Cookie:name=test;max-age=1234;expires=Sun, 30-Oct-2005 19:14:07 GMT;");
+        cookie = list.get(0);
+        assertEquals(0, cookie.getVersion());
+        assertEquals(1234, cookie.getMaxAge());
+        assertFalse(cookie.hasExpired());
+
+        Locale.setDefault(Locale.TAIWAN);
+        list = HttpCookie
+                .parse("Set-Cookie:name=test;expires=Sun, 30-Oct-2005 19:14:07 GMT;max-age=-12345;");
+        cookie = list.get(0);
+        assertEquals(0, cookie.getMaxAge());
+        assertTrue(cookie.hasExpired());
+
+        // Locale does not affect version 1 cookie.
+        Locale.setDefault(Locale.ITALIAN);
+        list = HttpCookie.parse("Set-Cookie2:name=test;max-age=1000");
+        cookie = list.get(0);
+        assertEquals(1000, cookie.getMaxAge());
+        assertFalse(cookie.hasExpired());
+    }
+
+    /**
+     * java.net.HttpCookie#parse(String) for normal cases
+     * @since 1.6
+     */
+    public void test_Parse() {
+        List<HttpCookie> list = HttpCookie.parse("test=\"null\"");
+        HttpCookie cookie = list.get(0);
+        // when two '"' presents, the parser ignores it.
+        assertEquals("null", cookie.getValue());
+        assertNull(cookie.getComment());
+        assertNull(cookie.getCommentURL());
+        assertFalse(cookie.getDiscard());
+        assertNull(cookie.getDomain());
+        assertEquals(-1, cookie.getMaxAge());
+        assertNull(cookie.getPath());
+        assertNull(cookie.getPortlist());
+        assertFalse(cookie.getSecure());
+        // default version is 0
+        assertEquals(0, cookie.getVersion());
+
+        list = HttpCookie.parse("Set-cookie2:name=\"tes,t\"");
+        cookie = list.get(0);
+        // when two '"' presents, the parser ignores it.
+        assertEquals("tes,t", cookie.getValue());
+
+        // If cookie header = Set-Cookie2, version = 1
+        list = HttpCookie
+                .parse("Set-cookie2:test=null\";;Port=abde,82;Path=/temp;;;Discard;commentURl=http://harmonytest.org;Max-age=-10;");
+        cookie = list.get(0);
+        assertEquals("null\"", cookie.getValue());
+        assertEquals(1, cookie.getVersion());
+        assertEquals("/temp", cookie.getPath());
+        assertTrue(cookie.getDiscard());
+        assertEquals("http://harmonytest.org", cookie.getCommentURL());
+        assertEquals(-10l, cookie.getMaxAge());
+        assertTrue(cookie.hasExpired());
+        assertEquals("abde,82", cookie.getPortlist());
+        // Version 0 cookie
+        list = HttpCookie
+                .parse("Set-Cookie:name=tes,t;Comment=version1-cookie;Discard=false;commentURL=vers\nion1-cookie-url;Domain=x.y;");
+        cookie = list.get(0);
+        assertEquals(0, cookie.getVersion());
+        assertEquals("tes,t", cookie.getValue());
+        assertEquals("name", cookie.getName());
+        assertEquals("version1-cookie", cookie.getComment());
+        assertEquals("vers\nion1-cookie-url", cookie.getCommentURL());
+        assertEquals("x.y", cookie.getDomain());
+        assertTrue(cookie.getDiscard());
+
+        // Check value
+        checkValidValue("Set-Cookie:", "val,ue");
+        checkValidValue("Set-Cookie:", "val\nue");
+        checkValidValue("Set-Cookie:", "value=value");
+        checkValidValue("Set-Cookie2:", "val\nue");
+        checkValidValue("Set-Cookie2:", "val\u2029ue");
+        checkValidValue("Set-Cookie2:", "value=value");
+
+        // Check comment
+        // In RFC 2965 '=' is mandatory, but this is not the case in RI.
+        list = HttpCookie.parse("Set-Cookie:name=tes,t;Comment;");
+        cookie = list.get(0);
+        assertNull(cookie.getComment());
+
+        list = HttpCookie
+                .parse("Set-Cookie:name=tes,t;Comment=sentence;Comment=anotherSentence");
+        cookie = list.get(0);
+        assertEquals("sentence", cookie.getComment());
+
+        // Check CommentURL
+        list = HttpCookie
+                .parse("Set-Cookie:name=tes,t;Commenturl;commentuRL=(la,la)");
+        cookie = list.get(0);
+        assertEquals("(la,la)", cookie.getCommentURL());
+
+        // Check Domain
+        list = HttpCookie.parse("Set-Cookie:name=test;Domain=a_domain");
+        cookie = list.get(0);
+        assertEquals("a_domain", cookie.getDomain());
+
+        // Check Path
+        list = HttpCookie.parse("Set-Cookie:name=test;PaTh=pa$th");
+        cookie = list.get(0);
+        assertEquals("pa$th", cookie.getPath());
+
+        // Check Max-Age
+        list = HttpCookie.parse("Set-Cookie:name=test;Max-Age=1000");
+        cookie = list.get(0);
+        assertEquals(1000, cookie.getMaxAge());
+
+        list = HttpCookie.parse("Set-Cookie:name=test;Max-Age=-1000");
+        cookie = list.get(0);
+        assertEquals(-1000, cookie.getMaxAge());
+
+        // Check portlist
+        list = HttpCookie.parse("Set-Cookie:name=tes,t;port");
+        cookie = list.get(0);
+        assertEquals(null, cookie.getPortlist());
+
+        list = HttpCookie.parse("Set-Cookie:name=tes,t;port=");
+        cookie = list.get(0);
+        assertEquals("", cookie.getPortlist());
+
+        list = HttpCookie.parse("Set-Cookie:name=tes,t;port=123 345");
+        cookie = list.get(0);
+        assertEquals("123 345", cookie.getPortlist());
+
+        list = HttpCookie.parse("Set-Cookie:name=tes,t;port=123,345");
+        cookie = list.get(0);
+        assertEquals("123,345", cookie.getPortlist());
+
+        // Check Secure
+        list = HttpCookie.parse("Set-Cookie:name=test;secure");
+        cookie = list.get(0);
+        assertTrue(cookie.getSecure());
+
+        list = HttpCookie.parse("Set-Cookie:name=test;secure=fa");
+        cookie = list.get(0);
+        assertTrue(cookie.getSecure());
+        assertFalse(cookie.hasExpired());
+
+        list = HttpCookie.parse("Set-Cookie2:name=test;secure=false");
+        cookie = list.get(0);
+        assertTrue(cookie.getSecure());
+
+        // Check expire
+        list = HttpCookie.parse("Set-Cookie:name=test;expires=2006-10-23");
+        cookie = list.get(0);
+        assertEquals(0, cookie.getMaxAge());
+        assertTrue(cookie.hasExpired());
+
+        // Also recognize invalid date
+        list = HttpCookie
+                .parse("Set-Cookie:name=test;expires=Sun, 29-Feb-1999 19:14:07 GMT");
+        cookie = list.get(0);
+        assertTrue(cookie.getMaxAge() < 0);
+        assertTrue(cookie.hasExpired());
+
+        // Parse multiple cookies
+        list = HttpCookie
+                .parse("Set-Cookie2:name=test;,Set-Cookie2:name2=test2;comment=c234;");
+        cookie = list.get(0);
+        assertEquals("name", cookie.getName());
+        assertEquals(1, cookie.getVersion());
+        assertEquals("test", cookie.getValue());
+        cookie = list.get(1);
+        assertEquals(1, cookie.getVersion());
+        // From the second cookie, the "set-cookie2" header does not take effect
+        assertEquals("Set-Cookie2:name2", cookie.getName());
+        assertEquals("c234", cookie.getComment());
+
+        list = HttpCookie.parse("Set-Cookie2:name=test,name2=test2");
+        assertEquals(1, list.get(0).getVersion());
+        assertEquals(1, list.get(1).getVersion());
+
+        // Must begin with "set-cookie2" header
+        list = HttpCookie.parse("name=test,Set-Cookie2:name2=test2");
+        cookie = list.get(0);
+        assertEquals(1, list.size());
+
+        HttpCookie c = HttpCookie.parse(
+                "Set-cookie:NAME2=VALUE2;path=/t;domain=.b.c;version=1").get(0);
+        assertEquals(1, c.getVersion());
+
+        c = HttpCookie.parse(
+                "Set-cookie2:NAME2=VALUE2;path=/t;domain=.b.c;version=0")
+                .get(0);
+        assertEquals(1, c.getVersion());
+
+        list = HttpCookie.parse("Set-cookie:null=;Domain=null;Port=null");
+        cookie = list.get(0);
+
+        assertNotNull(cookie.getValue());
+        assertNotNull(cookie.getName());
+        assertNotNull(cookie.getDomain());
+        assertNotNull(cookie.getPortlist());
+
+        // Check CommentURL, RI's bug: 'a  name' is not valid attribute name. 
+        list = HttpCookie
+                .parse("Set-Cookie:a  name=tes,t;Commenturl;commentuRL=(la,la);path=hello");
+        cookie = list.get(0);
+        assertEquals("(la,la)", cookie.getCommentURL());
+
+
+        list = HttpCookie
+                .parse("Set-Cookie:name=tes,t;Commenturl;commentuRL=(la,la);commentuRL=hello");
+        cookie = list.get(0);
+        assertEquals("(la,la)", cookie.getCommentURL());
+
+        list = HttpCookie
+                .parse("Set-Cookie:name=tes,t;Commenturl;commentuRL=(la,la); path  =hello");
+        cookie = list.get(0);
+        assertEquals("(la,la)", cookie.getCommentURL());
+        assertEquals("hello", cookie.getPath());
+
+        list = HttpCookie
+                .parse("a  Set-Cookie:name=tes,t;Commenturl;commentuRL=(la,la);path=hello");
+        cookie = list.get(0);
+        assertEquals("(la,la)", cookie.getCommentURL());
+
+
+    }
+
+    /**
+     * java.net.HttpCookie#parse(String) for version conflict cases
+     * @since 1.6
+     */
+    public void test_Parse_versionConflict() {
+        // If attribute expires presents, cookie will be recognized as version
+        // 0. No matter header is Set-cookie or Set-cookie2
+        List<HttpCookie> list = HttpCookie
+                .parse("Set-Cookie2:name=;expires=;discard");
+        HttpCookie cookie = list.get(0);
+        assertEquals(0, cookie.getVersion());
+        assertTrue(cookie.getDiscard());
+
+        list = HttpCookie.parse("Set-Cookie: name=value;port=80");
+        cookie = list.get(0);
+        assertEquals(0, cookie.getVersion());
+        assertEquals("80", cookie.getPortlist());
+
+        // In Set-Cookie header, max-age does not take effect when expires
+        // exists.
+        list = HttpCookie
+                .parse("Set-Cookie:name=test;expires=Tue, 27-Jan-1998 19:14:07 GMT;Max-Age=1000");
+        cookie = list.get(0);
+        assertTrue(cookie.getMaxAge() < 0);
+        assertTrue(cookie.hasExpired());
+        assertFalse(cookie.getDiscard());
+        // Reverse sequence. max-age takes effect and decides the result of
+        // hasExpired() method.
+        list = HttpCookie
+                .parse("Set-Cookie:name=value;max-age=1000;expires=Tue, 17-Jan-1998 19:14:07 GMT;version=1");
+        cookie = list.get(0);
+        assertEquals(0, cookie.getVersion());
+        assertEquals(1000, cookie.getMaxAge());
+        assertFalse(cookie.hasExpired());
+
+        // expires decides the version. Not take Set-cookie header, version into
+        // consideration if expires exists.
+        list = HttpCookie
+                .parse("Set-Cookie2:name=value;max-age=1000;version=1;expires=Tue, 17-Jan-1998 19:07:14 GMT;");
+        cookie = list.get(0);
+        assertEquals(0, cookie.getVersion());
+        assertEquals(1000, cookie.getMaxAge());
+        assertFalse(cookie.hasExpired());
+
+        // expires does not cover other version 1 attributes.
+        list = HttpCookie
+                .parse("Set-Cookie2: name=value;expires=Sun, 27-Jan-2018 19:14:07 GMT;comment=mycomment;port=80,8080");
+        cookie = list.get(0);
+        assertEquals(0, cookie.getVersion());
+        assertEquals("80,8080", cookie.getPortlist());
+        assertEquals("mycomment", cookie.getComment());
+
+        // When expires does not exist, version takes effect.
+        list = HttpCookie.parse("Set-Cookie:name=test;Version=1");
+        cookie = list.get(0);
+        assertEquals(1, cookie.getVersion());
+        assertEquals(-1, cookie.getMaxAge());
+        list = HttpCookie.parse("Set-Cookie:name=test;vERsion=0;Version=1;versioN=0;vErsIon=1");
+        cookie = list.get(0);
+        assertEquals(1, cookie.getVersion());
+
+        // When expires does not exist, max-age takes effect.
+        list = HttpCookie.parse("Set-Cookie:name=test;Max-Age=11");
+        cookie = list.get(0);
+        assertEquals(1, cookie.getVersion());
+        assertEquals(11, cookie.getMaxAge());
+        // other version 1 attributes does not take effect
+        list = HttpCookie
+                .parse("Set-Cookie:name=test;comment=mycomment;commentURL=url;discard;domain=a.b.com;path=temp;port=79;secure");
+        cookie = list.get(0);
+        assertEquals(0, cookie.getVersion());
+    }
+
+    /**
+     * java.net.HttpCookie#parse(String) on multiple threads
+     * Regression test for HARMONY-6307
+     * @since 1.6
+     */
+    class ParseThread extends Thread {
+        public AssertionError error = null;
+
+        public void run() {
+            try {
+                for (int i = 0; i < 200; i++) {
+                    List<HttpCookie> list = HttpCookie.parse("Set-cookie:PREF=test;path=/;domain=.b.c;");
+                    assertEquals(1, list.size());
+                    HttpCookie cookie = list.get(0);
+                    assertEquals(0, cookie.getVersion());
+                    assertEquals(".b.c", cookie.getDomain());
+                }
+            } catch (AssertionError e) {
+                error = e;
+            }
+        }
+    }
+
+    public void test_Parse_multipleThreads() throws InterruptedException {
+        ParseThread[] threads = new ParseThread[10];
+        // create threads
+        for (int i = 0; i < threads.length; i++) {
+            threads[i] = new ParseThread();
+        }
+
+        // start threads
+        for (ParseThread thread : threads) {
+            thread.start();
+        }
+
+        // wait for threads to finish
+        for (ParseThread thread : threads) {
+            thread.join();
+        }
+
+        for (ParseThread thread : threads) {
+            if (thread.error != null) {
+                fail("Assertion thrown in thread " + thread + ": " + thread.error);
+            }
+        }
+    }
+
+    private void checkValidValue(String header, String value) {
+        List<HttpCookie> list = HttpCookie
+                .parse(header + "name=" + value + ";");
+        HttpCookie cookie = list.get(0);
+        assertEquals(value, cookie.getValue());
+    }
+
+    private void checkInvalidCookie(String header) {
+        try {
+            HttpCookie.parse(header);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        // version 0 cookie only takes effect on Locale.ENGLISH
+        locale = Locale.getDefault();
+        Locale.setDefault(Locale.ENGLISH);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        Locale.setDefault(locale);
+        super.tearDown();
+    }
+
+}
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..534fb6e
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/IDNTest.java
@@ -0,0 +1,156 @@
+/* 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 {
+
+    /**
+     * {@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"));
+    }
+
+    /**
+     * {@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));
+    }
+
+    /**
+     * {@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"));
+    }
+
+    /**
+     * {@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/Inet4AddressTest.java b/luni/src/test/java/tests/api/java/net/Inet4AddressTest.java
new file mode 100644
index 0000000..87fb6df
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/Inet4AddressTest.java
@@ -0,0 +1,346 @@
+/*
+ *  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.io.Serializable;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class Inet4AddressTest extends junit.framework.TestCase {
+
+    /**
+     * java.net.Inet4Address#isMulticastAddress()
+     */
+    public void test_isMulticastAddress() throws Exception {
+
+        // Create 2 IP v4 addresses and call "isMulticastAddress()"
+        // result should return true if the first 4 bits of the
+        // address are: 1110, false otherwise
+        // Make 1 address with 1110, and 1 without
+        String addrName = "";
+        addrName = "224.0.0.0"; // a multicast addr 1110 = 224-239
+        InetAddress addr = InetAddress.getByName(addrName);
+        assertTrue("Multicast address " + addrName + " not detected.", addr
+                .isMulticastAddress());
+
+        addrName = "239.255.255.255"; // a multicast addr 1110 = 224-239
+        addr = InetAddress.getByName(addrName);
+        assertTrue("Multicast address " + addrName + " not detected.", addr
+                .isMulticastAddress());
+
+        addrName = "42.42.42.42"; // a non-multicast address
+        addr = InetAddress.getByName(addrName);
+        assertTrue("Non multicast address " + addrName
+                + " reporting as a multicast address.", !addr
+                .isMulticastAddress());
+
+    }
+
+    public void test_isAnyLocalAddress() throws Exception {
+        assertTrue(InetAddress.getByName("0.0.0.0").isAnyLocalAddress());
+        assertFalse(InetAddress.getByName("127.0.0.1").isAnyLocalAddress());
+    }
+
+    public void test_isLoopbackAddress() throws Exception {
+        // Create some IP V4 addresses and test if they are local...
+
+        String addrName = "";
+
+        addrName = "127.0.0.0"; // a loopback address should be 127.d.d.d
+        InetAddress addr = InetAddress.getByName(addrName);
+        assertTrue("Loopback address " + addrName + " not detected.", addr
+                .isLoopbackAddress());
+
+        addrName = "127.42.42.42"; // a loopback address should be
+        // 127.d.d.d
+        addr = InetAddress.getByName(addrName);
+        assertTrue("Loopback address " + addrName + " not detected.", addr
+                .isLoopbackAddress());
+
+        addrName = "42.42.42.42"; // a loopback address should be
+        // 127.d.d.d
+        addr = InetAddress.getByName(addrName);
+        assertTrue("Address incorrectly " + addrName
+                + " detected as a loopback address.", !addr
+                .isLoopbackAddress());
+    }
+
+    /**
+     * java.net.Inet4Address#isLinkLocalAddress()
+     */
+    public void test_isLinkLocalAddress() throws Exception {
+
+        String addrName = "";
+        // There are no link local addresses for IPv4
+        // We'll test one to ensure we get "false"
+
+        addrName = "42.42.42.42";
+        InetAddress addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 address " + addrName
+                + " incorrectly reporting as a link local address.", !addr
+                .isLinkLocalAddress());
+    }
+
+    /**
+     * java.net.Inet4Address#isSiteLocalAddress()
+     */
+    public void test_isSiteLocalAddress() throws Exception {
+        String addrName = "";
+        // There are no site local addresses for IPv4
+        // We'll test one to ensure we get "false"
+
+        addrName = "42.42.42.42";
+        InetAddress addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 address " + addrName
+                + " incorrectly reporting as a site local address.", !addr
+                .isSiteLocalAddress());
+    }
+
+    /**
+     * java.net.Inet4Address#isMCGlobal()
+     */
+    public void test_isMCGlobal() throws Exception {
+
+        // Create an IPv4 mulitcast address. It should return
+        // false for globabl mutlicast. There are no valid IPv4
+        // global multicast addresses
+
+        String addrName = "";
+        addrName = "224.0.0.0"; // a multicast addr 1110
+        InetAddress addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 link-local multicast address " + addrName
+                + " incorrectly identified as a global multicast address.",
+                !addr.isMCGlobal());
+
+        addrName = "224.0.0.255"; // a multicast addr 1110
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 link-local multicast address " + addrName
+                + " incorrectly identified as a global multicast address.",
+                !addr.isMCGlobal());
+
+        addrName = "224.0.1.0"; // a multicast addr 1110
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 global multicast address " + addrName
+                + " not identified as a global multicast address.", addr
+                .isMCGlobal());
+
+        addrName = "238.255.255.255"; // a multicast addr 1110
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 global multicast address " + addrName
+                + " not identified as a global multicast address.", addr
+                .isMCGlobal());
+
+        addrName = "239.0.0.0"; // a multicast addr 1110
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 reserved multicast address " + addrName
+                + " incorrectly identified as a global multicast address.",
+                !addr.isMCGlobal());
+
+        addrName = "239.191.255.255"; // a multicast addr 1110
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 reserved multicast address " + addrName
+                + " incorrectly identified as a global multicast address.",
+                !addr.isMCGlobal());
+    }
+
+    /**
+     * java.net.Inet4Address#isMCNodeLocal()
+     */
+    public void test_isMCNodeLocal() throws Exception {
+        // Create an IPv4 mulitcast address. It should return
+        // false for node-local mutlicast. There are no valid IPv4
+        // node-local multicast addresses
+
+        String addrName = "";
+        addrName = "224.42.42.42"; // a multicast addr 1110 = 224
+        InetAddress addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv4 multicast address "
+                        + addrName
+                        + " incorrectly identified as a node-local multicast address.",
+                !addr.isMCNodeLocal());
+
+        addrName = "239.0.0.0"; // a multicast addr 1110
+        addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv4 reserved multicast address "
+                        + addrName
+                        + " incorrectly identified as a node-local multicast address.",
+                !addr.isMCNodeLocal());
+    }
+
+    /**
+     * java.net.Inet4Address#isMCLinkLocal()
+     */
+    public void test_isMCLinkLocal() throws Exception {
+        // Create an IPv4 mulitcast address. It should return
+        // false for link-local mutlicast. There are no valid IPv4
+        // link-local multicast addresses
+
+        String addrName = "";
+        addrName = "224.0.0.0"; // a multicast addr 1110
+        InetAddress addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 link-local multicast address " + addrName
+                + " not identified as a link-local multicast address.",
+                addr.isMCLinkLocal());
+
+        addrName = "224.0.0.255"; // a multicast addr 1110
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 link-local multicast address " + addrName
+                + " not identified as a link-local multicast address.",
+                addr.isMCLinkLocal());
+
+        addrName = "224.0.1.0"; // a multicast addr 1110
+        addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv4 global multicast address "
+                        + addrName
+                        + " incorrectly identified as a link-local multicast address.",
+                !addr.isMCLinkLocal());
+
+        addrName = "239.0.0.0"; // a multicast addr 1110
+        addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv4 reserved multicast address "
+                        + addrName
+                        + " incorrectly identified as a link-local multicast address.",
+                !addr.isMCLinkLocal());
+    }
+
+    /**
+     * java.net.Inet4Address#isMCSiteLocal()
+     */
+    public void test_isMCSiteLocal() throws Exception {
+        // Create an IPv4 mulitcast address. It should return
+        // false for site-local mutlicast. There are no valid IPv4
+        // site-local multicast addresses
+
+        String addrName = "";
+        addrName = "240.0.0.0"; // a multicast addr 1110 = 224
+        InetAddress addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv4 multicast address "
+                        + addrName
+                        + " incorrectly identified as a site-local multicast address.",
+                !addr.isMCSiteLocal());
+
+        addrName = "239.0.0.0"; // a multicast addr 1110
+        addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv4 reserved multicast address "
+                        + addrName
+                        + " incorrectly identified as a site-local multicast address.",
+                !addr.isMCSiteLocal());
+
+        addrName = "239.255.0.0"; // a multicast addr 1110
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 site-local multicast address " + addrName
+                + " not identified as a site-local multicast address.",
+                addr.isMCSiteLocal());
+
+        addrName = "239.255.255.255"; // a multicast addr 1110
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 site-local multicast address " + addrName
+                + " not identified as a site-local multicast address.",
+                addr.isMCSiteLocal());
+
+        addrName = "239.255.2.2"; // a multicast addr 1110
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 site-local multicast address " + addrName
+                + " not identified as a site-local multicast address.",
+                addr.isMCSiteLocal());
+    }
+
+    /**
+     * java.net.Inet4Address#isMCOrgLocal()
+     */
+    public void test_isMCOrgLocal() throws Exception {
+        // Create an IPv4 mulitcast address. It should return
+        // false for organization-local mutlicast. There are no valid IPv4
+        // organization-local multicast addresses
+
+        String addrName = "";
+
+        addrName = "239.191.255.255"; // a multicast addr 1110
+        InetAddress addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv4 reserved multicast address "
+                        + addrName
+                        + " incorrectly identified as a org-local multicast address.",
+                !addr.isMCOrgLocal());
+
+        addrName = "239.252.0.0"; // a multicast addr 1110
+        addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv4 site-local multicast address "
+                        + addrName
+                        + " incorrectly identified as a org-local multicast address.",
+                !addr.isMCOrgLocal());
+
+        addrName = "239.192.0.0"; // a multicast addr 1110
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 org-local multicast address " + addrName
+                + " not identified as a org-local multicast address.", addr
+                .isMCOrgLocal());
+
+        addrName = "239.195.255.255"; // a multicast addr 1110
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 org-local multicast address " + addrName
+                + " not identified as a org-local multicast address.", addr
+                .isMCOrgLocal());
+    }
+
+    // comparator for Inet4Address objects
+    private static final SerializableAssert COMPARATOR = new SerializableAssert() {
+        public void assertDeserialized(Serializable initial,
+                Serializable deserialized) {
+
+            Inet4Address initAddr = (Inet4Address) initial;
+            Inet4Address desrAddr = (Inet4Address) deserialized;
+
+            byte[] iaAddresss = initAddr.getAddress();
+            byte[] deIAAddresss = desrAddr.getAddress();
+            for (int i = 0; i < iaAddresss.length; i++) {
+                assertEquals(iaAddresss[i], deIAAddresss[i]);
+            }
+            assertEquals(4, deIAAddresss.length);
+            assertEquals(initAddr.getHostName(), desrAddr.getHostName());
+        }
+    };
+
+    /**
+     * serialization/deserialization compatibility.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        SerializationTest.verifySelf(Inet4Address.getByName("localhost"),
+                COMPARATOR);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        SerializationTest.verifyGolden(this, Inet4Address
+                .getByName("localhost"), COMPARATOR);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/Inet6AddressTest.java b/luni/src/test/java/tests/api/java/net/Inet6AddressTest.java
new file mode 100644
index 0000000..ee62fd9
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/Inet6AddressTest.java
@@ -0,0 +1,916 @@
+/*
+ *  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.io.Serializable;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.UnknownHostException;
+import java.util.Locale;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class Inet6AddressTest extends junit.framework.TestCase {
+    public void test_isMulticastAddress() throws Exception {
+
+        String addrName = "";
+        InetAddress addr = null;
+
+        // IP V6 regular multicast and non-multicast tests
+        //
+        // Create 2 IP v6 addresses and call "isMulticastAddress()"
+        // A prefix of "11111111" means that the address is multicast
+        // The first one will be one with the prefix the second without
+
+        addrName = "FFFF::42:42"; // 11111111 = FFFF
+        addr = InetAddress.getByName(addrName);
+        assertTrue("Multicast address " + addrName + " not detected.", addr
+                .isMulticastAddress());
+
+        addrName = "42::42:42"; // an non-multicast address
+        addr = InetAddress.getByName(addrName);
+        assertTrue("Non multicast address " + addrName
+                + " reporting as a multicast address.", !addr
+                .isMulticastAddress());
+
+        // IPv4-compatible IPv6 address tests
+        //
+        // Now create 2 IP v6 addresses that are IP v4 compatable
+        // to IP v6 addresses. The address prefix for a multicast ip v4
+        // address is 1110 for the last 16 bits ::d.d.d.d
+        // We expect these to be false
+
+        addrName = "::224.42.42.42"; // an ipv4 multicast addr 1110 = 224
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 compatable address " + addrName
+                + " reported incorrectly as multicast.", !addr
+                .isMulticastAddress());
+
+        addrName = "::42.42.42.42"; // an ipv4 non-multicast address
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 compatable address " + addrName
+                + " reported incorrectly as multicast.", !addr
+                .isMulticastAddress());
+
+        // IPv4-mapped IPv6 address tests
+        //
+        // Now create 2 IP v6 addresses that are IP v4 compatable
+        // to IP v6 addresses. The address prefix for a multicast ip v4
+        // address is 1110 for the last 16 bits ::FFFF:d.d.d.d
+
+        addrName = "::FFFF:224.42.42.42"; // an ipv4 multicast addr 1110 =
+        // 224
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4-mapped IPv6 multicast address " + addrName
+                + " not detected.", addr.isMulticastAddress());
+
+        addrName = "::FFFF:42.42.42.42"; // an ipv4 non-multicast address
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4-mapped IPv6 non-multicast address " + addrName
+                + " reporting as a multicast address.", !addr
+                .isMulticastAddress());
+    }
+
+    public void test_isAnyLocalAddress() throws Exception {
+
+        String addrName = "";
+        InetAddress addr = null;
+
+        // test to ensure that the unspecified address returns tru
+        addrName = "::0"; // The unspecified address
+        addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "The unspecified (also known as wildcard and any local address) "
+                        + addrName + " not detected.", addr
+                .isAnyLocalAddress());
+
+        addrName = "::"; // another form of the unspecified address
+        addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "The unspecified (also known as wildcard and any local address) "
+                        + addrName + " not detected.", addr
+                .isAnyLocalAddress());
+
+        addrName = "::1"; // The loopback address
+        addr = InetAddress.getByName(addrName);
+        assertTrue("The addresses " + addrName
+                + " incorrectly reporting an the unspecified address.",
+                !addr.isAnyLocalAddress());
+    }
+
+    public void test_isLoopbackAddress() throws Exception {
+
+        String addrName = "";
+        // IP V6 regular address tests for loopback
+        // The loopback address for IPv6 is ::1
+
+        addrName = "::1";
+        InetAddress addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 loopback address " + addrName + " not detected.",
+                addr.isLoopbackAddress());
+
+        addrName = "::2";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 address incorrectly " + addrName
+                + " detected as a loopback address.", !addr
+                .isLoopbackAddress());
+
+        // a loopback address should be 127.d.d.d
+        addrName = "42:42::42:42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 address incorrectly " + addrName
+                + " detected as a loopback address.", !addr
+                .isLoopbackAddress());
+
+        // IPv4-compatible IPv6 address tests
+        //
+        // Now create 2 IP v6 addresses that are IP v4 compatable
+        // to IP v6 addresses. The address prefix for a multicast ip v4
+        // address is 1110 for the last 16 bits ::d.d.d.d
+        // We expect these to be false, as they are not IPv4 addresses
+
+        // a loopback address should be 127.d.d.d
+        addrName = "::127.0.0.0";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4-compatible IPv6 address " + addrName
+                + " detected incorrectly as a loopback.", !addr
+                .isLoopbackAddress());
+
+        addrName = "::127.42.42.42"; // a loopback address should be
+        // 127.d.d.d
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4-compatible IPv6 address " + addrName
+                + " detected incorrectly as a loopback.", !addr
+                .isLoopbackAddress());
+
+        // a loopback address should be 127.d.d.d
+        addrName = "::42.42.42.42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4-compatible IPv6 address " + addrName
+                + " detected incorrectly as a loopback.", !addr
+                .isLoopbackAddress());
+
+        // IPv4-mapped IPv6 address tests
+        //
+        // Now create 2 IP v6 addresses that are IP v4 compatable
+        // to IP v6 addresses. The address prefix for a multicast ip v4
+        // address is 1110 for the last 16 bits ::FFFF:d.d.d.d
+
+        // a loopback address should be 127.d.d.d
+        addrName = "::FFFF:127.0.0.0";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4-compatible IPv6 loopback address " + addrName
+                + " not detected.", addr.isLoopbackAddress());
+
+        // a loopback address should be 127.d.d.d
+        addrName = "::FFFF:127.42.42.42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4-compatible IPv6 loopback address " + addrName
+                + " not detected.", addr.isLoopbackAddress());
+
+        // a loopback address should be 127.d.d.d
+        addrName = "::FFFF:42.42.42.42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4-compatible IPv6 address incorrectly " + addrName
+                + " detected as a loopback address.", !addr
+                .isLoopbackAddress());
+    }
+
+    public void test_isLinkLocalAddress() throws Exception {
+
+        String addrName = "";
+        // IP V6 regular address tests for link local addresses
+        //
+        // Link local addresses are FE80:: -
+        // FEBF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
+
+        addrName = "FE80::0";
+        InetAddress addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv6 link local address " + addrName + " not detected.",
+                addr.isLinkLocalAddress());
+
+        addrName = "FEBF::FFFF:FFFF:FFFF:FFFF";
+        addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv6 link local address " + addrName + " not detected.",
+                addr.isLinkLocalAddress());
+
+        addrName = "FEC0::1";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 address " + addrName
+                + " detected incorrectly as a link local address.", !addr
+                .isLinkLocalAddress());
+
+        addrName = "FD80::1:FFFF:FFFF:FFFF:FFFF";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 address " + addrName
+                + " detected incorrectly as a link local address.", !addr
+                .isLinkLocalAddress());
+
+        addrName = "FE7F::FFFF:FFFF:FFFF:FFFF";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 address " + addrName
+                + " detected incorrectly as a link local address.", !addr
+                .isLinkLocalAddress());
+    }
+
+    public void test_isSiteLocalAddress() throws Exception {
+        String addrName = "";
+
+        // IP V6 regular address tests for link local addresses
+        //
+        // Link local addresses are FEC0::0 through to
+        // FEFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
+
+        addrName = "FEC0::0";
+        InetAddress addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv6 site local address " + addrName + " not detected.",
+                addr.isSiteLocalAddress());
+
+        addrName = "FEFF::FFFF:FFFF:FFFF:FFFF:FFFF";
+        addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv6 site local address " + addrName + " not detected.",
+                addr.isSiteLocalAddress());
+
+        addrName = "FEBF::FFFF:FFFF:FFFF:FFFF:FFFF";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 address " + addrName
+                + " detected incorrectly as a site local address.", !addr
+                .isSiteLocalAddress());
+
+        addrName = "FFC0::0";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 address " + addrName
+                + " detected incorrectly as a site local address.", !addr
+                .isSiteLocalAddress());
+    }
+
+    public void test_isMCGlobal() throws Exception {
+        String addrName = "";
+        // IP V6 regular address tests for Mulitcase Global addresses
+        //
+        // Multicast global addresses are FFxE:/112 where x is
+        // a set of flags, and the addition 112 bits make up
+        // the global address space
+
+        addrName = "FF0E::0";
+        InetAddress addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 global mutlicast address " + addrName
+                + " not detected.", addr.isMCGlobal());
+
+        addrName = "FF0E:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 global multicast address " + addrName
+                + " not detected.", addr.isMCGlobal());
+
+        // a currently invalid address as the prefix FFxE
+        // is only valid for x = {1,0} as the rest are reserved
+        addrName = "FFFE::0";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 global mutlicast address " + addrName
+                + " not detected.", addr.isMCGlobal());
+
+        // a currently invalid address as the prefix FFxE
+        // is only valid for x = {1,0} as the rest are reserved
+        addrName = "FFFE:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 global multicast address " + addrName
+                + " not detected.", addr.isMCGlobal());
+
+        // a sample MC organizational address
+        addrName = "FF08:42:42:42:42:42:42:42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 mulitcast organizational " + addrName
+                + " incorrectly indicated as a global address.", !addr
+                .isMCGlobal());
+
+        // a sample MC site address
+        addrName = "FF05:42:42:42:42:42:42:42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 mulitcast site address " + addrName
+                + " incorrectly indicated as a global address.", !addr
+                .isMCGlobal());
+
+        // a sample MC link address
+        addrName = "FF02:42:42:42:42:42:42:42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 mulitcast link address " + addrName
+                + " incorrectly indicated as a global address.", !addr
+                .isMCGlobal());
+
+        // a sample MC Node
+        addrName = "FF01:42:42:42:42:42:42:42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 mulitcast node address " + addrName
+                + " incorrectly indicated as a global address.", !addr
+                .isMCGlobal());
+
+        // IPv4-mapped IPv6 address tests
+        addrName = "::FFFF:224.0.1.0";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 global multicast address " + addrName
+                + " not identified as a global multicast address.", addr
+                .isMCGlobal());
+
+        addrName = "::FFFF:238.255.255.255";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 global multicast address " + addrName
+                + " not identified as a global multicast address.", addr
+                .isMCGlobal());
+    }
+
+    public void test_isMCNodeLocal() throws Exception {
+        String addrName = "";
+        // IP V6 regular address tests for Mulitcase node local addresses
+        //
+        // Multicast node local addresses are FFx1:/112 where x is
+        // a set of flags, and the addition 112 bits make up
+        // the global address space
+
+        addrName = "FF01::0";
+        InetAddress addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 node-local mutlicast address " + addrName
+                + " not detected.", addr.isMCNodeLocal());
+
+        addrName = "FF01:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 node-local multicast address " + addrName
+                + " not detected.", addr.isMCNodeLocal());
+
+        // a currently invalid address as the prefix FFxE
+        // is only valid for x = {1,0} as the rest are reserved
+        addrName = "FFF1::0";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 node-local mutlicast address " + addrName
+                + " not detected.", addr.isMCNodeLocal());
+
+        // a currently invalid address as the prefix FFxE
+        // is only valid for x = {1,0} as the rest are reserved
+        addrName = "FFF1:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 node-local multicast address " + addrName
+                + " not detected.", addr.isMCNodeLocal());
+
+        // a sample MC organizational address
+        addrName = "FF08:42:42:42:42:42:42:42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 mulitcast organizational address " + addrName
+                + " incorrectly indicated as a node-local address.", !addr
+                .isMCNodeLocal());
+
+        // a sample MC site address
+        addrName = "FF05:42:42:42:42:42:42:42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 mulitcast site address " + addrName
+                + " incorrectly indicated as a node-local address.", !addr
+                .isMCNodeLocal());
+
+        // a sample MC link address
+        addrName = "FF02:42:42:42:42:42:42:42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 mulitcast link address " + addrName
+                + " incorrectly indicated as a node-local address.", !addr
+                .isMCNodeLocal());
+
+        // a sample MC global address
+        addrName = "FF0E:42:42:42:42:42:42:42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 mulitcast node address " + addrName
+                + " incorrectly indicated as a node-local address.", !addr
+                .isMCNodeLocal());
+    }
+
+    public void test_isMCLinkLocal() throws Exception {
+        String addrName = "";
+        // IP V6 regular address tests for Mulitcase link local addresses
+        //
+        // Multicast link local addresses are FFx2:/112 where x is
+        // a set of flags, and the addition 112 bits make up
+        // the global address space
+
+        addrName = "FF02::0";
+        InetAddress addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 link local multicast address " + addrName
+                + " not detected.", addr.isMCLinkLocal());
+
+        addrName = "FF02:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 link local multicast address " + addrName
+                + " not detected.", addr.isMCLinkLocal());
+
+        // a currently invalid address as the prefix FFxE
+        // is only valid for x = {1,0} as the rest are reserved
+        addrName = "FFF2::0";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 link local multicast address " + addrName
+                + " not detected.", addr.isMCLinkLocal());
+
+        // a currently invalid address as the prefix FFxE
+        // is only valid for x = {1,0} as the rest are reserved
+        addrName = "FFF2:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 link local multicast address " + addrName
+                + " not detected.", addr.isMCLinkLocal());
+
+        // a sample MC organizational address
+        addrName = "FF08:42:42:42:42:42:42:42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv6 organization multicast address "
+                        + addrName
+                        + " incorrectly indicated as a link-local mulitcast address.",
+                !addr.isMCLinkLocal());
+
+        // a sample MC site address
+        addrName = "FF05:42:42:42:42:42:42:42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv6 site-local mulitcast address "
+                        + addrName
+                        + " incorrectly indicated as a link-local mulitcast address.",
+                !addr.isMCLinkLocal());
+
+        // a sample MC global address
+        addrName = "FF0E:42:42:42:42:42:42:42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv6 global multicast address "
+                        + addrName
+                        + " incorrectly indicated as a link-local mulitcast address.",
+                !addr.isMCLinkLocal());
+
+        // a sample MC Node
+        addrName = "FF01:42:42:42:42:42:42:42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv6 mulitcast node address "
+                        + addrName
+                        + " incorrectly indicated as a link-local mulitcast address.",
+                !addr.isMCLinkLocal());
+
+        // Ipv4-mapped IPv6 addresses
+
+        addrName = "::FFFF:224.0.0.0"; // a multicast addr 1110
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 link-local multicast address " + addrName
+                + " not identified as a link-local multicast address.",
+                addr.isMCLinkLocal());
+
+        addrName = "::FFFF:224.0.0.255"; // a multicast addr 1110
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 link-local multicast address " + addrName
+                + " not identified as a link-local multicast address.",
+                addr.isMCLinkLocal());
+    }
+
+    public void test_isMCSiteLocal() throws Exception {
+        String addrName = "";
+        // IP V6 regular address tests for Multicast site-local addresses
+        //
+        // Multicast global addresses are FFx5:/112 where x is
+        // a set of flags, and the addition 112 bits make up
+        // the global address space
+
+        addrName = "FF05::0";
+        InetAddress addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 site-local mutlicast address " + addrName
+                + " not detected.", addr.isMCSiteLocal());
+
+        addrName = "FF05:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 site-local multicast address " + addrName
+                + " not detected.", addr.isMCSiteLocal());
+
+        // a currently invalid address as the prefix FFxE
+        // is only valid for x = {1,0} as the rest are reserved
+        addrName = "FFF5::0";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 site-local mutlicast address " + addrName
+                + " not detected.", addr.isMCSiteLocal());
+
+        // a currently invalid address as the prefix FFxE
+        // is only valid for x = {1,0} as the rest are reserved
+        addrName = "FFF5:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 site-local multicast address " + addrName
+                + " not detected.", addr.isMCSiteLocal());
+
+        // a sample MC organizational address
+        addrName = "FF08:42:42:42:42:42:42:42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv6 organization multicast address "
+                        + addrName
+                        + " incorrectly indicated as a site-local mulitcast address.",
+                !addr.isMCSiteLocal());
+
+        // a sample MC global address
+        addrName = "FF0E:42:42:42:42:42:42:42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv6 global mulitcast address "
+                        + addrName
+                        + " incorrectly indicated as a site-local mulitcast address.",
+                !addr.isMCSiteLocal());
+
+        // a sample MC link address
+        addrName = "FF02:42:42:42:42:42:42:42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv6 link-local multicast address "
+                        + addrName
+                        + " incorrectly indicated as a site-local mulitcast address.",
+                !addr.isMCSiteLocal());
+
+        // a sample MC Node
+        addrName = "FF01:42:42:42:42:42:42:42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv6 mulitcast node address "
+                        + addrName
+                        + " incorrectly indicated as a site-local mulitcast address.",
+                !addr.isMCSiteLocal());
+
+        // IPv4-mapped IPv6 addresses
+        addrName = "::FFFF:239.255.0.0";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 site-local multicast address " + addrName
+                + " not identified as a site-local multicast address.",
+                addr.isMCSiteLocal());
+
+        addrName = "::FFFF:239.255.255.255";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 site-local multicast address " + addrName
+                + " not identified as a site-local multicast address.",
+                addr.isMCSiteLocal());
+    }
+
+    public void test_isMCOrgLocal() throws Exception {
+        String addrName = "";
+        // IP V6 regular address tests for Mulitcase organization-local
+        // addresses
+        //
+        // Multicast global addresses are FFxE:/112 where x is
+        // a set of flags, and the addition 112 bits make up
+        // the global address space
+
+        addrName = "FF08::0";
+        InetAddress addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 organization-local mutlicast address " + addrName
+                + " not detected.", addr.isMCOrgLocal());
+
+        addrName = "FF08:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 organization-local multicast address " + addrName
+                + " not detected.", addr.isMCOrgLocal());
+
+        // a currently invalid address as the prefix FFxE
+        // is only valid for x = {1,0} as the rest are reserved
+        addrName = "FFF8::0";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 organization-local mutlicast address " + addrName
+                + " not detected.", addr.isMCOrgLocal());
+
+        // a currently invalid address as the prefix FFxE
+        // is only valid for x = {1,0} as the rest are reserved
+        addrName = "FFF8:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv6 organization-local multicast address " + addrName
+                + " not detected.", addr.isMCOrgLocal());
+
+        // a sample MC global address
+        addrName = "FF0E:42:42:42:42:42:42:42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv6 global multicast address "
+                        + addrName
+                        + " incorrectly indicated as an organization-local mulitcast address.",
+                !addr.isMCOrgLocal());
+
+        // a sample MC site address
+        addrName = "FF05:42:42:42:42:42:42:42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv6 site-local mulitcast address "
+                        + addrName
+                        + " incorrectly indicated as an organization-local mulitcast address.",
+                !addr.isMCOrgLocal());
+
+        // a sample MC link address
+        addrName = "FF02:42:42:42:42:42:42:42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv6 link-local multicast address "
+                        + addrName
+                        + " incorrectly indicated as an organization-local mulitcast address.",
+                !addr.isMCOrgLocal());
+
+        // a sample MC Node
+        addrName = "FF01:42:42:42:42:42:42:42";
+        addr = InetAddress.getByName(addrName);
+        assertTrue(
+                "IPv6 mulitcast node address "
+                        + addrName
+                        + " incorrectly indicated as an organization-local mulitcast address.",
+                !addr.isMCOrgLocal());
+
+        // IPv4-mapped IPv6 addresses
+
+        addrName = "::FFFF:239.192.0.0";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 org-local multicast address " + addrName
+                + " not identified as a org-local multicast address.", addr
+                .isMCOrgLocal());
+
+        addrName = "::FFFF:239.195.255.255";
+        addr = InetAddress.getByName(addrName);
+        assertTrue("IPv4 org-local multicast address " + addrName
+                + " not identified as a org-local multicast address.", addr
+                .isMCOrgLocal());
+    }
+
+    public void test_isIPv4CompatibleAddress() throws Exception {
+        String addrName = "";
+        Inet6Address addr = null;
+
+        // Tests a number of addresses to see if they are compatable with
+        // IPv6 addresses
+
+        addrName = "FFFF::42:42"; // 11111111 = FFFF
+        addr = (Inet6Address) InetAddress.getByName(addrName);
+        assertTrue("A non-compatable IPv6 address " + addrName
+                + " incorrectly identified as a IPv4 compatable address.",
+                !addr.isIPv4CompatibleAddress());
+
+        // IPv4-compatible IPv6 address tests
+        //
+        // Now create 2 IP v6 addresses that are IP v4 compatable
+        // to IP v6 addresses.
+
+        addrName = "::0.0.0.0";
+        addr = (Inet6Address) InetAddress.getByName(addrName);
+        assertTrue("IPv4 compatable address " + addrName
+                + " not detected correctly.", addr
+                .isIPv4CompatibleAddress());
+
+        addrName = "::255.255.255.255"; // an ipv4 non-multicast address
+        addr = (Inet6Address) InetAddress.getByName(addrName);
+        assertTrue("IPv4 compatable address " + addrName
+                + " not detected correctly.", addr
+                .isIPv4CompatibleAddress());
+    }
+
+    public void test_getByNameLjava_lang_String() throws Exception {
+        // ones to add "::255.255.255.255", "::FFFF:0.0.0.0",
+        // "0.0.0.0.0.0::255.255.255.255", "F:F:F:F:F:F:F:F",
+        // "[F:F:F:F:F:F:F:F]"
+        String validIPAddresses[] = { "::1.2.3.4", "::", "::", "1::0", "1::",
+                "::1", "0", /* jdk1.5 accepts 0 as valid */
+                "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF",
+                "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255",
+                "0:0:0:0:0:0:0:0", "0:0:0:0:0:0:0.0.0.0" };
+
+        String invalidIPAddresses[] = { "FFFF:FFFF" };
+
+        for (int i = 0; i < validIPAddresses.length; i++) {
+
+            InetAddress.getByName(validIPAddresses[i]);
+
+            //exercise positive cache
+            InetAddress.getByName(validIPAddresses[i]);
+
+            if (!validIPAddresses[i].equals("0")) {
+                String tempIPAddress = "[" + validIPAddresses[i] + "]";
+                InetAddress.getByName(tempIPAddress);
+            }
+        }
+
+        for (int i = 0; i < invalidIPAddresses.length; i++) {
+            try {
+                InetAddress.getByName(invalidIPAddresses[i]);
+                fail("Invalid IP address incorrectly recognized as valid: "
+                        + invalidIPAddresses[i]);
+            } catch (Exception e) {
+            }
+
+            //exercise negative cache
+            try {
+                InetAddress.getByName(invalidIPAddresses[i]);
+                fail("Invalid IP address incorrectly recognized as valid: "
+                        + invalidIPAddresses[i]);
+            } catch (Exception e) {
+            }
+        }
+    }
+
+    public void test_getByAddressLString$BI() throws UnknownHostException {
+        try {
+            Inet6Address.getByAddress("123", null, 0);
+            fail("should throw UnknownHostException");
+        } catch (UnknownHostException uhe) {
+            // expected
+        }
+        byte[] addr1 = { (byte) 127, 0, 0, 1 };
+        try {
+            Inet6Address.getByAddress("123", addr1, 0);
+            fail("should throw UnknownHostException");
+        } catch (UnknownHostException uhe) {
+            // expected
+        }
+
+        byte[] addr2 = { (byte) 0xFE, (byte) 0x80, 0, 0, 0, 0, 0, 0, 0x02,
+                0x11, 0x25, (byte) 0xFF, (byte) 0xFE, (byte) 0xF8, (byte) 0x7C,
+                (byte) 0xB2 };
+
+        // should not throw any exception
+        Inet6Address.getByAddress("123", addr2, 3);
+        Inet6Address.getByAddress("123", addr2, 0);
+        Inet6Address.getByAddress("123", addr2, -1);
+    }
+
+    public void test_getByAddressLString$BLNetworkInterface()
+            throws UnknownHostException {
+        NetworkInterface nif = null;
+        try {
+            Inet6Address.getByAddress("123", null, nif);
+            fail("should throw UnknownHostException");
+        } catch (UnknownHostException uhe) {
+            // expected
+        }
+        byte[] addr1 = { (byte) 127, 0, 0, 1 };
+        try {
+            Inet6Address.getByAddress("123", addr1, nif);
+            fail("should throw UnknownHostException");
+        } catch (UnknownHostException uhe) {
+            // expected
+        }
+        byte[] addr2 = { (byte) 0xFE, (byte) 0x80, 0, 0, 0, 0, 0, 0, 0x02,
+                0x11, 0x25, (byte) 0xFF, (byte) 0xFE, (byte) 0xF8, (byte)
+
+                0x7C, (byte) 0xB2 };
+        // should not throw any exception
+        Inet6Address.getByAddress("123", addr2, nif);
+    }
+
+    public void test_getHostAddress_() throws Exception {
+        byte[] ipAddress = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+        InetAddress ia = InetAddress.getByAddress(ipAddress);
+        assertEquals("::1", ia.getHostAddress().toLowerCase(Locale.US));
+
+        ipAddress = new byte[] { -2, -128, 0, 0, 0, 0, 0, 0, 2, 17, 37, -1, -2, -8, 124, -79 };
+        ia = InetAddress.getByAddress(ipAddress);
+        assertEquals("fe80::211:25ff:fef8:7cb1", ia.getHostAddress().toLowerCase(Locale.US));
+    }
+
+    public void test_getScopeID() throws UnknownHostException {
+        Inet6Address v6ia;
+        byte[] addr = { (byte) 0xFE, (byte) 0x80, 0, 0, 0, 0, 0, 0, 0x02, 0x11,
+                0x25, (byte) 0xFF, (byte) 0xFE, (byte) 0xF8, (byte) 0x7C,
+                (byte) 0xB2 };
+
+        v6ia = Inet6Address.getByAddress("123", addr, 3);
+        assertEquals(3, v6ia.getScopeId());
+
+        v6ia = Inet6Address.getByAddress("123", addr, 0);
+        assertEquals(0, v6ia.getScopeId());
+
+        v6ia = Inet6Address.getByAddress("123", addr, -1);
+        assertEquals(0, v6ia.getScopeId());
+    }
+
+    public void test_getScopedInterface() throws UnknownHostException {
+        byte[] addr = { (byte) 0xFE, (byte) 0x80, (byte) 0x09, (byte) 0xb5,
+                (byte) 0x6b, (byte) 0xa4, 0, 0, 0, 0, 0, 0, (byte) 0x09,
+                (byte) 0xb5, (byte) 0x6b, (byte) 0xa4 };
+        Inet6Address v6Addr;
+        v6Addr = Inet6Address.getByAddress("123", addr, null);
+        assertNull(v6Addr.getScopedInterface());
+    }
+
+    public void test_hashCode() throws UnknownHostException {
+        byte[] addr = { (byte) 0xFE, (byte) 0x80, 0, 0, 0, 0, 0, 0, 0x02, 0x11,
+                0x25, (byte) 0xFF, (byte) 0xFE, (byte) 0xF8, (byte) 0x7C,
+                (byte) 0xB2 };
+        Inet6Address address1, address2;
+
+        address1 = Inet6Address.getByAddress("123", addr, 0);
+        address2 = Inet6Address.getByAddress("1234", addr, 0);
+        assertEquals(address1.hashCode(), address2.hashCode());
+    }
+
+    int bytesToInt(byte bytes[], int start) {
+
+        int byteMask = 255;
+        int value = ((bytes[start + 3] & byteMask))
+                | ((bytes[start + 2] & byteMask) << 8)
+                | ((bytes[start + 1] & byteMask) << 16)
+                | ((bytes[start] & byteMask) << 24);
+        return value;
+
+    }
+
+    String byteArrayToHexString(byte bytes[], boolean leadingZeros) {
+
+        String fullString = "";
+        int times = bytes.length / 4;
+        int intArray[] = new int[times];
+        for (int i = 0; i < times; i++) {
+            intArray[i] = bytesToInt(bytes, i * 4);
+        }
+
+        return intArrayToHexString(intArray, leadingZeros);
+    }
+
+    void intToBytes(int value, byte bytes[], int start) {
+
+        int byteMask = 255;
+        bytes[start + 3] = (byte) (value & byteMask);
+        bytes[start + 2] = (byte) ((value >> 8) & byteMask);
+        bytes[start + 1] = (byte) ((value >> 16) & byteMask);
+        bytes[start] = (byte) ((value >> 24) & byteMask);
+    }
+
+    String intArrayToHexString(int ints[], boolean leadingZeros) {
+
+        String fullString = "";
+        String tempString;
+        int intsLength = ints.length;
+        for (int i = 0; i < intsLength; i++) {
+            tempString = Integer.toHexString(ints[i]);
+            while (tempString.length() < 4 && leadingZeros) {
+                tempString = "0" + tempString;
+            }
+            if (i + 1 < intsLength) {
+                tempString += ":";
+            }
+            fullString += tempString;
+        }
+
+        return fullString.toUpperCase();
+    }
+
+    // comparator for Inet6Address objects
+    private static final SerializableAssert COMPARATOR = new SerializableAssert() {
+        public void assertDeserialized(Serializable initial,
+                Serializable deserialized) {
+
+            Inet6Address initAddr = (Inet6Address) initial;
+            Inet6Address desrAddr = (Inet6Address) deserialized;
+
+            byte[] iaAddresss = initAddr.getAddress();
+            byte[] deIAAddresss = desrAddr.getAddress();
+            for (int i = 0; i < iaAddresss.length; i++) {
+                assertEquals(iaAddresss[i], deIAAddresss[i]);
+            }
+            assertEquals(initAddr.getScopeId(), desrAddr.getScopeId());
+            assertEquals(initAddr.getScopedInterface(), desrAddr
+                    .getScopedInterface());
+        }
+    };
+
+    /**
+     * Tests serialization/deserialization compatibility with ourselves.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        byte[] localv6 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+
+        SerializationTest.verifySelf(InetAddress.getByAddress(localv6),
+                COMPARATOR);
+    }
+
+    /**
+     * Tests serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        byte[] localv6 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+
+        Object[] addresses = { InetAddress.getByAddress(localv6),
+                // Regression for Harmony-1039: ser-form has
+                // null interface name
+                InetAddress.getByAddress(localv6) };
+
+        SerializationTest.verifyGolden(this, addresses, COMPARATOR);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/InetAddressTest.java b/luni/src/test/java/tests/api/java/net/InetAddressTest.java
new file mode 100644
index 0000000..520b795
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/InetAddressTest.java
@@ -0,0 +1,449 @@
+/*
+ *  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.io.IOException;
+import java.io.Serializable;
+import java.net.DatagramSocket;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.UnknownHostException;
+import java.security.Permission;
+import java.util.ArrayList;
+import java.util.Enumeration;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+import tests.support.Support_Configuration;
+
+public class InetAddressTest extends junit.framework.TestCase {
+
+    /**
+     * java.net.InetAddress#getByName(String)
+     */
+    public void test_getByNameUnknownHostException() {
+        // Related to HARMONY-5784
+
+        // loop a few times to flex the negative cache paths
+        for (int i = 0; i < 5; i++) {
+            try {
+                InetAddress.getByName("unknown.unknown.bad");
+                fail("An UnknownHostException should have been thrown");
+            } catch (UnknownHostException e) {
+                assertTrue(e.getMessage().contains("unknown.unknown.bad"));
+            }
+        }
+    }
+
+    public void test_equalsLjava_lang_Object() throws Exception {
+        InetAddress ia1 = InetAddress.getByName("localhost");
+        InetAddress ia2 = InetAddress.getByName("::1");
+        assertEquals(ia2, ia1);
+    }
+
+    /**
+     * java.net.InetAddress#getAddress()
+     */
+    public void test_getAddress() throws UnknownHostException {
+        // Test for method byte [] java.net.InetAddress.getAddress()
+        try {
+            InetAddress ia = InetAddress.getByName("127.0.0.1");
+            byte[] caddr = new byte[] { 127, 0, 0, 1 };
+            byte[] addr = ia.getAddress();
+            for (int i = 0; i < addr.length; i++)
+                assertTrue("Incorrect address returned", caddr[i] == addr[i]);
+        } catch (java.net.UnknownHostException e) {
+        }
+
+        byte[] origBytes = new byte[] { 0, 1, 2, 3 };
+        InetAddress address = InetAddress.getByAddress(origBytes);
+        origBytes[0] = -1;
+        byte[] newBytes = address.getAddress();
+        assertSame((byte) 0, newBytes[0]);
+    }
+
+    /**
+     * java.net.InetAddress#getAllByName(java.lang.String)
+     */
+    @SuppressWarnings("nls")
+    public void test_getAllByNameLjava_lang_String() throws Exception {
+        // Test for method java.net.InetAddress []
+        // java.net.InetAddress.getAllByName(java.lang.String)
+        InetAddress[] all = InetAddress.getAllByName("localhost");
+        assertNotNull(all);
+        // Number of aliases depends on individual test machine
+        assertTrue(all.length >= 1);
+        for (InetAddress alias : all) {
+            // Check that each alias has the same hostname. Intentionally not
+            // checking for exact string match.
+            assertTrue(alias.getHostName().startsWith("localhost"));
+        }// end for all aliases
+
+        //Regression for HARMONY-56
+        InetAddress[] ias = InetAddress.getAllByName(null);
+        assertEquals(2, ias.length);
+        for (InetAddress ia : ias) {
+            assertTrue(ia.isLoopbackAddress());
+        }
+        ias = InetAddress.getAllByName("");
+        assertEquals(2, ias.length);
+        for (InetAddress ia : ias) {
+            assertTrue(ia.isLoopbackAddress());
+        }
+
+        // Check that getting addresses by dotted string distinguish
+        // IPv4 and IPv6 subtypes.
+        InetAddress[] list = InetAddress.getAllByName("192.168.0.1");
+        for (InetAddress addr : list) {
+            assertFalse("Expected subclass returned",
+                    addr.getClass().equals(InetAddress.class));
+        }
+    }
+
+    /**
+     * java.net.InetAddress#getByName(java.lang.String)
+     */
+    public void test_getByNameLjava_lang_String() throws Exception {
+        // Test for method java.net.InetAddress
+        // java.net.InetAddress.getByName(java.lang.String)
+        InetAddress ia2 = InetAddress.getByName("127.0.0.1");
+
+        // TODO : Test to ensure all the address formats are recognized
+        InetAddress i = InetAddress.getByName("1.2.3");
+        assertEquals("1.2.0.3", i.getHostAddress());
+        i = InetAddress.getByName("1.2");
+        assertEquals("1.0.0.2", i.getHostAddress());
+        i = InetAddress.getByName(String.valueOf(0xffffffffL));
+        assertEquals("255.255.255.255", i.getHostAddress());
+    }
+
+    /**
+     * java.net.InetAddress#getHostAddress()
+     */
+    public void test_getHostAddress() throws Exception {
+        assertEquals("1.2.3.4", InetAddress.getByName("1.2.3.4").getHostAddress());
+        assertEquals("::1", InetAddress.getByName("::1").getHostAddress());
+    }
+
+    /**
+     * java.net.InetAddress#getLocalHost()
+     */
+    public void test_getLocalHost() throws Exception {
+        // Test for method java.net.InetAddress
+        // java.net.InetAddress.getLocalHost()
+
+        // We don't know the host name or ip of the machine
+        // running the test, so we can't build our own address
+        DatagramSocket dg = new DatagramSocket(0, InetAddress
+                .getLocalHost());
+        assertTrue("Incorrect host returned", InetAddress.getLocalHost()
+                .equals(dg.getLocalAddress()));
+        dg.close();
+    }
+
+    /**
+     * java.net.InetAddress#getLocalHost()
+     */
+    public void test_getLocalHost_extended() throws Exception {
+        // Bogus, but we don't know the host name or ip of the machine
+        // running the test, so we can't build our own address
+        DatagramSocket dg = new DatagramSocket(0, InetAddress.getLocalHost());
+        assertEquals("Incorrect host returned", InetAddress.getLocalHost(), dg.getLocalAddress());
+        dg.close();
+    }
+
+    /**
+     * java.net.InetAddress#isMulticastAddress()
+     */
+    public void test_isMulticastAddress() throws UnknownHostException {
+        InetAddress ia2 = InetAddress.getByName("239.255.255.255");
+        assertTrue(ia2.isMulticastAddress());
+        ia2 = InetAddress.getByName("localhost");
+        assertFalse(ia2.isMulticastAddress());
+    }
+
+    /**
+     * java.net.InetAddress#isAnyLocalAddress()
+     */
+    public void test_isAnyLocalAddress() throws UnknownHostException {
+        InetAddress ia2 = InetAddress.getByName("239.255.255.255");
+        assertFalse(ia2.isAnyLocalAddress());
+        ia2 = InetAddress.getByName("localhost");
+        assertFalse(ia2.isAnyLocalAddress());
+    }
+
+    /**
+     * java.net.InetAddress#isLinkLocalAddress()
+     */
+    public void test_isLinkLocalAddress() throws UnknownHostException {
+        InetAddress ia2 = InetAddress.getByName("239.255.255.255");
+        assertFalse(ia2.isLinkLocalAddress());
+        ia2 = InetAddress.getByName("localhost");
+        assertFalse(ia2.isLinkLocalAddress());
+    }
+
+    /**
+     * java.net.InetAddress#isLoopbackAddress()
+     */
+    public void test_isLoopbackAddress() throws UnknownHostException {
+        InetAddress ia2 = InetAddress.getByName("239.255.255.255");
+        assertFalse(ia2.isLoopbackAddress());
+        ia2 = InetAddress.getByName("localhost");
+        assertTrue(ia2.isLoopbackAddress());
+        ia2 = InetAddress.getByName("127.0.0.2");
+        assertTrue(ia2.isLoopbackAddress());
+    }
+
+    /**
+     * java.net.InetAddress#isLoopbackAddress()
+     */
+    public void test_isSiteLocalAddress() throws UnknownHostException {
+        InetAddress ia2 = InetAddress.getByName("239.255.255.255");
+        assertFalse(ia2.isSiteLocalAddress());
+        ia2 = InetAddress.getByName("localhost");
+        assertFalse(ia2.isSiteLocalAddress());
+        ia2 = InetAddress.getByName("127.0.0.2");
+        assertFalse(ia2.isSiteLocalAddress());
+        ia2 = InetAddress.getByName("243.243.45.3");
+        assertFalse(ia2.isSiteLocalAddress());
+        ia2 = InetAddress.getByName("10.0.0.2");
+        assertTrue(ia2.isSiteLocalAddress());
+    }
+
+    /**
+     * java.net.InetAddress#isMCGlobal()/isMCLinkLocal/isMCNodeLocal/isMCOrgLocal/isMCSiteLocal
+     */
+    public void test_isMCVerify() throws UnknownHostException {
+        InetAddress ia2 = InetAddress.getByName("239.255.255.255");
+        assertFalse(ia2.isMCGlobal());
+        assertFalse(ia2.isMCLinkLocal());
+        assertFalse(ia2.isMCNodeLocal());
+        assertFalse(ia2.isMCOrgLocal());
+        assertTrue(ia2.isMCSiteLocal());
+        ia2 = InetAddress.getByName("243.243.45.3");
+        assertFalse(ia2.isMCGlobal());
+        assertFalse(ia2.isMCLinkLocal());
+        assertFalse(ia2.isMCNodeLocal());
+        assertFalse(ia2.isMCOrgLocal());
+        assertFalse(ia2.isMCSiteLocal());
+        ia2 = InetAddress.getByName("250.255.255.254");
+        assertFalse(ia2.isMCGlobal());
+        assertFalse(ia2.isMCLinkLocal());
+        assertFalse(ia2.isMCNodeLocal());
+        assertFalse(ia2.isMCOrgLocal());
+        assertFalse(ia2.isMCSiteLocal());
+        ia2 = InetAddress.getByName("10.0.0.2");
+        assertFalse(ia2.isMCGlobal());
+        assertFalse(ia2.isMCLinkLocal());
+        assertFalse(ia2.isMCNodeLocal());
+        assertFalse(ia2.isMCOrgLocal());
+        assertFalse(ia2.isMCSiteLocal());
+    }
+
+    /**
+     * java.net.InetAddress#toString()
+     */
+    public void test_toString() throws Exception {
+        // Test for method java.lang.String java.net.InetAddress.toString()
+        InetAddress ia2 = InetAddress.getByName("127.0.0.1");
+        assertEquals("/127.0.0.1", ia2.toString());
+        // Regression for HARMONY-84
+        InetAddress addr2 = InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 });
+        assertEquals("Assert 1: wrong string from address", "/127.0.0.1", addr2.toString());
+    }
+
+    /**
+     * java.net.InetAddress#getByAddress(java.lang.String, byte[])
+     */
+    public void test_getByAddressLjava_lang_String$B() {
+        // Check an IPv4 address with an IPv6 hostname
+        byte ipAddress[] = { 127, 0, 0, 1 };
+        String addressStr = "::1";
+        try {
+            InetAddress addr = InetAddress.getByAddress(addressStr, ipAddress);
+            addr = InetAddress.getByAddress(ipAddress);
+        } catch (UnknownHostException e) {
+            fail("Unexpected problem creating IP Address "
+                    + ipAddress.length);
+        }
+
+        byte ipAddress2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 127, 0, 0,
+                1 };
+        addressStr = "::1";
+        try {
+            InetAddress addr = InetAddress.getByAddress(addressStr, ipAddress2);
+            addr = InetAddress.getByAddress(ipAddress);
+        } catch (UnknownHostException e) {
+            fail("Unexpected problem creating IP Address "
+                    + ipAddress.length);
+        }
+    }
+
+    /**
+     * java.net.InetAddress#getCanonicalHostName()
+     */
+    public void test_getCanonicalHostName() throws Exception {
+        InetAddress theAddress = null;
+        theAddress = InetAddress.getLocalHost();
+        assertTrue("getCanonicalHostName returned a zero length string ",
+                theAddress.getCanonicalHostName().length() != 0);
+        assertTrue("getCanonicalHostName returned an empty string ",
+                !theAddress.equals(""));
+    }
+
+    /**
+     * java.net.InetAddress#isReachableI
+     */
+    public void test_isReachableI() throws Exception {
+        InetAddress ia = Inet4Address.getByName("127.0.0.1");
+        assertTrue(ia.isReachable(10000));
+        ia = Inet4Address.getByName("127.0.0.1");
+        try {
+            ia.isReachable(-1);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // correct
+        }
+    }
+
+    /**
+     * java.net.InetAddress#isReachableLjava_net_NetworkInterfaceII
+     */
+    public void test_isReachableLjava_net_NetworkInterfaceII() throws Exception {
+        // tests local address
+        InetAddress ia = Inet4Address.getByName("127.0.0.1");
+        assertTrue(ia.isReachable(null, 0, 10000));
+        ia = Inet4Address.getByName("127.0.0.1");
+        try {
+            ia.isReachable(null, -1, 10000);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // correct
+        }
+        try {
+            ia.isReachable(null, 0, -1);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // correct
+        }
+        try {
+            ia.isReachable(null, -1, -1);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // correct
+        }
+        // tests nowhere
+        ia = Inet4Address.getByName("1.1.1.1");
+        assertFalse(ia.isReachable(1000));
+        assertFalse(ia.isReachable(null, 0, 1000));
+
+        // Regression test for HARMONY-1842.
+        ia = InetAddress.getByName("localhost"); //$NON-NLS-1$
+        Enumeration<NetworkInterface> nif = NetworkInterface.getNetworkInterfaces();
+        NetworkInterface netif;
+        while (nif.hasMoreElements()) {
+            netif = nif.nextElement();
+            ia.isReachable(netif, 10, 1000);
+        }
+    }
+
+    // comparator for InetAddress objects
+    private static final SerializableAssert COMPARATOR = new SerializableAssert() {
+        public void assertDeserialized(Serializable initial,
+                Serializable deserialized) {
+
+            InetAddress initAddr = (InetAddress) initial;
+            InetAddress desrAddr = (InetAddress) deserialized;
+
+            byte[] iaAddresss = initAddr.getAddress();
+            byte[] deIAAddresss = desrAddr.getAddress();
+            for (int i = 0; i < iaAddresss.length; i++) {
+                assertEquals(iaAddresss[i], deIAAddresss[i]);
+            }
+            assertEquals(initAddr.getHostName(), desrAddr.getHostName());
+        }
+    };
+
+    // Regression Test for Harmony-2290
+    public void test_isReachableLjava_net_NetworkInterfaceII_loopbackInterface() throws IOException {
+        final int TTL = 20;
+        final int TIME_OUT = 3000;
+
+        NetworkInterface loopbackInterface = null;
+        ArrayList<InetAddress> localAddresses = new ArrayList<InetAddress>();
+        Enumeration<NetworkInterface> networkInterfaces = NetworkInterface
+                .getNetworkInterfaces();
+        while (networkInterfaces.hasMoreElements()) {
+            NetworkInterface networkInterface = networkInterfaces.nextElement();
+            Enumeration<InetAddress> addresses = networkInterface
+                    .getInetAddresses();
+            while (addresses.hasMoreElements()) {
+                InetAddress address = addresses.nextElement();
+                if (address.isLoopbackAddress()) {
+                    loopbackInterface = networkInterface;
+                } else {
+                    localAddresses.add(address);
+                }
+            }
+        }
+
+        //loopbackInterface can reach local address
+        if (null != loopbackInterface) {
+            for (InetAddress destAddress : localAddresses) {
+                assertTrue(destAddress.isReachable(loopbackInterface, TTL, TIME_OUT));
+            }
+        }
+
+        //loopback Interface cannot reach outside address
+        InetAddress destAddress = InetAddress.getByName("www.google.com");
+        assertFalse(destAddress.isReachable(loopbackInterface, TTL, TIME_OUT));
+    }
+
+    /**
+     * serialization/deserialization compatibility.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        SerializationTest.verifySelf(InetAddress.getByName("localhost"),
+                COMPARATOR);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        SerializationTest.verifyGolden(this,
+                InetAddress.getByName("localhost"), COMPARATOR);
+    }
+
+    /**
+     * java.net.InetAddress#getByAddress(byte[])
+     */
+    public void test_getByAddress() {
+        // Regression for HARMONY-61
+        try {
+            InetAddress.getByAddress(null);
+            fail("Assert 0: UnknownHostException must be thrown");
+        } catch (UnknownHostException e) {
+            // Expected
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/InetAddressThreadTest.java b/luni/src/test/java/tests/api/java/net/InetAddressThreadTest.java
new file mode 100644
index 0000000..0de7f23
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/InetAddressThreadTest.java
@@ -0,0 +1,175 @@
+/*
+ *  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.InetAddress;
+
+import tests.support.Support_Configuration;
+
+public class InetAddressThreadTest extends junit.framework.TestCase {
+
+    private static boolean someoneDone[] = new boolean[2];
+
+    protected static boolean threadedTestSucceeded;
+
+    protected static String threadedTestErrorString;
+
+    /**
+     * This class is used to test inet_ntoa, gethostbyaddr and gethostbyname
+     * functions in the VM to make sure they're threadsafe. getByName will cause
+     * the gethostbyname function to be called. getHostName will cause the
+     * gethostbyaddr to be called. getHostAddress will cause inet_ntoa to be
+     * called.
+     */
+    static class threadsafeTestThread extends Thread {
+        private String lookupName;
+
+        private InetAddress testAddress;
+
+        private int testType;
+
+        /*
+         * REP_NUM can be adjusted if desired. Since this error is
+         * non-deterministic it may not always occur. Setting REP_NUM higher,
+         * increases the chances of an error being detected, but causes the test
+         * to take longer. Because the Java threads spend a lot of time
+         * performing operations other than running the native code that may not
+         * be threadsafe, it is quite likely that several thousand iterations
+         * will elapse before the first error is detected.
+         */
+        private static final int REP_NUM = 20000;
+
+        public threadsafeTestThread(String name, String lookupName,
+                InetAddress testAddress, int type) {
+            super(name);
+            this.lookupName = lookupName;
+            this.testAddress = testAddress;
+            testType = type;
+        }
+
+        public void run() {
+            try {
+                String correctName = testAddress.getHostName();
+                String correctAddress = testAddress.getHostAddress();
+                long startTime = System.currentTimeMillis();
+
+                synchronized (someoneDone) {
+                }
+
+                for (int i = 0; i < REP_NUM; i++) {
+                    if (someoneDone[testType]) {
+                        break;
+                    } else if ((i % 25) == 0
+                            && System.currentTimeMillis() - startTime > 240000) {
+                        System.out
+                                .println("Exiting due to time limitation after "
+                                        + i + " iterations");
+                        break;
+                    }
+
+                    InetAddress ia = InetAddress.getByName(lookupName);
+                    String hostName = ia.getHostName();
+                    String hostAddress = ia.getHostAddress();
+
+                    // Intentionally not looking for exact name match so that
+                    // the test works across different platforms that may or
+                    // may not include a domain suffix on the hostname
+                    if (!hostName.startsWith(correctName)) {
+                        threadedTestSucceeded = false;
+                        threadedTestErrorString = (testType == 0 ? "gethostbyname"
+                                : "gethostbyaddr")
+                                + ": getHostName() returned "
+                                + hostName
+                                + " instead of " + correctName;
+                        break;
+                    }
+                    // IP addresses should match exactly
+                    if (!correctAddress.equals(hostAddress)) {
+                        threadedTestSucceeded = false;
+                        threadedTestErrorString = (testType == 0 ? "gethostbyname"
+                                : "gethostbyaddr")
+                                + ": getHostName() returned "
+                                + hostAddress
+                                + " instead of " + correctAddress;
+                        break;
+                    }
+
+                }
+                someoneDone[testType] = true;
+            } catch (Exception e) {
+                threadedTestSucceeded = false;
+                threadedTestErrorString = e.toString();
+            }
+        }
+    }
+
+    /**
+     * java.net.InetAddress#getHostName()
+     */
+    public void test_getHostName() throws Exception {
+        // Test for method java.lang.String java.net.InetAddress.getHostName()
+
+        // Make sure there is no caching
+        String originalPropertyValue = System
+                .getProperty("networkaddress.cache.ttl");
+        System.setProperty("networkaddress.cache.ttl", "0");
+
+        // Test for threadsafety
+        try {
+            InetAddress lookup1 = InetAddress.getByName("localhost");
+            assertEquals("127.0.0.1", lookup1.getHostAddress());
+            InetAddress lookup2 = InetAddress.getByName("localhost");
+            assertEquals("127.0.0.1", lookup2.getHostAddress());
+            threadsafeTestThread thread1 = new threadsafeTestThread("1",
+                    lookup1.getHostName(), lookup1, 0);
+            threadsafeTestThread thread2 = new threadsafeTestThread("2",
+                    lookup2.getHostName(), lookup2, 0);
+            threadsafeTestThread thread3 = new threadsafeTestThread("3",
+                    lookup1.getHostAddress(), lookup1, 1);
+            threadsafeTestThread thread4 = new threadsafeTestThread("4",
+                    lookup2.getHostAddress(), lookup2, 1);
+
+            // initialize the flags
+            threadedTestSucceeded = true;
+            synchronized (someoneDone) {
+                thread1.start();
+                thread2.start();
+                thread3.start();
+                thread4.start();
+            }
+            thread1.join();
+            thread2.join();
+            thread3.join();
+            thread4.join();
+            /* FIXME: comment the assertion below because it is platform/configuration dependent
+             * Please refer to HARMONY-1664 (https://issues.apache.org/jira/browse/HARMONY-1664)
+             * for details
+             */
+//            assertTrue(threadedTestErrorString, threadedTestSucceeded);
+        } finally {
+            // restore the old value of the property
+            if (originalPropertyValue == null)
+                // setting the property to -1 has the same effect as having the
+                // property be null
+                System.setProperty("networkaddress.cache.ttl", "-1");
+            else
+                System.setProperty("networkaddress.cache.ttl",
+                        originalPropertyValue);
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/InetSocketAddressTest.java b/luni/src/test/java/tests/api/java/net/InetSocketAddressTest.java
new file mode 100644
index 0000000..bb04040
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/InetSocketAddressTest.java
@@ -0,0 +1,131 @@
+/* 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.io.Serializable;
+import java.net.InetSocketAddress;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class InetSocketAddressTest extends TestCase {
+
+    /**
+     * java.net.InetSocketAddress#InetSocketAddress(String, int)
+     */
+    public void test_ConstructorLjava_lang_StringI() throws Exception {
+        // regression test for Harmony-1042
+        InetSocketAddress address = new InetSocketAddress("127.0.0.1", 0);
+        assertEquals("/127.0.0.1:0", address.toString());
+        String localhostName = address.getHostName();
+        assertNotNull(localhostName);
+        assertEquals(localhostName + "/127.0.0.1:0", address.toString());
+    }
+
+    /**
+     * java.net.InetSocketAddress#createUnresolved(String, int)
+     */
+    public void test_createUnresolvedLjava_lang_StringI() {
+        HostPortPair[] legalHostPortPairs = { new HostPortPair("127.0.0.1", 1234),
+                new HostPortPair("192.168.0.1", 10000), new HostPortPair("127.0.0", 0),
+                new HostPortPair("127.0.0", 65535),
+                new HostPortPair("strange host", 65535) };
+        for (int i = 0; i < legalHostPortPairs.length; i++) {
+            InetSocketAddress isa = InetSocketAddress.createUnresolved(
+                    legalHostPortPairs[i].host, legalHostPortPairs[i].port);
+            assertTrue(isa.isUnresolved());
+            assertNull(isa.getAddress());
+            assertEquals(isa.getHostName(), legalHostPortPairs[i].host);
+            assertEquals(isa.getPort(), legalHostPortPairs[i].port);
+        }
+    }
+
+    /**
+     * java.net.InetSocketAddress#createUnresolved(String, int)
+     */
+    public void test_createUnresolvedLjava_lang_StringI_IllegalArgumentException() {
+        HostPortPair[] illegalHostPortPairs = { new HostPortPair(null, 1),
+                new HostPortPair("host", -1), new HostPortPair("host", 65536) };
+        for (int i = 0; i < illegalHostPortPairs.length; i++) {
+            try {
+                InetSocketAddress.createUnresolved(
+                        illegalHostPortPairs[i].host,
+                        illegalHostPortPairs[i].port);
+                fail("should throw IllegalArgumentException, host = "
+                        + illegalHostPortPairs[i].host + ",port = "
+                        + illegalHostPortPairs[i].port);
+            } catch (IllegalArgumentException e) {
+                // expected
+            }
+        }
+    }
+
+    /*
+      * inner class for createUnresolved test convenience.
+      */
+    class HostPortPair {
+        String host;
+
+        int port;
+
+        public HostPortPair(String host, int port) {
+            this.host = host;
+            this.port = port;
+        }
+    }
+
+    ;
+
+    // comparator for InetSocketAddress objects
+    private static final SerializableAssert COMPARATOR = new SerializableAssert() {
+        public void assertDeserialized(Serializable initial,
+                Serializable deserialized) {
+
+            InetSocketAddress init = (InetSocketAddress) initial;
+            InetSocketAddress desr = (InetSocketAddress) deserialized;
+
+            assertEquals("HostName", init.getHostName(), desr.getHostName());
+            assertEquals("Port", init.getPort(), desr.getPort());
+            assertEquals("Address", init.getAddress(), desr.getAddress());
+        }
+    };
+
+    /**
+     * serialization/deserialization compatibility.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        Object[] testCases = {
+                InetSocketAddress.createUnresolved("badhost", 1000), // unresolved
+                new InetSocketAddress("Localhost", 1000) };
+
+        SerializationTest.verifySelf(testCases, COMPARATOR);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        Object[] testCases = {
+                InetSocketAddress.createUnresolved("badhost", 1000), // unresolved
+                new InetSocketAddress("Localhost", 1000) };
+
+        SerializationTest.verifyGolden(this, testCases, COMPARATOR);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/InterfaceAddressTest.java b/luni/src/test/java/tests/api/java/net/InterfaceAddressTest.java
new file mode 100644
index 0000000..625283c
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/InterfaceAddressTest.java
@@ -0,0 +1,164 @@
+/*
+ *  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.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InterfaceAddress;
+import java.net.NetworkInterface;
+import java.util.Enumeration;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+public class InterfaceAddressTest extends TestCase {
+    private InterfaceAddress interfaceAddr;
+
+    private InterfaceAddress anotherInterfaceAddr;
+
+    /**
+     * java.net.InterfaceAddress.hashCode()
+     * @since 1.6
+     */
+    public void test_hashCode() {
+        // RI may fail on this when both broadcast addresses are null
+        if (interfaceAddr != null) {
+            assertEquals(anotherInterfaceAddr, interfaceAddr);
+            assertEquals(anotherInterfaceAddr.hashCode(), interfaceAddr
+                    .hashCode());
+        }
+    }
+
+    /**
+     * java.net.InterfaceAddress.equals(Object)
+     * @since 1.6
+     */
+    public void test_equals_LObject() {
+        // RI may fail on this when both broadcast addresses are null
+        if (interfaceAddr != null) {
+            assertFalse(interfaceAddr.equals(null));
+            assertFalse(interfaceAddr.equals(new Object()));
+
+            assertTrue(interfaceAddr.equals(anotherInterfaceAddr));
+            assertNotSame(anotherInterfaceAddr, interfaceAddr);
+        }
+    }
+
+    /**
+     * java.net.InterfaceAddress.toString()
+     * @since 1.6
+     */
+    public void test_toString() {
+        if (interfaceAddr != null) {
+            assertNotNull(interfaceAddr.toString());
+            assertEquals(anotherInterfaceAddr.toString(), interfaceAddr
+                    .toString());
+            assertTrue(interfaceAddr.toString().contains("/"));
+            assertTrue(interfaceAddr.toString().contains("["));
+            assertTrue(interfaceAddr.toString().contains("]"));
+        }
+    }
+
+    /**
+     * java.net.InterfaceAddress.getAddress()
+     * @since 1.6
+     */
+    public void test_getAddress() {
+        if (interfaceAddr != null) {
+            InetAddress addr1 = interfaceAddr.getAddress();
+            assertNotNull(addr1);
+            InetAddress addr2 = anotherInterfaceAddr.getAddress();
+            assertNotNull(addr2);
+            assertEquals(addr2, addr1);
+        }
+    }
+
+    /**
+     * java.net.InterfaceAddress.getBroadcast()
+     * @since 1.6
+     */
+    public void test_getBroadcast() {
+        if (interfaceAddr != null) {
+            InetAddress addr = interfaceAddr.getAddress();
+            InetAddress addr1 = interfaceAddr.getBroadcast();
+            InetAddress addr2 = anotherInterfaceAddr.getBroadcast();
+            if (addr instanceof Inet4Address) {
+                assertEquals(addr2, addr1);
+            } else if (addr instanceof Inet6Address) {
+                assertNull(addr1);
+                assertNull(addr2);
+            }
+        }
+    }
+
+    /**
+     * java.net.InterfaceAddress.getNetworkPrefixLength()
+     * @since 1.6
+     */
+    public void test_getNetworkPrefixLength() {
+        if (interfaceAddr != null) {
+            short prefix1 = interfaceAddr.getNetworkPrefixLength();
+            short prefix2 = anotherInterfaceAddr.getNetworkPrefixLength();
+            assertEquals(prefix2, prefix1);
+        }
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        Enumeration<NetworkInterface> netifs = NetworkInterface
+                .getNetworkInterfaces();
+        NetworkInterface theInterface = null;
+        if (netifs != null) {
+            while (netifs.hasMoreElements()) {
+                theInterface = netifs.nextElement();
+                if (theInterface != null) {
+                    List<InterfaceAddress> addrs = theInterface
+                            .getInterfaceAddresses();
+                    if (!(addrs == null || addrs.isEmpty())) {
+                        interfaceAddr = addrs.get(0);
+                        break;
+                    }
+                }
+            }
+        }
+
+        // get another InterfaceAddress object if the interfaceAddr exists. It
+        // equals to interfaceAddr, but is not the same one.
+        if (theInterface != null && interfaceAddr != null) {
+            Enumeration<InetAddress> addresses = theInterface
+                    .getInetAddresses();
+            if (addresses != null && addresses.hasMoreElements()) {
+                NetworkInterface anotherNetworkInter = NetworkInterface
+                        .getByInetAddress(addresses.nextElement());
+                anotherInterfaceAddr = anotherNetworkInter
+                        .getInterfaceAddresses().get(0);
+            }
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        interfaceAddr = null;
+        anotherInterfaceAddr = null;
+        super.tearDown();
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/net/JarURLConnectionTest.java b/luni/src/test/java/tests/api/java/net/JarURLConnectionTest.java
new file mode 100644
index 0000000..6134aab
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/JarURLConnectionTest.java
@@ -0,0 +1,324 @@
+/*
+ *  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.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.JarURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import tests.support.resource.Support_Resources;
+
+public class JarURLConnectionTest extends junit.framework.TestCase {
+
+    JarURLConnection juc;
+
+    URLConnection uc;
+
+    private static final String BASE =
+            "file:resources/org/apache/harmony/luni/tests/java/net/lf.jar";
+
+    /**
+     * java.net.JarURLConnection#getAttributes()
+     */
+    public void test_getAttributes() throws Exception {
+        URL u = new URL("jar:" + BASE + "!/swt.dll");
+
+        juc = (JarURLConnection) u.openConnection();
+        java.util.jar.Attributes a = juc.getJarEntry().getAttributes();
+        assertEquals("Returned incorrect Attributes", "SHA MD5", a
+                .get(new java.util.jar.Attributes.Name("Digest-Algorithms")));
+    }
+
+    /**
+     * @throws Exception
+     * java.net.JarURLConnection#getEntryName()
+     */
+    public void test_getEntryName() throws Exception {
+        URL u = new URL("jar:" + BASE + "!/plus.bmp");
+        juc = (JarURLConnection) u.openConnection();
+        assertEquals("Returned incorrect entryName", "plus.bmp", juc
+                .getEntryName());
+        u = new URL("jar:" + BASE + "!/");
+        juc = (JarURLConnection) u.openConnection();
+        assertNull("Returned incorrect entryName", juc.getEntryName());
+//      Regression test for harmony-3053
+        URL url = new URL("jar:file:///bar.jar!/foo.jar!/Bugs/HelloWorld.class");
+        assertEquals("foo.jar!/Bugs/HelloWorld.class", ((JarURLConnection) url.openConnection()).getEntryName());
+    }
+
+    /**
+     * java.net.JarURLConnection#getJarEntry()
+     */
+    public void test_getJarEntry() throws Exception {
+        URL u = new URL("jar:" + BASE + "!/plus.bmp");
+        juc = (JarURLConnection) u.openConnection();
+        assertEquals("Returned incorrect JarEntry", "plus.bmp", juc
+                .getJarEntry().getName());
+        u = new URL("jar:" + BASE + "!/");
+        juc = (JarURLConnection) u.openConnection();
+        assertNull("Returned incorrect JarEntry", juc.getJarEntry());
+    }
+
+    /**
+     * java.net.JarURLConnection#getJarFile()
+     */
+    public void test_getJarFile() throws MalformedURLException, IOException {
+        URL url = null;
+        url = new URL("jar:" + BASE + "!/missing");
+
+        JarURLConnection connection = null;
+        connection = (JarURLConnection) url.openConnection();
+        try {
+            connection.connect();
+            fail("Did not throw exception on connect");
+        } catch (IOException e) {
+            // expected
+        }
+
+        try {
+            connection.getJarFile();
+            fail("Did not throw exception after connect");
+        } catch (IOException e) {
+            // expected
+        }
+
+        File resources = Support_Resources.createTempFolder();
+
+        Support_Resources.copyFile(resources, null, "hyts_att.jar");
+        File file = new File(resources.toString() + "/hyts_att.jar");
+        URL fUrl1 = new URL("jar:file:" + file.getPath() + "!/");
+        JarURLConnection con1 = (JarURLConnection) fUrl1.openConnection();
+        ZipFile jf1 = con1.getJarFile();
+        JarURLConnection con2 = (JarURLConnection) fUrl1.openConnection();
+        ZipFile jf2 = con2.getJarFile();
+        assertTrue("file: JarFiles not the same", jf1 == jf2);
+        jf1.close();
+        assertTrue("File should exist", file.exists());
+        new URL("jar:" + BASE + "!/");
+        con1 = (JarURLConnection) fUrl1.openConnection();
+        jf1 = con1.getJarFile();
+        con2 = (JarURLConnection) fUrl1.openConnection();
+        jf2 = con2.getJarFile();
+        assertTrue("http: JarFiles not the same", jf1 == jf2);
+        jf1.close();
+    }
+
+    /**
+     * java.net.JarURLConnection.getJarFile()
+     * <p/>
+     * Regression test for HARMONY-29
+     */
+    public void test_getJarFile29() throws Exception {
+        File jarFile = File.createTempFile("1+2 3", "test.jar");
+        jarFile.deleteOnExit();
+        JarOutputStream out = new JarOutputStream(new FileOutputStream(jarFile));
+        out.putNextEntry(new ZipEntry("test"));
+        out.closeEntry();
+        out.close();
+
+        JarURLConnection conn = (JarURLConnection) new URL("jar:file:"
+                + jarFile.getAbsolutePath().replaceAll(" ", "%20") + "!/")
+                .openConnection();
+        conn.getJarFile().entries();
+    }
+
+    //Regression for HARMONY-3436
+    public void test_setUseCaches() throws Exception {
+        File resources = Support_Resources.createTempFolder();
+        Support_Resources.copyFile(resources, null, "hyts_att.jar");
+        File file = new File(resources.toString() + "/hyts_att.jar");
+        URL url = new URL("jar:file:" + file.getPath() + "!/HasAttributes.txt");
+
+        JarURLConnection connection = (JarURLConnection) url.openConnection();
+        connection.setUseCaches(false);
+        InputStream in = connection.getInputStream();
+        JarFile jarFile1 = connection.getJarFile();
+        JarEntry jarEntry1 = connection.getJarEntry();
+        byte[] data = new byte[1024];
+        while (in.read(data) >= 0)
+            ;
+        in.close();
+        JarFile jarFile2 = connection.getJarFile();
+        JarEntry jarEntry2 = connection.getJarEntry();
+        assertSame(jarFile1, jarFile2);
+        assertSame(jarEntry1, jarEntry2);
+
+        try {
+            connection.getInputStream();
+            fail("should throw IllegalStateException");
+        } catch (IllegalStateException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.net.JarURLConnection#getJarFileURL()
+     */
+    public void test_getJarFileURL() throws Exception {
+        URL fileURL = new URL(BASE);
+        URL u = new URL("jar:" + BASE + "!/plus.bmp");
+        juc = (JarURLConnection) u.openConnection();
+        assertEquals("Returned incorrect file URL",
+                fileURL, juc.getJarFileURL());
+
+        // Regression test for harmony-3053
+        URL url = new URL("jar:file:///bar.jar!/foo.jar!/Bugs/HelloWorld.class");
+        assertEquals("file:/bar.jar", ((JarURLConnection) url.openConnection()).getJarFileURL().toString());
+    }
+
+    /**
+     * java.net.JarURLConnection#getMainAttributes()
+     */
+    public void test_getMainAttributes() throws Exception {
+        URL u = new URL("jar:" + BASE + "!/swt.dll");
+        juc = (JarURLConnection) u.openConnection();
+        java.util.jar.Attributes a = juc.getMainAttributes();
+        assertEquals("Returned incorrect Attributes", "1.0", a
+                .get(java.util.jar.Attributes.Name.MANIFEST_VERSION));
+    }
+
+    /**
+     * java.net.JarURLConnection#getInputStream()
+     */
+    public void test_getInputStream_DeleteJarFileUsingURLConnection()
+            throws Exception {
+        String jarFileName = "file.jar";
+        String entry = "text.txt";
+        File file = new File(jarFileName);
+        FileOutputStream jarFile = new FileOutputStream(jarFileName);
+        JarOutputStream out = new JarOutputStream(new BufferedOutputStream(
+                jarFile));
+        JarEntry jarEntry = new JarEntry(entry);
+        out.putNextEntry(jarEntry);
+        out.write(new byte[] { 'a', 'b', 'c' });
+        out.close();
+
+        URL url = new URL("jar:file:" + jarFileName + "!/" + entry);
+        URLConnection conn = url.openConnection();
+        conn.setUseCaches(false);
+        InputStream is = conn.getInputStream();
+        is.close();
+        assertTrue(file.delete());
+    }
+
+    /**
+     * java.net.JarURLConnection#getManifest()
+     */
+    public void test_getManifest() throws Exception {
+        URL u = new URL("jar:" + BASE + "!/plus.bmp");
+        juc = (JarURLConnection) u.openConnection();
+        Manifest mf = juc.getManifest();
+        assertNotNull(mf);
+        // equal but not same manifest
+        assertEquals(mf, juc.getManifest());
+        assertNotSame(mf, juc.getManifest());
+        // same main attributes
+        assertEquals(juc.getMainAttributes(), mf.getMainAttributes());
+    }
+
+    /**
+     * java.net.JarURLConnection#getCertificates()
+     */
+    public void test_getCertificates() throws Exception {
+        URL u = new URL("jar:" + BASE + "!/plus.bmp");
+        juc = (JarURLConnection) u.openConnection();
+        // read incomplete, shall return null
+        assertNull(juc.getCertificates());
+        assertEquals("Returned incorrect JarEntry", "plus.bmp", juc
+                .getJarEntry().getName());
+        // read them all
+        InputStream is = juc.getInputStream();
+        byte[] buf = new byte[80];
+        while (is.read(buf) > 0) ;
+        // still return null for this type of file
+        assertNull(juc.getCertificates());
+
+        URL fileURL = new URL("jar:" + BASE + "!/");
+        juc = (JarURLConnection) fileURL.openConnection();
+        is = juc.getJarFileURL().openStream();
+        while (is.read(buf) > 0) ;
+        // null for this jar file
+        assertNull(juc.getCertificates());
+    }
+
+    /**
+     * java.net.JarURLConnection#getContentLength()
+     * Regression test for HARMONY-3665
+     */
+    public void test_getContentLength() throws Exception {
+        // check length for jar file itself
+        URL u = new URL("jar:" + BASE + "!/");
+        assertEquals("Returned incorrect size for jar file", 33095,
+                u.openConnection().getContentLength());
+
+        // check length for jar entry
+        u = new URL("jar:" + BASE + "!/plus.bmp");
+        assertEquals("Returned incorrect size for the entry", 190,
+                u.openConnection().getContentLength());
+    }
+
+    /**
+     * java.net.JarURLConnection#getContentType()
+     * Regression test for HARMONY-3665
+     */
+    public void test_getContentType() throws Exception {
+        // check type for jar file itself
+        URL u = new URL("jar:" + BASE + "!/");
+        assertEquals("Returned incorrect type for jar file", "x-java/jar",
+                u.openConnection().getContentType());
+
+        // check type for jar entry with known type
+        u = new URL("jar:" + BASE + "!/plus.bmp");
+        assertEquals("Returned incorrect type for the entry with known type",
+                "image/bmp", u.openConnection().getContentType());
+
+        // check type for jar entry with unknown type
+        u = new URL("jar:" + BASE + "!/Manifest.mf");
+        assertEquals("Returned incorrect type for the entry with known type",
+                "content/unknown", u.openConnection().getContentType());
+    }
+
+    public void test_getURLEncodedEntry() throws IOException {
+        String base = "file:resources/org/apache/harmony/luni/tests/java/net/url-test.jar";
+        URL url = new URL("jar:" + base + "!/test%20folder%20for%20url%20test/test");
+
+        if (url != null) {
+            // Force existence check
+            InputStream is = url.openStream();
+            is.close();
+        }
+    }
+
+    protected void setUp() {
+    }
+
+    protected void tearDown() {
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/MalformedURLExceptionTest.java b/luni/src/test/java/tests/api/java/net/MalformedURLExceptionTest.java
new file mode 100644
index 0000000..1e8364b
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/MalformedURLExceptionTest.java
@@ -0,0 +1,72 @@
+/*
+ *  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.MalformedURLException;
+import java.net.URL;
+
+public class MalformedURLExceptionTest extends junit.framework.TestCase {
+
+    /**
+     * java.net.MalformedURLException#MalformedURLException()
+     */
+    public void test_Constructor() {
+        // Test for method java.net.MalformedURLException()
+        boolean passed;
+        passed = false;
+        try {
+            new URL("notAProtocol://www.ibm.com");
+        } catch (MalformedURLException e) {
+            // correct
+            passed = true;
+        }
+
+        assertTrue("Failed to throw correct exception", passed);
+    }
+
+    /**
+     * java.net.MalformedURLException#MalformedURLException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        // Test for method java.net.MalformedURLException(java.lang.String)
+        final String myString = "Gawsh!";
+        try {
+            if (true)
+                throw new MalformedURLException(myString);
+        } catch (MalformedURLException e) {
+            assertTrue("Incorrect exception text", e.toString().indexOf(
+                    myString) >= 0);
+            return;
+        }
+        fail("Exception not thrown");
+    }
+
+    /**
+     * 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() {
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java b/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java
new file mode 100644
index 0000000..064b1d7
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java
@@ -0,0 +1,895 @@
+/*
+ *  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.io.IOException;
+import java.net.BindException;
+import java.net.DatagramPacket;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.MulticastSocket;
+import java.net.NetworkInterface;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+
+import tests.support.Support_PortManager;
+
+public class MulticastSocketTest extends junit.framework.TestCase {
+
+    private boolean atLeastTwoInterfaces = false;
+
+    private NetworkInterface networkInterface1 = null;
+
+    private NetworkInterface networkInterface2 = null;
+
+    private NetworkInterface IPV6networkInterface1 = null;
+
+    private static InetAddress lookup(String s) {
+        try {
+            return InetAddress.getByName(s);
+        } catch (IOException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    // These IP addresses aren't inherently "good" or "bad"; they're just used like that.
+    // We use the "good" addresses for our actual group, and the "bad" addresses are for
+    // a group that we won't actually set up.
+
+    private static InetAddress GOOD_IPv4 = lookup("224.0.0.3");
+    private static InetAddress BAD_IPv4 = lookup("224.0.0.4");
+
+    private static InetAddress GOOD_IPv6 = lookup("ff05::7:7");
+    private static InetAddress BAD_IPv6 = lookup("ff05::7:8");
+
+    static class MulticastServer extends Thread {
+
+        public MulticastSocket ms;
+
+        boolean running = true;
+
+        volatile public byte[] rbuf = new byte[512];
+
+        volatile DatagramPacket rdp = null;
+
+        private InetAddress groupAddr = null;
+        private SocketAddress groupSockAddr = null;
+        private NetworkInterface groupNI = null;
+
+        public void run() {
+            try {
+                byte[] tmpbuf = new byte[512];
+                DatagramPacket tmpPack = new DatagramPacket(tmpbuf, tmpbuf.length);
+
+                while (running) {
+                    try {
+                        ms.receive(tmpPack);
+
+                        System.arraycopy(tmpPack.getData(), 0, rdp.getData(), rdp.getOffset(), tmpPack.getLength());
+                        rdp.setLength(tmpPack.getLength());
+                        rdp.setAddress(tmpPack.getAddress());
+                        rdp.setPort(tmpPack.getPort());
+                    } catch (java.io.InterruptedIOException e) {
+                        Thread.yield();
+                    }
+                }
+            } catch (java.io.IOException e) {
+                System.out.println("Multicast server failed: " + e);
+            } finally {
+                ms.close();
+            }
+        }
+
+        public void stopServer() {
+            running = false;
+            try {
+                if (groupAddr != null) {
+                    ms.leaveGroup(groupAddr);
+                } else if (groupSockAddr != null) {
+                    ms.leaveGroup(groupSockAddr, groupNI);
+                }
+            } catch (IOException e) {
+            }
+        }
+
+        public MulticastServer(InetAddress anAddress, int aPort) throws java.io.IOException {
+            rbuf = new byte[512];
+            rbuf[0] = -1;
+            rdp = new DatagramPacket(rbuf, rbuf.length);
+            ms = new MulticastSocket(aPort);
+            ms.setSoTimeout(2000);
+            groupAddr = anAddress;
+            ms.joinGroup(groupAddr);
+        }
+
+        public MulticastServer(SocketAddress anAddress, int aPort, NetworkInterface netInterface) throws java.io.IOException {
+            rbuf = new byte[512];
+            rbuf[0] = -1;
+            rdp = new DatagramPacket(rbuf, rbuf.length);
+            ms = new MulticastSocket(aPort);
+            ms.setSoTimeout(2000);
+            groupSockAddr = anAddress;
+            groupNI = netInterface;
+            ms.joinGroup(groupSockAddr, groupNI);
+        }
+    }
+
+    public void test_Constructor() throws IOException {
+        // regression test for 497
+        MulticastSocket s = new MulticastSocket();
+        // regression test for Harmony-1162
+        assertTrue(s.getReuseAddress());
+    }
+
+    public void test_ConstructorI() throws IOException {
+        MulticastSocket orig = new MulticastSocket();
+        int port = orig.getLocalPort();
+        orig.close();
+        MulticastSocket dup = null;
+        try {
+            dup = new MulticastSocket(port);
+            // regression test for Harmony-1162
+            assertTrue(dup.getReuseAddress());
+        } catch (IOException e) {
+            fail("duplicate binding not allowed: " + e);
+        }
+        if (dup != null) {
+            dup.close();
+        }
+    }
+
+    public void test_getInterface() throws Exception {
+        int groupPort = Support_PortManager.getNextPortForUDP();
+
+        // validate that we get the expected response when one was not set
+        MulticastSocket mss = new MulticastSocket(groupPort);
+        // we expect an ANY address in this case
+        assertTrue(mss.getInterface().isAnyLocalAddress());
+
+        // validate that we get the expected response when we set via
+        // setInterface
+        Enumeration addresses = networkInterface1.getInetAddresses();
+        if (addresses.hasMoreElements()) {
+            InetAddress firstAddress = (InetAddress) addresses.nextElement();
+            mss.setInterface(firstAddress);
+            assertEquals("getNetworkInterface did not return interface set by setInterface", firstAddress, mss.getInterface());
+
+            groupPort = Support_PortManager.getNextPortForUDP();
+            mss = new MulticastSocket(groupPort);
+            mss.setNetworkInterface(networkInterface1);
+            assertEquals("getInterface did not return interface set by setNetworkInterface", networkInterface1, NetworkInterface.getByInetAddress(mss.getInterface()));
+        }
+
+        mss.close();
+    }
+
+    public void test_getNetworkInterface() throws IOException {
+        int groupPort = Support_PortManager.getNextPortForUDP();
+
+        // validate that we get the expected response when one was not set
+        MulticastSocket mss = new MulticastSocket(groupPort);
+        NetworkInterface theInterface = mss.getNetworkInterface();
+        assertTrue("network interface returned wrong network interface when not set:" + theInterface,
+                theInterface.getInetAddresses().hasMoreElements());
+        InetAddress firstAddress = (InetAddress) theInterface.getInetAddresses().nextElement();
+        // validate we the first address in the network interface is the ANY address
+        assertTrue(firstAddress.isAnyLocalAddress());
+
+        mss.setNetworkInterface(networkInterface1);
+        assertEquals("getNetworkInterface did not return interface set by setNeworkInterface",
+                networkInterface1, mss.getNetworkInterface());
+
+        if (atLeastTwoInterfaces) {
+            mss.setNetworkInterface(networkInterface2);
+            assertEquals("getNetworkInterface did not return network interface set by second setNetworkInterface call",
+                    networkInterface2, mss.getNetworkInterface());
+        }
+        mss.close();
+
+        groupPort = Support_PortManager.getNextPortForUDP();
+        mss = new MulticastSocket(groupPort);
+        if (IPV6networkInterface1 != null) {
+            mss.setNetworkInterface(IPV6networkInterface1);
+            assertEquals("getNetworkInterface did not return interface set by setNeworkInterface",
+                    IPV6networkInterface1, mss.getNetworkInterface());
+        }
+
+        // validate that we get the expected response when we set via setInterface
+        groupPort = Support_PortManager.getNextPortForUDP();
+        mss = new MulticastSocket(groupPort);
+        Enumeration addresses = networkInterface1.getInetAddresses();
+        if (addresses.hasMoreElements()) {
+            firstAddress = (InetAddress) addresses.nextElement();
+            mss.setInterface(firstAddress);
+            assertEquals("getNetworkInterface did not return interface set by setInterface",
+                    networkInterface1, mss.getNetworkInterface());
+        }
+        mss.close();
+    }
+
+    public void test_getTimeToLive() throws Exception {
+        MulticastSocket mss = new MulticastSocket();
+        mss.setTimeToLive(120);
+        assertEquals("Returned incorrect 1st TTL", 120, mss.getTimeToLive());
+        mss.setTimeToLive(220);
+        assertEquals("Returned incorrect 2nd TTL", 220, mss.getTimeToLive());
+    }
+
+    public void test_getTTL() throws Exception {
+        MulticastSocket mss = new MulticastSocket();
+        mss.setTTL((byte) 120);
+        assertEquals("Returned incorrect TTL", 120, mss.getTTL());
+    }
+
+    public void test_joinGroupLjava_net_InetAddress_IPv4() throws Exception {
+        test_joinGroupLjava_net_InetAddress(GOOD_IPv4);
+    }
+
+    public void test_joinGroupLjava_net_InetAddress_IPv6() throws Exception {
+        test_joinGroupLjava_net_InetAddress(GOOD_IPv6);
+    }
+
+    private void test_joinGroupLjava_net_InetAddress(InetAddress group) throws Exception {
+        int[] ports = Support_PortManager.getNextPortsForUDP(2);
+        int groupPort = ports[0];
+
+        MulticastServer server = new MulticastServer(group, groupPort);
+        server.start();
+        Thread.sleep(1000);
+        String msg = "Hello World";
+        MulticastSocket mss = new MulticastSocket(ports[1]);
+        DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg.length(), group, groupPort);
+        mss.send(sdp, (byte) 10);
+        Thread.sleep(1000);
+        String receivedMessage = new String(server.rdp.getData(), 0, server.rdp.getLength());
+        assertEquals("Group member did not recv data", msg, receivedMessage);
+        mss.close();
+        server.stopServer();
+    }
+
+    public void test_joinGroup_null_null() throws Exception {
+        MulticastSocket mss = new MulticastSocket(0);
+        try {
+            mss.joinGroup(null, null);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+        mss.close();
+    }
+
+    public void test_joinGroup_non_multicast_address_IPv4() throws Exception {
+        MulticastSocket mss = new MulticastSocket(0);
+        try {
+            mss.joinGroup(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 0), null);
+            fail();
+        } catch (IOException expected) {
+        }
+        mss.close();
+    }
+
+    public void test_joinGroup_non_multicast_address_IPv6() throws Exception {
+        MulticastSocket mss = new MulticastSocket(0);
+        try {
+            mss.joinGroup(new InetSocketAddress(InetAddress.getByName("::1"), 0), null);
+            fail();
+        } catch (IOException expected) {
+        }
+        mss.close();
+    }
+
+    public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4() throws Exception {
+        test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(GOOD_IPv4, BAD_IPv4);
+    }
+
+    public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6() throws Exception {
+        test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(GOOD_IPv6, BAD_IPv6);
+    }
+
+    private void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(InetAddress group, InetAddress group2) throws Exception {
+        int[] ports = Support_PortManager.getNextPortsForUDP(2);
+        int groupPort = ports[0];
+        int serverPort = ports[1];
+
+        SocketAddress groupSockAddr = new InetSocketAddress(group, groupPort);
+
+        // Check that we can join a group using a null network interface.
+        MulticastSocket mss = new MulticastSocket(groupPort);
+        mss.joinGroup(groupSockAddr, null);
+        mss.setTimeToLive(2);
+        Thread.sleep(1000);
+
+        // set up the server and join the group on networkInterface1
+        MulticastServer server = new MulticastServer(groupSockAddr, serverPort, networkInterface1);
+        server.start();
+        Thread.sleep(1000);
+        String msg = "Hello World";
+        DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg.length(), group, serverPort);
+        mss.setTimeToLive(2);
+        mss.send(sdp);
+        Thread.sleep(1000);
+        // now validate that we received the data as expected
+        assertEquals("Group member did not recv data", msg, new String(server.rdp.getData(), 0, server.rdp.getLength()));
+        server.stopServer();
+        mss.close();
+
+        // now validate that we handled the case were we join a
+        // different multicast address.
+        // verify we do not receive the data
+        ports = Support_PortManager.getNextPortsForUDP(2);
+        serverPort = ports[0];
+        server = new MulticastServer(groupSockAddr, serverPort, networkInterface1);
+        server.start();
+        Thread.sleep(1000);
+
+        groupPort = ports[1];
+        mss = new MulticastSocket(groupPort);
+        mss.setTimeToLive(10);
+        msg = "Hello World - Different Group";
+        sdp = new DatagramPacket(msg.getBytes(), msg.length(), group2, serverPort);
+        mss.send(sdp);
+        Thread.sleep(1000);
+        assertFalse("Group member received data when sent on different group: ",
+                new String(server.rdp.getData(), 0, server.rdp.getLength()).equals(msg));
+        server.stopServer();
+        mss.close();
+    }
+
+    public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface() throws Exception {
+        // if there is more than one network interface then check that
+        // we can join on specific interfaces and that we only receive
+        // if data is received on that interface
+        if (!atLeastTwoInterfaces) {
+            return;
+        }
+        // set up server on first interfaces
+        NetworkInterface loopbackInterface = NetworkInterface.getByInetAddress(InetAddress.getByName("127.0.0.1"));
+
+        boolean anyLoop = networkInterface1.equals(loopbackInterface) || networkInterface2.equals(loopbackInterface);
+        System.err.println("anyLoop=" + anyLoop);
+
+        ArrayList<NetworkInterface> realInterfaces = new ArrayList<NetworkInterface>();
+        Enumeration<NetworkInterface> theInterfaces = NetworkInterface.getNetworkInterfaces();
+        while (theInterfaces.hasMoreElements()) {
+            NetworkInterface thisInterface = (NetworkInterface) theInterfaces.nextElement();
+            if (thisInterface.getInetAddresses().hasMoreElements()) {
+                realInterfaces.add(thisInterface);
+            }
+        }
+
+        for (int i = 0; i < realInterfaces.size(); i++) {
+            NetworkInterface thisInterface = realInterfaces.get(i);
+
+            // get the first address on the interface
+
+            // start server which is joined to the group and has
+            // only asked for packets on this interface
+            Enumeration<InetAddress> addresses = thisInterface.getInetAddresses();
+
+            NetworkInterface sendingInterface = null;
+            InetAddress group = null;
+            if (addresses.hasMoreElements()) {
+                InetAddress firstAddress = (InetAddress) addresses.nextElement();
+                if (firstAddress instanceof Inet4Address) {
+                    group = InetAddress.getByName("224.0.0.4");
+                    if (anyLoop) {
+                        if (networkInterface1.equals(loopbackInterface)) {
+                            sendingInterface = networkInterface2;
+                        } else {
+                            sendingInterface = networkInterface1;
+                        }
+                    } else {
+                        if (i == 1) {
+                            sendingInterface = networkInterface2;
+                        } else {
+                            sendingInterface = networkInterface1;
+                        }
+                    }
+                } else {
+                    // if this interface only seems to support IPV6 addresses
+                    group = InetAddress.getByName("FF01:0:0:0:0:0:2:8001");
+                    sendingInterface = IPV6networkInterface1;
+                }
+            }
+
+            int[] ports = Support_PortManager.getNextPortsForUDP(2);
+            int serverPort = ports[0];
+            int groupPort = ports[1];
+            InetSocketAddress groupSockAddr = new InetSocketAddress(group, serverPort);
+            MulticastServer server = new MulticastServer(groupSockAddr, serverPort, thisInterface);
+            server.start();
+            Thread.sleep(1000);
+
+            // Now send out a package on interface
+            // networkInterface 1. We should
+            // only see the packet if we send it on interface 1
+            MulticastSocket mss = new MulticastSocket(groupPort);
+            mss.setNetworkInterface(sendingInterface);
+            String msg = "Hello World - Again" + thisInterface.getName();
+            DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg.length(), group, serverPort);
+            System.err.println(thisInterface + " " + group);
+            mss.send(sdp);
+            Thread.sleep(1000);
+            if (thisInterface.equals(sendingInterface)) {
+                assertEquals("Group member did not recv data when bound on specific interface",
+                        msg, new String(server.rdp.getData(), 0, server.rdp.getLength()));
+            } else {
+                assertFalse("Group member received data on other interface when only asked for it on one interface: ",
+                        new String(server.rdp.getData(), 0, server.rdp.getLength()).equals(msg));
+            }
+
+            server.stopServer();
+            mss.close();
+        }
+    }
+
+    public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins_IPv4() throws Exception {
+        test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins(GOOD_IPv4);
+    }
+
+    public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins_IPv6() throws Exception {
+        test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins(GOOD_IPv6);
+    }
+
+    private void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins(InetAddress group) throws Exception {
+        // validate that we can join the same address on two
+        // different interfaces but not on the same interface
+        int groupPort = Support_PortManager.getNextPortForUDP();
+        MulticastSocket mss = new MulticastSocket(groupPort);
+        SocketAddress groupSockAddr = new InetSocketAddress(group, groupPort);
+        mss.joinGroup(groupSockAddr, networkInterface1);
+        mss.joinGroup(groupSockAddr, networkInterface2);
+        try {
+            mss.joinGroup(groupSockAddr, networkInterface1);
+            fail("Did not get expected exception when joining for second time on same interface");
+        } catch (IOException e) {
+        }
+        mss.close();
+    }
+
+    public void test_leaveGroupLjava_net_InetAddress_IPv4() throws Exception {
+        test_leaveGroupLjava_net_InetAddress(GOOD_IPv4);
+    }
+
+    public void test_leaveGroupLjava_net_InetAddress_IPv6() throws Exception {
+        test_leaveGroupLjava_net_InetAddress(GOOD_IPv6);
+    }
+
+    private void test_leaveGroupLjava_net_InetAddress(InetAddress group) throws Exception {
+        int[] ports = Support_PortManager.getNextPortsForUDP(2);
+        int groupPort = ports[0];
+
+        String msg = "Hello World";
+        MulticastSocket mss = new MulticastSocket(ports[1]);
+        DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg.length(), group, groupPort);
+        mss.send(sdp, (byte) 10);
+        try {
+            // Try to leave a group we didn't join.
+            mss.leaveGroup(group);
+            fail();
+        } catch (IOException expected) {
+        }
+        mss.close();
+    }
+
+    public void test_leaveGroup_null_null() throws Exception {
+        MulticastSocket mss = new MulticastSocket(0);
+        try {
+            mss.leaveGroup(null, null);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+        mss.close();
+    }
+
+    public void test_leaveGroup_non_multicast_address_IPv4() throws Exception {
+        MulticastSocket mss = new MulticastSocket(0);
+        try {
+            mss.leaveGroup(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 0), null);
+            fail();
+        } catch (IOException expected) {
+        }
+        mss.close();
+    }
+
+    public void test_leaveGroup_non_multicast_address_IPv6() throws Exception {
+        MulticastSocket mss = new MulticastSocket(0);
+        try {
+            mss.leaveGroup(new InetSocketAddress(InetAddress.getByName("::1"), 0), null);
+            fail();
+        } catch (IOException expected) {
+        }
+        mss.close();
+    }
+
+    public void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4() throws Exception {
+        test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface(GOOD_IPv4, BAD_IPv4);
+    }
+
+    public void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6() throws Exception {
+        test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface(GOOD_IPv6, BAD_IPv6);
+    }
+
+    private void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface(InetAddress group, InetAddress group2) throws Exception {
+        String msg = null;
+        int groupPort = Support_PortManager.getNextPortForUDP();
+        SocketAddress groupSockAddr = null;
+        SocketAddress groupSockAddr2 = null;
+
+        groupSockAddr = new InetSocketAddress(group, groupPort);
+
+        // now test that we can join and leave a group successfully
+        groupPort = Support_PortManager.getNextPortForUDP();
+        MulticastSocket mss = new MulticastSocket(groupPort);
+        groupSockAddr = new InetSocketAddress(group, groupPort);
+        mss.joinGroup(groupSockAddr, null);
+        mss.leaveGroup(groupSockAddr, null);
+        try {
+            mss.leaveGroup(groupSockAddr, null);
+            fail("Did not get exception when trying to leave group that was already left");
+        } catch (IOException expected) {
+        }
+
+        groupSockAddr2 = new InetSocketAddress(group2, groupPort);
+        mss.joinGroup(groupSockAddr, networkInterface1);
+        try {
+            mss.leaveGroup(groupSockAddr2, networkInterface1);
+            fail("Did not get exception when trying to leave group that was never joined");
+        } catch (IOException expected) {
+        }
+
+        mss.leaveGroup(groupSockAddr, networkInterface1);
+        if (atLeastTwoInterfaces) {
+            mss.joinGroup(groupSockAddr, networkInterface1);
+            try {
+                mss.leaveGroup(groupSockAddr, networkInterface2);
+                fail("Did not get exception when trying to leave group on wrong interface joined on [" + networkInterface1 + "] left on [" + networkInterface2 + "]");
+            } catch (IOException expected) {
+            }
+        }
+    }
+
+    public void test_sendLjava_net_DatagramPacketB_IPv4() throws Exception {
+        test_sendLjava_net_DatagramPacketB(GOOD_IPv4);
+    }
+
+    public void test_sendLjava_net_DatagramPacketB_IPv6() throws Exception {
+        test_sendLjava_net_DatagramPacketB(GOOD_IPv6);
+    }
+
+    private void test_sendLjava_net_DatagramPacketB(InetAddress group) throws Exception {
+        String msg = "Hello World";
+        int[] ports = Support_PortManager.getNextPortsForUDP(2);
+        int groupPort = ports[0];
+
+        MulticastSocket mss = new MulticastSocket(ports[1]);
+        MulticastServer server = new MulticastServer(group, groupPort);
+        server.start();
+        Thread.sleep(200);
+        DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg.length(), group, groupPort);
+        mss.send(sdp, (byte) 10);
+        Thread.sleep(1000);
+        mss.close();
+        byte[] data = server.rdp.getData();
+        int length = server.rdp.getLength();
+        assertEquals("Failed to send data. Received " + length, msg, new String(data, 0, length));
+        server.stopServer();
+    }
+
+    public void test_setInterfaceLjava_net_InetAddress() throws Exception {
+        MulticastSocket mss = new MulticastSocket();
+        mss.setInterface(InetAddress.getLocalHost());
+        InetAddress theInterface = mss.getInterface();
+        // under IPV6 we are not guarrenteed to get the same address back as
+        // the address, all we should be guaranteed is that we get an
+        // address on the same interface
+        if (theInterface instanceof Inet6Address) {
+            assertTrue("Failed to return correct interface IPV6", NetworkInterface.getByInetAddress(mss.getInterface()).equals(NetworkInterface.getByInetAddress(theInterface)));
+        } else {
+            assertTrue("Failed to return correct interface IPV4 got:" + mss.getInterface() + " excpeted: " + InetAddress.getLocalHost(), mss.getInterface().equals(InetAddress.getLocalHost()));
+        }
+        mss.close();
+    }
+
+    public void test_setInterface_unbound_address_IPv4() throws Exception {
+        test_setInterface_unbound_address(GOOD_IPv4);
+    }
+
+    public void test_setInterface_unbound_address_IPv6() throws Exception {
+        test_setInterface_unbound_address(GOOD_IPv6);
+    }
+
+    // Regression test for Harmony-2410
+    private void test_setInterface_unbound_address(InetAddress address) throws Exception {
+        MulticastSocket mss = new MulticastSocket();
+        try {
+            mss.setInterface(address);
+            fail();
+        } catch (SocketException expected) {
+        }
+        mss.close();
+    }
+
+    public void test_setNetworkInterfaceLjava_net_NetworkInterface_null() throws Exception {
+        // validate that null interface is handled ok
+        MulticastSocket mss = new MulticastSocket();
+        try {
+            mss.setNetworkInterface(null);
+            fail("No socket exception when we set then network interface with NULL");
+        } catch (SocketException ex) {
+        }
+        mss.close();
+    }
+
+    public void test_setNetworkInterfaceLjava_net_NetworkInterface_round_trip() throws Exception {
+        // validate that we can get and set the interface
+        MulticastSocket mss = new MulticastSocket();
+        mss.setNetworkInterface(networkInterface1);
+        assertEquals("Interface did not seem to be set by setNeworkInterface", networkInterface1, mss.getNetworkInterface());
+        mss.close();
+    }
+
+    public void test_setNetworkInterfaceLjava_net_NetworkInterface_IPv4() throws Exception {
+        test_setNetworkInterfaceLjava_net_NetworkInterface(GOOD_IPv4);
+    }
+
+    public void test_setNetworkInterfaceLjava_net_NetworkInterface_IPv6() throws Exception {
+        test_setNetworkInterfaceLjava_net_NetworkInterface(GOOD_IPv6);
+    }
+
+    private void test_setNetworkInterfaceLjava_net_NetworkInterface(InetAddress group) throws IOException, InterruptedException {
+        // set up the server and join the group
+        Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
+        while (theInterfaces.hasMoreElements()) {
+            NetworkInterface thisInterface = (NetworkInterface) theInterfaces.nextElement();
+            if (thisInterface.getInetAddresses().hasMoreElements()) {
+                if ((!((InetAddress) thisInterface.getInetAddresses().nextElement()).isLoopbackAddress())) {
+                    int[] ports = Support_PortManager.getNextPortsForUDP(2);
+                    int serverPort = ports[0];
+                    int groupPort = ports[1];
+
+                    MulticastServer server = new MulticastServer(group, serverPort);
+                    server.start();
+                    // give the server some time to start up
+                    Thread.sleep(1000);
+
+                    // Send the packets on a particular interface. The
+                    // source address in the received packet
+                    // should be one of the addresses for the interface
+                    // set
+                    MulticastSocket mss = new MulticastSocket(groupPort);
+                    mss.setNetworkInterface(thisInterface);
+                    String msg = thisInterface.getName();
+                    byte theBytes[] = msg.getBytes();
+                    DatagramPacket sdp = new DatagramPacket(theBytes, theBytes.length, group, serverPort);
+                    mss.send(sdp);
+                    Thread.sleep(1000);
+                    String receivedMessage = new String(server.rdp.getData(), 0, server.rdp.getLength());
+                    assertEquals("Group member did not recv data sent on a specific interface", msg, receivedMessage);
+                    // stop the server
+                    server.stopServer();
+                    mss.close();
+                }
+            }
+        }
+    }
+
+    public void test_setTimeToLiveI() throws Exception {
+        MulticastSocket mss = new MulticastSocket();
+        mss.setTimeToLive(120);
+        assertEquals("Returned incorrect 1st TTL", 120, mss.getTimeToLive());
+        mss.setTimeToLive(220);
+        assertEquals("Returned incorrect 2nd TTL", 220, mss.getTimeToLive());
+        mss.close();
+    }
+
+    public void test_setTTLB() throws Exception {
+        MulticastSocket mss = new MulticastSocket();
+        mss.setTTL((byte) 120);
+        assertEquals("Failed to set TTL", 120, mss.getTTL());
+        mss.close();
+    }
+
+    public void test_ConstructorLjava_net_SocketAddress() throws Exception {
+        MulticastSocket ms = new MulticastSocket((SocketAddress) null);
+        assertTrue("should not be bound", !ms.isBound() && !ms.isClosed() && !ms.isConnected());
+        ms.bind(new InetSocketAddress(InetAddress.getLocalHost(), Support_PortManager.getNextPortForUDP()));
+        assertTrue("should be bound", ms.isBound() && !ms.isClosed() && !ms.isConnected());
+        ms.close();
+        assertTrue("should be closed", ms.isClosed());
+        ms = new MulticastSocket(new InetSocketAddress(InetAddress.getLocalHost(), Support_PortManager.getNextPortForUDP()));
+        assertTrue("should be bound", ms.isBound() && !ms.isClosed() && !ms.isConnected());
+        ms.close();
+        assertTrue("should be closed", ms.isClosed());
+        ms = new MulticastSocket(new InetSocketAddress("localhost", Support_PortManager.getNextPortForUDP()));
+        assertTrue("should be bound", ms.isBound() && !ms.isClosed() && !ms.isConnected());
+        ms.close();
+        assertTrue("should be closed", ms.isClosed());
+        try {
+            ms = new MulticastSocket(new InetSocketAddress("unresolvedname", Support_PortManager.getNextPortForUDP()));
+            fail();
+        } catch (IOException expected) {
+        }
+
+        // regression test for Harmony-1162
+        InetSocketAddress addr = new InetSocketAddress("0.0.0.0", 0);
+        MulticastSocket s = new MulticastSocket(addr);
+        assertTrue(s.getReuseAddress());
+    }
+
+    public void test_getLoopbackMode() throws Exception {
+        MulticastSocket ms = new MulticastSocket((SocketAddress) null);
+        assertTrue("should not be bound", !ms.isBound() && !ms.isClosed() && !ms.isConnected());
+        ms.getLoopbackMode();
+        assertTrue("should not be bound", !ms.isBound() && !ms.isClosed() && !ms.isConnected());
+        ms.close();
+        assertTrue("should be closed", ms.isClosed());
+    }
+
+    public void test_setLoopbackModeZ() throws Exception {
+        MulticastSocket ms = new MulticastSocket();
+        ms.setLoopbackMode(true);
+        assertTrue("loopback should be true", ms.getLoopbackMode());
+        ms.setLoopbackMode(false);
+        assertTrue("loopback should be false", !ms.getLoopbackMode());
+        ms.close();
+        assertTrue("should be closed", ms.isClosed());
+    }
+
+    public void test_setLoopbackModeSendReceive_IPv4() throws Exception {
+        test_setLoopbackModeSendReceive(GOOD_IPv4);
+    }
+
+    public void test_setLoopbackModeSendReceive_IPv6() throws Exception {
+        test_setLoopbackModeSendReceive(GOOD_IPv6);
+    }
+
+    private void test_setLoopbackModeSendReceive(InetAddress group) throws IOException {
+        final int PORT = Support_PortManager.getNextPortForUDP();
+        final String message = "Hello, world!";
+
+        // test send receive
+        MulticastSocket socket = new MulticastSocket(PORT);
+        socket.setLoopbackMode(false); // false indicates doing loop back
+        socket.joinGroup(group);
+
+        // send the datagram
+        byte[] sendData = message.getBytes();
+        DatagramPacket sendDatagram = new DatagramPacket(sendData, 0, sendData.length, new InetSocketAddress(group, PORT));
+        socket.send(sendDatagram);
+
+        // receive the datagram
+        byte[] recvData = new byte[100];
+        DatagramPacket recvDatagram = new DatagramPacket(recvData, recvData.length);
+        socket.setSoTimeout(5000); // prevent eternal block in
+        socket.receive(recvDatagram);
+        String recvMessage = new String(recvData, 0, recvDatagram.getLength());
+        assertEquals(message, recvMessage);
+        socket.close();
+    }
+
+    public void test_setReuseAddressZ() throws Exception {
+        // test case were we set it to false
+        MulticastSocket theSocket1 = null;
+        MulticastSocket theSocket2 = null;
+        try {
+            InetSocketAddress theAddress = new InetSocketAddress(InetAddress.getLocalHost(), Support_PortManager.getNextPortForUDP());
+            theSocket1 = new MulticastSocket(null);
+            theSocket2 = new MulticastSocket(null);
+            theSocket1.setReuseAddress(false);
+            theSocket2.setReuseAddress(false);
+            theSocket1.bind(theAddress);
+            theSocket2.bind(theAddress);
+            fail("No exception when trying to connect to do duplicate socket bind with re-useaddr set to false");
+        } catch (BindException expected) {
+        }
+        if (theSocket1 != null) {
+            theSocket1.close();
+        }
+        if (theSocket2 != null) {
+            theSocket2.close();
+        }
+
+        // test case were we set it to true
+        InetSocketAddress theAddress = new InetSocketAddress(InetAddress.getLocalHost(), Support_PortManager.getNextPortForUDP());
+        theSocket1 = new MulticastSocket(null);
+        theSocket2 = new MulticastSocket(null);
+        theSocket1.setReuseAddress(true);
+        theSocket2.setReuseAddress(true);
+        theSocket1.bind(theAddress);
+        theSocket2.bind(theAddress);
+
+        if (theSocket1 != null) {
+            theSocket1.close();
+        }
+        if (theSocket2 != null) {
+            theSocket2.close();
+        }
+
+        // test the default case which we expect to be
+        // the same on all platforms
+        theAddress = new InetSocketAddress(InetAddress.getLocalHost(), Support_PortManager.getNextPortForUDP());
+        theSocket1 = new MulticastSocket(null);
+        theSocket2 = new MulticastSocket(null);
+        theSocket1.bind(theAddress);
+        theSocket2.bind(theAddress);
+        if (theSocket1 != null) {
+            theSocket1.close();
+        }
+        if (theSocket2 != null) {
+            theSocket2.close();
+        }
+    }
+
+    @Override
+    protected void setUp() {
+        Enumeration theInterfaces = null;
+        try {
+            theInterfaces = NetworkInterface.getNetworkInterfaces();
+        } catch (Exception e) {
+        }
+
+        // only consider interfaces that have addresses associated with them.
+        // Otherwise tests don't work so well
+        if (theInterfaces != null) {
+            boolean atLeastOneInterface = false;
+            while (theInterfaces.hasMoreElements() && (atLeastOneInterface == false)) {
+                networkInterface1 = (NetworkInterface) theInterfaces.nextElement();
+                if (networkInterface1.getInetAddresses().hasMoreElements()) {
+                    atLeastOneInterface = true;
+                }
+            }
+            assertTrue(atLeastOneInterface);
+
+            atLeastTwoInterfaces = false;
+            if (theInterfaces.hasMoreElements()) {
+                while (theInterfaces.hasMoreElements() && (atLeastTwoInterfaces == false)) {
+                    networkInterface2 = (NetworkInterface) theInterfaces.nextElement();
+                    if (networkInterface2.getInetAddresses().hasMoreElements()) {
+                        atLeastTwoInterfaces = true;
+                    }
+                }
+            }
+
+            // first the first interface that supports IPV6 if one exists
+            try {
+                theInterfaces = NetworkInterface.getNetworkInterfaces();
+            } catch (Exception e) {
+            }
+            boolean found = false;
+            while (theInterfaces.hasMoreElements() && !found) {
+                NetworkInterface nextInterface = (NetworkInterface) theInterfaces.nextElement();
+                Enumeration addresses = nextInterface.getInetAddresses();
+                if (addresses.hasMoreElements()) {
+                    while (addresses.hasMoreElements()) {
+                        InetAddress nextAddress = (InetAddress) addresses.nextElement();
+                        if (nextAddress instanceof Inet6Address) {
+                            IPV6networkInterface1 = nextInterface;
+                            found = true;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/NetworkInterfaceTest.java b/luni/src/test/java/tests/api/java/net/NetworkInterfaceTest.java
new file mode 100644
index 0000000..e377083
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/NetworkInterfaceTest.java
@@ -0,0 +1,496 @@
+/*
+ *  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.InetAddress;
+import java.net.InterfaceAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+public class NetworkInterfaceTest extends junit.framework.TestCase {
+
+    // private member variables used for tests
+    Enumeration<NetworkInterface> theInterfaces = null;
+
+    boolean atLeastOneInterface = false;
+
+    boolean atLeastTwoInterfaces = false;
+
+    private NetworkInterface networkInterface1 = null;
+
+    private NetworkInterface sameAsNetworkInterface1 = null;
+
+    private NetworkInterface networkInterface2 = null;
+
+    /**
+     * 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()));
+        }
+    }
+
+    /**
+     * java.net.NetworkInterface#getInetAddresses()
+     */
+    public void test_getInetAddresses() throws Exception {
+        if (atLeastOneInterface) {
+            Enumeration theAddresses = networkInterface1.getInetAddresses();
+            while (theAddresses.hasMoreElements()) {
+                InetAddress theAddress = (InetAddress) theAddresses
+                        .nextElement();
+                assertNotNull("validate that address is not null", theAddress);
+            }
+        }
+
+        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();
+                okAddresses.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();
+                    okAddresses.add(theAddress);
+                    index++;
+                }
+            }
+
+            // 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 without permission is not returned",
+                            !nextAddress.equals(notOkAddresses.get(i)));
+                }
+                if (atLeastTwoInterfaces) {
+                    reducedAddresses = networkInterface2.getInetAddresses();
+                    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 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)));
+            }
+        }
+    }
+
+    /**
+     * 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()));
+        }
+    }
+
+    /**
+     * 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) {
+        }
+
+        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) {
+                assertEquals(
+                        "validate that Interface can be obtained with its name",
+                        networkInterface1, 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) {
+                assertEquals(
+                        "validate that Interface can be obtained with its name",
+                        networkInterface2, NetworkInterface.getByName(theName));
+            }
+        }
+    }
+
+    /**
+     * java.net.NetworkInterface#getByInetAddress(java.net.InetAddress)
+     */
+    public void test_getByInetAddressLjava_net_InetAddress() throws Exception {
+
+        byte addressBytes[] = new byte[4];
+        addressBytes[0] = 0;
+        addressBytes[1] = 0;
+        addressBytes[2] = 0;
+        addressBytes[3] = 0;
+
+        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) {
+        }
+
+        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();
+            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));
+            }
+        }
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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));
+        }
+    }
+
+    /**
+     * 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());
+        }
+    }
+
+    /**
+     * 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()));
+
+        }
+    }
+
+    /**
+     * java.net.NetworkInterface#getInterfaceAddresses()
+     * @since 1.6
+     */
+    public void test_getInterfaceAddresses() throws SocketException {
+        if (theInterfaces != null) {
+            while (theInterfaces.hasMoreElements()) {
+                NetworkInterface netif = theInterfaces.nextElement();
+                assertEquals(netif.getName()
+                        + " getInterfaceAddresses should contain no element", 0,
+                        netif.getInterfaceAddresses().size());
+            }
+
+            theInterfaces = NetworkInterface.getNetworkInterfaces();
+            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);
+            }
+        }
+    }
+
+    /**
+     * 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;
+                    }
+                }
+                assertEquals(loopback, netif.isLoopback());
+            }
+        }
+    }
+
+    /**
+     * 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);
+                }
+            }
+        }
+    }
+
+    /**
+     * 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();
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/NoRouteToHostExceptionTest.java b/luni/src/test/java/tests/api/java/net/NoRouteToHostExceptionTest.java
new file mode 100644
index 0000000..bddd414
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/NoRouteToHostExceptionTest.java
@@ -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.
+ */
+
+package tests.api.java.net;
+
+import java.net.NoRouteToHostException;
+
+public class NoRouteToHostExceptionTest extends junit.framework.TestCase {
+
+    /**
+     * java.net.NoRouteToHostException#NoRouteToHostException()
+     */
+    public void test_Constructor() {
+        try {
+            if (true) {
+                throw new NoRouteToHostException();
+            }
+            fail("Failed to generate expected exception");
+        } catch (NoRouteToHostException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.net.NoRouteToHostException#NoRouteToHostException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        // Cannot test correctly without changing some routing tables !!
+        try {
+            if (true) {
+                throw new NoRouteToHostException("test");
+            }
+            fail("Failed to generate expected exception");
+        } catch (NoRouteToHostException e) {
+            assertEquals("Threw exception with incorrect message", "test", e
+                    .getMessage());
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/PasswordAuthenticationTest.java b/luni/src/test/java/tests/api/java/net/PasswordAuthenticationTest.java
new file mode 100644
index 0000000..732941c
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/PasswordAuthenticationTest.java
@@ -0,0 +1,74 @@
+/*
+ *  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.PasswordAuthentication;
+
+public class PasswordAuthenticationTest extends junit.framework.TestCase {
+
+    /**
+     * java.net.PasswordAuthentication#PasswordAuthentication(java.lang.String,
+     *char[])
+     */
+    public void test_ConstructorLjava_lang_String$C() {
+        // Test for method java.net.PasswordAuthentication(java.lang.String,
+        // char [])
+        char[] password = new char[] { 'd', 'r', 'o', 'w', 's', 's', 'a', 'p' };
+        final String name = "Joe Blow";
+        PasswordAuthentication pa = new PasswordAuthentication(name, password);
+        char[] returnedPassword = pa.getPassword();
+        assertTrue("Incorrect name", pa.getUserName().equals(name));
+        assertTrue("Password was not cloned", returnedPassword != password);
+        assertTrue("Passwords not equal length",
+                returnedPassword.length == password.length);
+        for (int counter = password.length - 1; counter >= 0; counter--)
+            assertTrue("Passwords not equal",
+                    returnedPassword[counter] == password[counter]);
+    }
+
+    /**
+     * java.net.PasswordAuthentication#getPassword()
+     */
+    public void test_getPassword() {
+        // Test for method char [] java.net.PasswordAuthentication.getPassword()
+        assertTrue("Used to test", true);
+    }
+
+    /**
+     * java.net.PasswordAuthentication#getUserName()
+     */
+    public void test_getUserName() {
+        // Test for method java.lang.String
+        // java.net.PasswordAuthentication.getUserName()
+        assertTrue("Used to test", true);
+    }
+
+    /**
+     * 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() {
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/ProtocolExceptionTest.java b/luni/src/test/java/tests/api/java/net/ProtocolExceptionTest.java
new file mode 100644
index 0000000..fecf678
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/ProtocolExceptionTest.java
@@ -0,0 +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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES 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.ProtocolException;
+
+public class ProtocolExceptionTest extends junit.framework.TestCase {
+
+    /**
+     * java.net.ProtocolException#ProtocolException()
+     */
+    public void test_Constructor() {
+        // Test for method java.net.ProtocolException()
+        try {
+            throw new ProtocolException();
+        } catch (ProtocolException e) {
+            return;
+        } catch (Exception e) {
+            fail("Exception during ProtocolException test : " + e.getMessage());
+        }
+        fail("Failed to generate expected exception");
+    }
+
+    /**
+     * java.net.ProtocolException#ProtocolException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        // Test for method java.net.ProtocolException(java.lang.String)
+        try {
+            throw new ProtocolException("Some error message");
+        } catch (ProtocolException e) {
+            return;
+        } catch (Exception e) {
+            fail("Exception during ProtocolException test : " + e.getMessage());
+        }
+        fail("Failed to generate expected exception");
+    }
+
+    /**
+     * 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() {
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/ProxySelectorTest.java b/luni/src/test/java/tests/api/java/net/ProxySelectorTest.java
new file mode 100644
index 0000000..995ffef
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/ProxySelectorTest.java
@@ -0,0 +1,562 @@
+/* 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.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.NetPermission;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.Permission;
+import java.util.List;
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+public class ProxySelectorTest extends TestCase {
+
+    private static final String HTTP_PROXY_HOST = "127.0.0.1";
+
+    private static final int HTTP_PROXY_PORT = 80;
+
+    private static final String HTTPS_PROXY_HOST = "127.0.0.2";
+
+    private static final int HTTPS_PROXY_PORT = 443;
+
+    private static final String FTP_PROXY_HOST = "127.0.0.3";
+
+    private static final int FTP_PROXY_PORT = 80;
+
+    private static final String SOCKS_PROXY_HOST = "127.0.0.4";
+
+    private static final int SOCKS_PROXY_PORT = 1080;
+
+    private static URI httpUri;
+
+    private static URI ftpUri;
+
+    private static URI httpsUri;
+
+    private static URI tcpUri;
+
+    private List proxyList;
+
+    private ProxySelector selector = ProxySelector.getDefault();
+
+    static {
+        try {
+            httpUri = new URI("http://test.com");
+            ftpUri = new URI("ftp://test.com");
+            httpsUri = new URI("https://test.com");
+            tcpUri = new URI("socket://host.com");
+        } catch (URISyntaxException e) {
+
+        }
+    }
+
+    /*
+      * Original system properties must be restored after running each test case.
+      */
+    private Properties originalSystemProperties;
+
+    /**
+     * java.net.ProxySelector#getDefault()
+     */
+    public void test_getDefault() {
+        ProxySelector selector1 = ProxySelector.getDefault();
+        assertNotNull(selector1);
+
+        ProxySelector selector2 = ProxySelector.getDefault();
+        assertSame(selector1, selector2);
+    }
+
+    /**
+     * java.net.ProxySelector#setDefault(ProxySelector)}
+     */
+    public void test_setDefaultLjava_net_ProxySelector() {
+        ProxySelector originalSelector = ProxySelector.getDefault();
+        try {
+            ProxySelector newSelector = new MockProxySelector();
+            ProxySelector.setDefault(newSelector);
+            assertSame(newSelector, ProxySelector.getDefault());
+            // use null to unset
+            ProxySelector.setDefault(null);
+            assertSame(null, ProxySelector.getDefault());
+        } finally {
+            ProxySelector.setDefault(originalSelector);
+        }
+    }
+
+    /**
+     * java.net.ProxySelector#select(URI)
+     */
+    public void test_selectLjava_net_URI_SelectExact()
+            throws URISyntaxException {
+        // no proxy, return a proxyList only contains NO_PROXY
+        proxyList = selector.select(httpUri);
+        assertProxyEquals(proxyList, Proxy.NO_PROXY);
+
+        // set http proxy
+        System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+        System.setProperty("http.proxyPort", String.valueOf(HTTP_PROXY_PORT));
+        // set https proxy
+        System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+        System.setProperty("https.proxyPort", String.valueOf(HTTPS_PROXY_PORT));
+        // set ftp proxy
+        System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+        System.setProperty("ftp.proxyPort", String.valueOf(FTP_PROXY_PORT));
+        // set socks proxy
+        System.setProperty("socksProxyHost", SOCKS_PROXY_HOST);
+        System.setProperty("socksProxyPort", String.valueOf(SOCKS_PROXY_PORT));
+
+        proxyList = selector.select(httpUri);
+        assertProxyEquals(proxyList, Proxy.Type.HTTP, HTTP_PROXY_HOST, HTTP_PROXY_PORT);
+
+        proxyList = selector.select(httpsUri);
+        assertProxyEquals(proxyList, Proxy.Type.HTTP, HTTPS_PROXY_HOST, HTTPS_PROXY_PORT);
+
+        proxyList = selector.select(ftpUri);
+        assertProxyEquals(proxyList, Proxy.Type.HTTP, FTP_PROXY_HOST, FTP_PROXY_PORT);
+
+        proxyList = selector.select(tcpUri);
+        assertProxyEquals(proxyList, Proxy.Type.SOCKS, SOCKS_PROXY_HOST, SOCKS_PROXY_PORT);
+
+    }
+
+    /**
+     * java.net.ProxySelector#select(URI)
+     */
+    public void test_selectLjava_net_URI_SelectExact_NullHost()
+            throws URISyntaxException {
+        // regression test for Harmony-1063
+        httpUri = new URI("http://a@");
+        ftpUri = new URI("ftp://a@");
+        httpsUri = new URI("https://a@");
+        tcpUri = new URI("socket://a@");
+        // no proxy, return a proxyList only contains NO_PROXY
+        proxyList = selector.select(httpUri);
+        assertProxyEquals(proxyList, Proxy.NO_PROXY);
+
+        // set http proxy
+        System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+        System.setProperty("http.proxyPort", String.valueOf(HTTP_PROXY_PORT));
+        // set https proxy
+        System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+        System.setProperty("https.proxyPort", String.valueOf(HTTPS_PROXY_PORT));
+        // set ftp proxy
+        System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+        System.setProperty("ftp.proxyPort", String.valueOf(FTP_PROXY_PORT));
+        // set socks proxy
+        System.setProperty("socksProxyHost", SOCKS_PROXY_HOST);
+        System.setProperty("socksProxyPort", String.valueOf(SOCKS_PROXY_PORT));
+
+        proxyList = selector.select(httpUri);
+        assertProxyEquals(proxyList, Proxy.Type.HTTP, HTTP_PROXY_HOST,
+                HTTP_PROXY_PORT);
+
+        proxyList = selector.select(httpsUri);
+        assertProxyEquals(proxyList, Proxy.Type.HTTP, HTTPS_PROXY_HOST,
+                HTTPS_PROXY_PORT);
+
+        proxyList = selector.select(ftpUri);
+        assertProxyEquals(proxyList, Proxy.Type.HTTP, FTP_PROXY_HOST,
+                FTP_PROXY_PORT);
+
+        proxyList = selector.select(tcpUri);
+        assertProxyEquals(proxyList, Proxy.Type.SOCKS, SOCKS_PROXY_HOST,
+                SOCKS_PROXY_PORT);
+
+    }
+
+    //Regression for HARMONY-4281
+    public void test_selectLjava_net_URI_SelectExact_NullHost_withNoProxyHostsProperty() {
+        System.setProperty("http.nonProxyHosts", "localhost|127.0.0.1");
+        System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+        System.setProperty("http.proxyPort", String.valueOf(HTTP_PROXY_PORT));
+        // set https proxy
+        System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+        System.setProperty("https.proxyPort", String.valueOf(HTTPS_PROXY_PORT));
+        // set ftp proxy
+        System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+        System.setProperty("ftp.proxyPort", String.valueOf(FTP_PROXY_PORT));
+        // set socks proxy
+        System.setProperty("socksProxyHost", SOCKS_PROXY_HOST);
+        System.setProperty("socksProxyPort", String.valueOf(SOCKS_PROXY_PORT));
+
+        proxyList = selector.select(httpUri);
+        assertProxyEquals(proxyList, Proxy.Type.HTTP, HTTP_PROXY_HOST,
+                HTTP_PROXY_PORT);
+    }
+
+    /**
+     * java.net.ProxySelector#select(URI)
+     */
+    public void test_selectLjava_net_URI_SelectExact_DefaultPort()
+            throws URISyntaxException {
+        // set http proxy
+        System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+
+        // set https proxy
+        System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+        // set ftp proxy
+        System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+        // set socks proxy
+        System.setProperty("socksProxyHost", SOCKS_PROXY_HOST);
+
+        proxyList = selector.select(httpUri);
+        assertProxyEquals(proxyList, Proxy.Type.HTTP, HTTP_PROXY_HOST, HTTP_PROXY_PORT);
+
+        proxyList = selector.select(httpsUri);
+        assertProxyEquals(proxyList, Proxy.Type.HTTP, HTTPS_PROXY_HOST, HTTPS_PROXY_PORT);
+
+        proxyList = selector.select(ftpUri);
+        assertProxyEquals(proxyList, Proxy.Type.HTTP, FTP_PROXY_HOST, FTP_PROXY_PORT);
+
+        proxyList = selector.select(tcpUri);
+        assertProxyEquals(proxyList, Proxy.Type.SOCKS, SOCKS_PROXY_HOST, SOCKS_PROXY_PORT);
+
+    }
+
+    /**
+     * java.net.ProxySelector#select(URI)
+     */
+    public void test_selectLjava_net_URI_SelectExact_InvalidPort()
+            throws URISyntaxException {
+        final String INVALID_PORT = "abc";
+
+        // set http proxy
+        System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+        System.setProperty("http.proxyPort", INVALID_PORT);
+        // set https proxy
+        System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+        System.setProperty("https.proxyPort", INVALID_PORT);
+        // set ftp proxy
+        System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+        System.setProperty("ftp.proxyPort", INVALID_PORT);
+        // set socks proxy
+        System.setProperty("socksProxyHost", SOCKS_PROXY_HOST);
+        System.setProperty("socksproxyPort", INVALID_PORT);
+
+        proxyList = selector.select(httpUri);
+        assertProxyEquals(proxyList, Proxy.Type.HTTP, HTTP_PROXY_HOST, HTTP_PROXY_PORT);
+
+        proxyList = selector.select(httpsUri);
+        assertProxyEquals(proxyList, Proxy.Type.HTTP, HTTPS_PROXY_HOST, HTTPS_PROXY_PORT);
+
+        proxyList = selector.select(ftpUri);
+        assertProxyEquals(proxyList, Proxy.Type.HTTP, FTP_PROXY_HOST, FTP_PROXY_PORT);
+
+        proxyList = selector.select(tcpUri);
+        assertProxyEquals(proxyList, Proxy.Type.SOCKS, SOCKS_PROXY_HOST, SOCKS_PROXY_PORT);
+    }
+
+    /**
+     * java.net.ProxySelector#select(URI)
+     */
+    // RI may fail this test case.
+    // Uncomment this test case when regex.jar is ready.
+    /*
+     public void test_selectLjava_net_URI_Select_NonProxyHosts()
+             throws URISyntaxException {
+         // RI's bug. Some RIs may fail this test case.
+         URI[] httpUris = { new URI("http://test.com"),
+                 new URI("http://10.10.1.2"), new URI("http://a"),
+                 new URI("http://def.abc.com") };
+         URI[] ftpUris = { new URI("ftp://test.com"),
+                 new URI("ftp://10.10.1.2"), new URI("ftp://a"),
+                 new URI("ftp://def.abc.com") };
+
+         // set http proxy
+         System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+         System.setProperty("http.nonProxyHosts", "a|b|tes*|10.10.*|*.abc.com");
+         // set ftp proxy
+         System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+         System.setProperty("ftp.nonProxyHosts", "a|b|tes*|10.10.*|*.abc.com");
+
+         for (int i = 0; i < httpUris.length; i++) {
+             proxyList = selector.select(httpUris[i]);
+             assertProxyEquals(proxyList,Proxy.NO_PROXY);
+         }
+
+         for (int i = 0; i < ftpUris.length; i++) {
+             proxyList = selector.select(ftpUris[i]);
+             assertProxyEquals(proxyList,Proxy.NO_PROXY);
+         }
+     }*/
+
+    /**
+     * java.net.ProxySelector#select(URI)
+     */
+    public void test_selectLjava_net_URI_SelectLikeHTTP()
+            throws URISyntaxException {
+        System.setProperty("http.proxyHost", "");
+        // set https proxy
+        System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+        System.setProperty("https.proxyPort", String.valueOf(HTTPS_PROXY_PORT));
+        // set ftp proxy
+        System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+        System.setProperty("ftp.proxyPort", String.valueOf(FTP_PROXY_PORT));
+        // set socks proxy
+        System.setProperty("socksProxyHost", SOCKS_PROXY_HOST);
+        System.setProperty("socksProxyPort", String.valueOf(SOCKS_PROXY_PORT));
+
+        proxyList = selector.select(httpUri);
+        assertProxyEquals(proxyList, Proxy.Type.SOCKS, SOCKS_PROXY_HOST, SOCKS_PROXY_PORT);
+    }
+
+    /**
+     * java.net.ProxySelector#select(URI)
+     */
+    public void test_selectLjava_net_URI_SelectNoHTTP()
+            throws URISyntaxException {
+        // set https proxy
+        System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+        System.setProperty("https.proxyPort", String.valueOf(HTTPS_PROXY_PORT));
+        // set ftp proxy
+        System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+        System.setProperty("ftp.proxyPort", String.valueOf(FTP_PROXY_PORT));
+
+        proxyList = selector.select(httpUri);
+        assertProxyEquals(proxyList, Proxy.NO_PROXY);
+    }
+
+    /**
+     * java.net.ProxySelector#select(URI)
+     */
+    public void test_selectLjava_net_URI_SelectLikeHTTPS()
+            throws URISyntaxException {
+        // set http proxy
+        System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+        System.setProperty("http.proxyPort", String.valueOf(HTTP_PROXY_PORT));
+        // set https proxy host empty
+        System.setProperty("http.proxyHost", "");
+        // set ftp proxy
+        System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+        System.setProperty("ftp.proxyPort", String.valueOf(FTP_PROXY_PORT));
+        // set socks proxy
+        System.setProperty("socksProxyHost", SOCKS_PROXY_HOST);
+        System.setProperty("socksProxyPort", String.valueOf(SOCKS_PROXY_PORT));
+
+        proxyList = selector.select(httpsUri);
+        assertProxyEquals(proxyList, Proxy.Type.SOCKS, SOCKS_PROXY_HOST, SOCKS_PROXY_PORT);
+    }
+
+    /**
+     * java.net.ProxySelector#select(URI)
+     */
+    public void test_selectLjava_net_URI_SelectNoHTTPS()
+            throws URISyntaxException {
+        // set https proxy
+        System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+        System.setProperty("http.proxyPort", String.valueOf(HTTP_PROXY_PORT));
+        // set ftp proxy
+        System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+        System.setProperty("ftp.proxyPort", String.valueOf(FTP_PROXY_PORT));
+
+        proxyList = selector.select(httpsUri);
+        assertProxyEquals(proxyList, Proxy.NO_PROXY);
+    }
+
+    /**
+     * java.net.ProxySelector#select(URI)
+     */
+    public void test_selectLjava_net_URI_SelectLikeFTP()
+            throws URISyntaxException {
+        // set http proxy
+        System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+        System.setProperty("http.proxyPort", String.valueOf(HTTP_PROXY_PORT));
+        // set ftp host empty
+        System.setProperty("ftp.proxyHost", "");
+        // set https proxy
+        System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+        System.setProperty("https.proxyPort", String.valueOf(HTTPS_PROXY_PORT));
+        // set socks proxy
+        System.setProperty("socksProxyHost", SOCKS_PROXY_HOST);
+        System.setProperty("socksProxyPort", String.valueOf(SOCKS_PROXY_PORT));
+
+        proxyList = selector.select(ftpUri);
+        assertProxyEquals(proxyList, Proxy.Type.SOCKS, SOCKS_PROXY_HOST, SOCKS_PROXY_PORT);
+    }
+
+    /**
+     * java.net.ProxySelector#select(URI)
+     */
+    public void test_selectLjava_net_URI_SelectNoFTP()
+            throws URISyntaxException {
+        // set http proxy
+        System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+        System.setProperty("http.proxyPort", String.valueOf(HTTP_PROXY_PORT));
+        // set https proxy
+        System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+        System.setProperty("https.proxyPort", String.valueOf(HTTPS_PROXY_PORT));
+
+        proxyList = selector.select(ftpUri);
+        assertProxyEquals(proxyList, Proxy.NO_PROXY);
+    }
+
+    /**
+     * java.net.ProxySelector#select(URI)
+     */
+    public void test_selectLjava_net_URI_SelectNoSOCKS()
+            throws URISyntaxException {
+        // set http proxy
+        System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+        System.setProperty("http.proxyPort", String.valueOf(HTTP_PROXY_PORT));
+        // set https proxy
+        System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+        System.setProperty("https.proxyPort", String.valueOf(HTTPS_PROXY_PORT));
+        // set socks proxy
+        System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+        System.setProperty("ftp.proxyPort", String.valueOf(FTP_PROXY_PORT));
+
+        proxyList = selector.select(tcpUri);
+        assertProxyEquals(proxyList, Proxy.NO_PROXY);
+    }
+
+    /**
+     * java.net.ProxySelector#select(URI)
+     */
+    public void test_connectionFailedLjava_net_URILjava_net_SocketAddressLjava_io_IOException()
+            throws URISyntaxException {
+        // set http proxy
+        System.setProperty("http.proxyHost", HTTP_PROXY_HOST);
+        System.setProperty("http.proxyPort", String.valueOf(HTTP_PROXY_PORT));
+        // set https proxy
+        System.setProperty("https.proxyHost", HTTPS_PROXY_HOST);
+        System.setProperty("https.proxyPort", String.valueOf(HTTPS_PROXY_PORT));
+        // set ftp proxy
+        System.setProperty("ftp.proxyHost", FTP_PROXY_HOST);
+        System.setProperty("ftp.proxyPort", String.valueOf(FTP_PROXY_PORT));
+        // set socks proxy
+        System.setProperty("socksProxyHost", SOCKS_PROXY_HOST);
+        System.setProperty("socksProxyPort", String.valueOf(SOCKS_PROXY_PORT));
+
+        List proxyList1 = selector.select(httpUri);
+        assertNotNull(proxyList1);
+        assertEquals(1, proxyList1.size());
+        Proxy proxy1 = (Proxy) proxyList1.get(0);
+        selector
+                .connectFailed(httpUri, proxy1.address(), new SocketException());
+
+        List proxyList2 = selector.select(httpUri);
+        assertNotNull(proxyList2);
+        assertEquals(1, proxyList2.size());
+        Proxy proxy2 = (Proxy) proxyList2.get(0);
+        // Default implementation doesn't change the proxy list
+        assertEquals(proxy1, proxy2);
+    }
+
+    /**
+     * java.net.ProxySelector#select(URI)
+     */
+    public void test_connectionFailedLjava_net_URILjava_net_SocketAddressLjava_io_IOException_IllegalArguement()
+            throws URISyntaxException {
+        SocketAddress sa = InetSocketAddress.createUnresolved("127.0.0.1", 0);
+        try {
+            selector.connectFailed(null, sa, new SocketException());
+            fail("should throw IllegalArgumentException if any argument is null.");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            selector.connectFailed(httpUri, null, new SocketException());
+            fail("should throw IllegalArgumentException if any argument is null.");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            selector.connectFailed(httpUri, sa, null);
+            fail("should throw IllegalArgumentException if any argument is null.");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+    }
+
+    /**
+     * java.net.ProxySelector#select(URI)
+     */
+    public void test_selectLjava_net_URI_IllegalArgument()
+            throws URISyntaxException {
+        URI[] illegalUris = { new URI("abc"), new URI("http"), null };
+        for (int i = 0; i < illegalUris.length; i++) {
+            try {
+                selector.select(illegalUris[i]);
+                fail("should throw IllegalArgumentException");
+            } catch (IllegalArgumentException e) {
+                // expected
+            }
+        }
+    }
+
+    /*
+      * asserts whether selectedProxyList contains one and only one element,
+      * and the element equals proxy.
+      */
+    private void assertProxyEquals(List selectedProxyList, Proxy proxy) {
+        assertNotNull(selectedProxyList);
+        assertEquals(1, selectedProxyList.size());
+        assertEquals((Proxy) selectedProxyList.get(0), proxy);
+    }
+
+    /*
+      * asserts whether selectedProxyList contains one and only one element,
+      * and the element equals proxy which is represented by arguments "type",
+      * "host","port".
+      */
+    private void assertProxyEquals(List selectedProxyList, Proxy.Type type,
+            String host, int port) {
+        SocketAddress sa = InetSocketAddress.createUnresolved(host, port);
+        Proxy proxy = new Proxy(type, sa);
+        assertProxyEquals(selectedProxyList, proxy);
+    }
+
+    /*
+      * Mock selector for setDefault test
+      */
+    static class MockProxySelector extends ProxySelector {
+
+        public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
+
+        }
+
+        public List<Proxy> select(URI uri) {
+            return null;
+        }
+    }
+
+    /*
+      * @see junit.framework.TestCase#setUp()
+      */
+    protected void setUp() throws Exception {
+        super.setUp();
+        // save original system properties
+        originalSystemProperties = (Properties) System.getProperties().clone();
+    }
+
+    /*
+      * @see junit.framework.TestCase#tearDown()
+      */
+    protected void tearDown() throws Exception {
+        // restore original system properties
+        System.setProperties(originalSystemProperties);
+        super.tearDown();
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/ProxyTest.java b/luni/src/test/java/tests/api/java/net/ProxyTest.java
new file mode 100644
index 0000000..f004683
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/ProxyTest.java
@@ -0,0 +1,238 @@
+/* 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.InetSocketAddress;
+import java.net.Proxy;
+import java.net.SocketAddress;
+
+import junit.framework.TestCase;
+
+public class ProxyTest extends TestCase {
+
+    private SocketAddress address = new InetSocketAddress("127.0.0.1", 1234);
+
+    /**
+     * java.net.Proxy#Proxy(java.net.Proxy.Type, SocketAddress)
+     */
+    public void test_ConstructorLjava_net_ProxyLjava_net_SocketAddress_Normal() {
+        // test HTTP type proxy
+        Proxy proxy = new Proxy(Proxy.Type.HTTP, address);
+        assertEquals(Proxy.Type.HTTP, proxy.type());
+        assertEquals(address, proxy.address());
+
+        // test SOCKS type proxy
+        proxy = new Proxy(Proxy.Type.SOCKS, address);
+        assertEquals(Proxy.Type.SOCKS, proxy.type());
+        assertEquals(address, proxy.address());
+
+        // test DIRECT type proxy
+        proxy = Proxy.NO_PROXY;
+        assertEquals(Proxy.Type.DIRECT, proxy.type());
+        assertNull(proxy.address());
+    }
+
+    /**
+     * java.net.Proxy#Proxy(java.net.Proxy.Type, SocketAddress)
+     */
+    public void test_ConstructorLjava_net_ProxyLjava_net_SocketAddress_IllegalAddress() {
+        Proxy proxy = null;
+        // test HTTP type proxy
+        try {
+            proxy = new Proxy(Proxy.Type.HTTP, null);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        // test SOCKS type proxy
+        try {
+            proxy = new Proxy(Proxy.Type.SOCKS, null);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        // test DIRECT type proxy
+        try {
+            proxy = new Proxy(Proxy.Type.DIRECT, null);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        // test DIRECT type proxy, any address is illegal
+        try {
+            proxy = new Proxy(Proxy.Type.DIRECT, address);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+    }
+
+    /**
+     * java.net.Proxy#hashCode()
+     * @see also see test_equalsLjava_lang_Object_Equals
+     */
+    public void test_hashCode() {
+        // This method has been tested in test_equalsLjava_lang_Object_Equals.
+    }
+
+    /**
+     * java.net.Proxy#type()
+     */
+    public void test_type() {
+        // This method has been tested in test_ConstructorLjava_net_ProxyLjava_net_SocketAddress_Normal.
+    }
+
+    /**
+     * java.net.Proxy#address() This method has been tested in
+     * Constructor test case.
+     */
+    public void test_address() {
+        // This method has been tested in test_ConstructorLjava_net_ProxyLjava_net_SocketAddress_Normal.
+    }
+
+    /**
+     * java.net.Proxy#toString()
+     */
+    public void test_toString() {
+        Proxy proxy = new Proxy(Proxy.Type.HTTP, address);
+        // include type String
+        assertTrue(proxy.toString().indexOf(proxy.type().toString()) != -1);
+        // include address String
+        assertTrue(proxy.toString().indexOf(proxy.address().toString()) != -1);
+
+        proxy = new Proxy(Proxy.Type.SOCKS, address);
+        // include type String
+        assertTrue(proxy.toString().indexOf(proxy.type().toString()) != -1);
+        // include address String
+        assertTrue(proxy.toString().indexOf(proxy.address().toString()) != -1);
+
+        proxy = Proxy.NO_PROXY;
+        // include type String
+        assertTrue(proxy.toString().indexOf(proxy.type().toString()) != -1);
+
+        proxy = new Proxy(null, address);
+        // ensure no NPE is thrown
+        proxy.toString();
+
+        // Regression test for Java 6 spec change
+        proxy = new Proxy(Proxy.Type.HTTP, address);
+        assertTrue(proxy.toString().contains("@"));
+        proxy = new Proxy(Proxy.Type.SOCKS, address);
+        assertTrue(proxy.toString().contains(address.toString()));
+    }
+
+    /**
+     * java.net.Proxy#equals(Object)
+     */
+    public void test_equalsLjava_lang_Object_Equals() {
+        SocketAddress address1 = new InetSocketAddress("127.0.0.1", 1234);
+        SocketAddress address2 = new InetSocketAddress("127.0.0.1", 1234);
+        // HTTP type
+        Proxy proxy1 = new Proxy(Proxy.Type.HTTP, address1);
+        Proxy proxy2 = new Proxy(Proxy.Type.HTTP, address2);
+        assertTrue(proxy1.equals(proxy2));
+        // assert hashCode
+        assertTrue(proxy1.hashCode() == proxy2.hashCode());
+
+        // SOCKS type
+        Proxy proxy3 = new Proxy(Proxy.Type.SOCKS, address1);
+        Proxy proxy4 = new Proxy(Proxy.Type.SOCKS, address2);
+        assertTrue(proxy3.equals(proxy4));
+        // assert hashCode
+        assertTrue(proxy3.hashCode() == proxy4.hashCode());
+
+        // null type
+        Proxy proxy5 = new Proxy(null, address1);
+        Proxy proxy6 = new Proxy(null, address2);
+        assertTrue(proxy5.equals(proxy6));
+    }
+
+    /**
+     * java.net.Proxy#equals(Object)
+     */
+    public void test_equalsLjava_lang_Object_NotEquals() {
+        SocketAddress address1 = new InetSocketAddress("127.0.0.1", 1234);
+        SocketAddress address2 = new InetSocketAddress("127.0.0.1", 1235);
+        Proxy proxy[] = { new Proxy(Proxy.Type.HTTP, address1),
+                new Proxy(Proxy.Type.HTTP, address2),
+                new Proxy(Proxy.Type.SOCKS, address1),
+                new Proxy(Proxy.Type.SOCKS, address2), Proxy.NO_PROXY,
+                new Proxy(null, address1), new Proxy(null, address2) };
+        // All of them are not equals
+        for (int i = 0; i < proxy.length; i++) {
+            for (int j = i + 1; j < proxy.length; j++) {
+                assertFalse(proxy[i].equals(proxy[j]));
+            }
+        }
+        // Not equals to an Object type instance. Ensure no exception is thrown.
+        assertFalse(proxy[0].equals(new Object()));
+    }
+
+    /**
+     * java.net.Proxy.Type#valueOf(String)
+     */
+    public void test_Type_valueOfLjava_lang_String_Normal() {
+        assertEquals(Proxy.Type.DIRECT, Proxy.Type.valueOf("DIRECT"));
+        assertEquals(Proxy.Type.HTTP, Proxy.Type.valueOf("HTTP"));
+        assertEquals(Proxy.Type.SOCKS, Proxy.Type.valueOf("SOCKS"));
+    }
+
+    /**
+     * java.net.Proxy.Type#valueOf(String)
+     */
+    public void test_Type_valueOfLjava_lang_String_IllegalName() {
+        String[] illegalName = { "Direct", "direct", "http", "socks",
+                "illegalName", "" };
+        for (int i = 0; i < illegalName.length; i++) {
+            try {
+                Proxy.Type.valueOf(illegalName[i]);
+                fail("should throw IllegalArgumentException, illegalName:"
+                        + illegalName);
+            } catch (IllegalArgumentException e) {
+                // expected
+            }
+        }
+    }
+
+    /**
+     * java.net.Proxy.Type#valueOf(String)
+     */
+    public void test_Type_valueOfLjava_lang_String_NullPointerException() {
+        // Some old RIs,which throw IllegalArgumentException.
+        // Latest RIs throw NullPointerException.
+        try {
+            Proxy.Type.valueOf(null);
+            fail("should throw an exception.");
+        } catch (NullPointerException e) {
+            // May be caused by some compilers' code
+        } catch (IllegalArgumentException e) {
+            // other compilers will throw this
+        }
+    }
+
+    /**
+     * java.net.Proxy.Type#values()
+     */
+    public void test_Type_values() {
+        Proxy.Type types[] = Proxy.Type.values();
+        assertEquals(3, types.length);
+        assertEquals(Proxy.Type.DIRECT, types[0]);
+        assertEquals(Proxy.Type.HTTP, types[1]);
+        assertEquals(Proxy.Type.SOCKS, types[2]);
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/net/ResponseCacheTest.java b/luni/src/test/java/tests/api/java/net/ResponseCacheTest.java
new file mode 100644
index 0000000..51d7f6d
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/ResponseCacheTest.java
@@ -0,0 +1,70 @@
+/* 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.io.IOException;
+import java.net.CacheRequest;
+import java.net.CacheResponse;
+import java.net.NetPermission;
+import java.net.ResponseCache;
+import java.net.URI;
+import java.net.URLConnection;
+import java.security.Permission;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+public class ResponseCacheTest extends TestCase {
+
+    /**
+     * java.net.ResponseCache#getDefault()
+     */
+    public void test_GetDefault() throws Exception {
+        assertNull(ResponseCache.getDefault());
+    }
+
+    /**
+     * java.net.ResponseCache#setDefault(ResponseCache)
+     */
+    public void test_SetDefaultLjava_net_ResponseCache_Normal()
+            throws Exception {
+        ResponseCache rc1 = new MockResponseCache();
+        ResponseCache rc2 = new MockResponseCache();
+        ResponseCache.setDefault(rc1);
+        assertSame(ResponseCache.getDefault(), rc1);
+        ResponseCache.setDefault(rc2);
+        assertSame(ResponseCache.getDefault(), rc2);
+        ResponseCache.setDefault(null);
+        assertNull(ResponseCache.getDefault());
+    }
+
+    /*
+      * MockResponseCache for testSetDefault(ResponseCache)
+      */
+    class MockResponseCache extends ResponseCache {
+
+        public CacheResponse get(URI arg0, String arg1, Map arg2)
+                throws IOException {
+            return null;
+        }
+
+        public CacheRequest put(URI arg0, URLConnection arg1)
+                throws IOException {
+            return null;
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/SecureCacheResponseTest.java b/luni/src/test/java/tests/api/java/net/SecureCacheResponseTest.java
new file mode 100644
index 0000000..b7babe7
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/SecureCacheResponseTest.java
@@ -0,0 +1,85 @@
+/* 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.io.IOException;
+import java.io.InputStream;
+import java.net.SecureCacheResponse;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.util.List;
+import java.util.Map;
+
+import javax.net.ssl.SSLPeerUnverifiedException;
+
+import junit.framework.TestCase;
+
+public class SecureCacheResponseTest extends TestCase {
+
+    public void testSecureCacheResponse() {
+        // test constructor
+        SecureCacheResponse sc = new MockCacheResponse();
+        // nothing happened
+        assertNull(sc.getCipherSuite());
+    }
+
+    class MockCacheResponse extends SecureCacheResponse {
+
+        @Override
+        public String getCipherSuite() {
+            // do nothing
+            return null;
+        }
+
+        @Override
+        public List<Certificate> getLocalCertificateChain() {
+            // do nothing
+            return null;
+        }
+
+        @Override
+        public Principal getLocalPrincipal() {
+            // do nothing
+            return null;
+        }
+
+        @Override
+        public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
+            // do nothing
+            return null;
+        }
+
+        @Override
+        public List<Certificate> getServerCertificateChain() throws SSLPeerUnverifiedException {
+            // do nothing
+            return null;
+        }
+
+        @Override
+        public InputStream getBody() throws IOException {
+            // do nothing
+            return null;
+        }
+
+        @Override
+        public Map<String, List<String>> getHeaders() throws IOException {
+            // do nothing
+            return null;
+        }
+
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/ServerSocketTest.java b/luni/src/test/java/tests/api/java/net/ServerSocketTest.java
new file mode 100644
index 0000000..c0e2496
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/ServerSocketTest.java
@@ -0,0 +1,949 @@
+/*
+ *  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 tests.support.Support_Configuration;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.net.BindException;
+import java.net.ConnectException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.PlainServerSocketImpl;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketImpl;
+import java.net.SocketImplFactory;
+import java.net.UnknownHostException;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Properties;
+
+public class ServerSocketTest extends junit.framework.TestCase {
+
+    boolean interrupted;
+
+    ServerSocket s;
+
+    Socket sconn;
+
+    Thread t;
+
+    static class SSClient implements Runnable {
+        Socket cs;
+
+        int port;
+
+        public SSClient(int prt) {
+            port = prt;
+        }
+
+        public void run() {
+            try {
+                // Go to sleep so the server can setup and wait for connection
+                Thread.sleep(1000);
+                cs = new Socket(InetAddress.getLocalHost().getHostName(), port);
+                // Sleep again to allow server side processing. Thread is
+                // stopped by server.
+                Thread.sleep(10000);
+            } catch (InterruptedException e) {
+                return;
+            } catch (Throwable e) {
+                System.out
+                        .println("Error establishing client: " + e.toString());
+            } finally {
+                try {
+                    if (cs != null)
+                        cs.close();
+                } catch (Exception e) {
+                }
+            }
+        }
+    }
+
+    /**
+     * java.net.ServerSocket#ServerSocket()
+     */
+    public void test_Constructor() {
+        // Test for method java.net.ServerSocket(int)
+        assertTrue("Used during tests", true);
+    }
+
+    /**
+     * java.net.ServerSocket#ServerSocket(int)
+     */
+    public void test_ConstructorI() {
+        // Test for method java.net.ServerSocket(int)
+        assertTrue("Used during tests", true);
+    }
+
+    /**
+     * java.net.ServerSocket#ServerSocket(int)
+     */
+    public void test_ConstructorI_SocksSet() throws IOException {
+        // Harmony-623 regression test
+        ServerSocket ss = null;
+        Properties props = (Properties) System.getProperties().clone();
+        try {
+            System.setProperty("socksProxyHost", "127.0.0.1");
+            System.setProperty("socksProxyPort", "12345");
+            ss = new ServerSocket(0);
+        } finally {
+            System.setProperties(props);
+            if (null != ss) {
+                ss.close();
+            }
+        }
+    }
+
+    /**
+     * java.net.ServerSocket#ServerSocket(int, int)
+     */
+    public void test_ConstructorII() throws IOException {
+        try {
+            s = new ServerSocket(0, 10);
+            s.setSoTimeout(2000);
+            startClient(s.getLocalPort());
+            sconn = s.accept();
+        } catch (InterruptedIOException e) {
+            return;
+        }
+
+        ServerSocket s1 = new ServerSocket(0);
+        try {
+            try {
+                ServerSocket s2 = new ServerSocket(s1.getLocalPort());
+                s2.close();
+                fail("Was able to create two serversockets on same port");
+            } catch (BindException e) {
+                // Expected
+            }
+        } finally {
+            s1.close();
+        }
+
+        s1 = new ServerSocket(0);
+        int allocatedPort = s1.getLocalPort();
+        s1.close();
+        s1 = new ServerSocket(allocatedPort);
+        s1.close();
+    }
+
+    /**
+     * java.net.ServerSocket#ServerSocket(int, int, java.net.InetAddress)
+     */
+    public void test_ConstructorIILjava_net_InetAddress()
+            throws UnknownHostException, IOException {
+        s = new ServerSocket(0, 10, InetAddress.getLocalHost());
+        try {
+            s.setSoTimeout(5000);
+            startClient(s.getLocalPort());
+            sconn = s.accept();
+            assertNotNull("Was unable to accept connection", sconn);
+            sconn.close();
+        } finally {
+            s.close();
+        }
+    }
+
+    /**
+     * java.net.ServerSocket#accept()
+     */
+    public void test_accept() throws IOException {
+        s = new ServerSocket(0);
+        try {
+            s.setSoTimeout(5000);
+            startClient(s.getLocalPort());
+            sconn = s.accept();
+            int localPort1 = s.getLocalPort();
+            int localPort2 = sconn.getLocalPort();
+            sconn.close();
+            assertEquals("Bad local port value", localPort1, localPort2);
+        } finally {
+            s.close();
+        }
+
+        try {
+            interrupted = false;
+            final ServerSocket ss = new ServerSocket(0);
+            ss.setSoTimeout(12000);
+            Runnable runnable = new Runnable() {
+                public void run() {
+                    try {
+                        ss.accept();
+                    } catch (InterruptedIOException e) {
+                        interrupted = true;
+                    } catch (IOException e) {
+                    }
+                }
+            };
+            Thread thread = new Thread(runnable, "ServerSocket.accept");
+            thread.start();
+            try {
+                do {
+                    Thread.sleep(500);
+                } while (!thread.isAlive());
+            } catch (InterruptedException e) {
+            }
+            ss.close();
+            int c = 0;
+            do {
+                try {
+                    Thread.sleep(500);
+                } catch (InterruptedException e) {
+                }
+                if (interrupted) {
+                    fail("accept interrupted");
+                }
+                if (++c > 4) {
+                    fail("accept call did not exit");
+                }
+            } while (thread.isAlive());
+
+            interrupted = false;
+            ServerSocket ss2 = new ServerSocket(0);
+            ss2.setSoTimeout(500);
+            Date start = new Date();
+            try {
+                ss2.accept();
+            } catch (InterruptedIOException e) {
+                interrupted = true;
+            }
+            assertTrue("accept not interrupted", interrupted);
+            Date finish = new Date();
+            int delay = (int) (finish.getTime() - start.getTime());
+            assertTrue("timeout too soon: " + delay + " " + start.getTime()
+                    + " " + finish.getTime(), delay >= 490);
+            ss2.close();
+        } catch (IOException e) {
+            fail("Unexpected IOException : " + e.getMessage());
+        }
+    }
+
+    /**
+     * java.net.ServerSocket#close()
+     */
+    public void test_close() throws IOException {
+        try {
+            s = new ServerSocket(0);
+            try {
+                s.close();
+                s.accept();
+                fail("Close test failed");
+            } catch (SocketException e) {
+                // expected;
+            }
+        } finally {
+            s.close();
+        }
+    }
+
+    /**
+     * java.net.ServerSocket#getInetAddress()
+     */
+    public void test_getInetAddress() throws IOException {
+        InetAddress addr = InetAddress.getLocalHost();
+        s = new ServerSocket(0, 10, addr);
+        try {
+            assertEquals("Returned incorrect InetAdrees", addr, s
+                    .getInetAddress());
+        } finally {
+            s.close();
+        }
+    }
+
+    /**
+     * java.net.ServerSocket#getLocalPort()
+     */
+    public void test_getLocalPort() throws IOException {
+        // Try a specific port number, but don't complain if we don't get it
+        int portNumber = 63024; // I made this up
+        try {
+            try {
+                s = new ServerSocket(portNumber);
+            } catch (BindException e) {
+                // we could not get the port, give up
+                return;
+            }
+            assertEquals("Returned incorrect port", portNumber, s
+                    .getLocalPort());
+        } finally {
+            s.close();
+        }
+    }
+
+    /**
+     * java.net.ServerSocket#getSoTimeout()
+     */
+    public void test_getSoTimeout() throws IOException {
+        s = new ServerSocket(0);
+        try {
+            s.setSoTimeout(100);
+            assertEquals("Returned incorrect sotimeout", 100, s.getSoTimeout());
+        } finally {
+            s.close();
+        }
+    }
+
+    /**
+     * java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
+     */
+    public void test_setSocketFactoryLjava_net_SocketImplFactory()
+            throws IOException {
+        SocketImplFactory factory = new MockSocketImplFactory();
+        // Should not throw SocketException when set DatagramSocketImplFactory
+        // for the first time.
+        ServerSocket.setSocketFactory(factory);
+
+        try {
+            ServerSocket.setSocketFactory(null);
+            fail("Should throw SocketException");
+        } catch (SocketException e) {
+            // Expected
+        }
+
+        try {
+            ServerSocket.setSocketFactory(factory);
+            fail("Should throw SocketException");
+        } catch (SocketException e) {
+            // Expected
+        }
+    }
+
+    private static class MockSocketImplFactory implements SocketImplFactory {
+        public SocketImpl createSocketImpl() {
+            return new PlainServerSocketImpl();
+        }
+    }
+
+    /**
+     * java.net.ServerSocket#setSoTimeout(int)
+     */
+    public void test_setSoTimeoutI() throws IOException {
+        // Timeout should trigger and throw InterruptedIOException
+        try {
+            s = new ServerSocket(0);
+            s.setSoTimeout(100);
+            s.accept();
+        } catch (InterruptedIOException e) {
+            assertEquals("Set incorrect sotimeout", 100, s.getSoTimeout());
+            return;
+        }
+
+        // Timeout should not trigger in this case
+        s = new ServerSocket(0);
+        startClient(s.getLocalPort());
+        s.setSoTimeout(10000);
+        sconn = s.accept();
+    }
+
+    /**
+     * java.net.ServerSocket#toString()
+     */
+    public void test_toString() throws Exception {
+        s = new ServerSocket(0);
+        try {
+            int portNumber = s.getLocalPort();
+            assertEquals("ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport="
+                    + portNumber + "]", s.toString());
+        } finally {
+            s.close();
+        }
+    }
+
+    /**
+     * java.net.ServerSocket#bind(java.net.SocketAddress)
+     */
+    public void test_bindLjava_net_SocketAddress() throws IOException {
+        class mySocketAddress extends SocketAddress {
+            public mySocketAddress() {
+            }
+        }
+        // create servers socket, bind it and then validate basic state
+        ServerSocket theSocket = new ServerSocket();
+        InetSocketAddress theAddress = new InetSocketAddress(InetAddress
+                .getLocalHost(), 0);
+        theSocket.bind(theAddress);
+        int portNumber = theSocket.getLocalPort();
+        assertTrue(
+                "Returned incorrect InetSocketAddress(2):"
+                        + theSocket.getLocalSocketAddress().toString()
+                        + "Expected: "
+                        + (new InetSocketAddress(InetAddress.getLocalHost(),
+                        portNumber)).toString(), theSocket
+                .getLocalSocketAddress().equals(
+                        new InetSocketAddress(InetAddress
+                                .getLocalHost(), portNumber)));
+        assertTrue("Server socket not bound when it should be:", theSocket
+                .isBound());
+
+        // now make sure that it is actually bound and listening on the
+        // address we provided
+        Socket clientSocket = new Socket();
+        InetSocketAddress clAddress = new InetSocketAddress(InetAddress
+                .getLocalHost(), portNumber);
+        clientSocket.connect(clAddress);
+        Socket servSock = theSocket.accept();
+
+        assertEquals(clAddress, clientSocket.getRemoteSocketAddress());
+        theSocket.close();
+        servSock.close();
+        clientSocket.close();
+
+        // validate we can specify null for the address in the bind and all
+        // goes ok
+        theSocket = new ServerSocket();
+        theSocket.bind(null);
+        theSocket.close();
+
+        // Address that we have already bound to
+        theSocket = new ServerSocket();
+        ServerSocket theSocket2 = new ServerSocket();
+        try {
+            theAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0);
+            theSocket.bind(theAddress);
+            SocketAddress localAddress = theSocket.getLocalSocketAddress();
+            theSocket2.bind(localAddress);
+            fail("No exception binding to address that is not available");
+        } catch (IOException ex) {
+        }
+        theSocket.close();
+        theSocket2.close();
+
+        // validate we get io address when we try to bind to address we
+        // cannot bind to
+        theSocket = new ServerSocket();
+        try {
+            theSocket.bind(new InetSocketAddress(InetAddress
+                    .getByAddress(Support_Configuration.nonLocalAddressBytes),
+                    0));
+            fail("No exception was thrown when binding to bad address");
+        } catch (IOException ex) {
+        }
+        theSocket.close();
+
+        // now validate case where we pass in an unsupported subclass of
+        // SocketAddress
+        theSocket = new ServerSocket();
+        try {
+            theSocket.bind(new mySocketAddress());
+            fail("No exception when binding using unsupported SocketAddress subclass");
+        } catch (IllegalArgumentException ex) {
+        }
+        theSocket.close();
+    }
+
+    /**
+     * java.net.ServerSocket#bind(java.net.SocketAddress, int)
+     */
+    public void test_bindLjava_net_SocketAddressI() throws IOException {
+        class mySocketAddress extends SocketAddress {
+
+            public mySocketAddress() {
+            }
+        }
+
+        // create servers socket, bind it and then validate basic state
+        ServerSocket theSocket = new ServerSocket();
+        InetSocketAddress theAddress = new InetSocketAddress(InetAddress
+                .getLocalHost(), 0);
+        theSocket.bind(theAddress, 5);
+        int portNumber = theSocket.getLocalPort();
+        assertTrue(
+                "Returned incorrect InetSocketAddress(2):"
+                        + theSocket.getLocalSocketAddress().toString()
+                        + "Expected: "
+                        + (new InetSocketAddress(InetAddress.getLocalHost(),
+                        portNumber)).toString(), theSocket
+                .getLocalSocketAddress().equals(
+                        new InetSocketAddress(InetAddress
+                                .getLocalHost(), portNumber)));
+        assertTrue("Server socket not bound when it should be:", theSocket
+                .isBound());
+
+        // now make sure that it is actually bound and listening on the
+        // address we provided
+        SocketAddress localAddress = theSocket.getLocalSocketAddress();
+        Socket clientSocket = new Socket();
+        clientSocket.connect(localAddress);
+        Socket servSock = theSocket.accept();
+
+        assertTrue(clientSocket.getRemoteSocketAddress().equals(localAddress));
+        theSocket.close();
+        servSock.close();
+        clientSocket.close();
+
+        // validate we can specify null for the address in the bind and all
+        // goes ok
+        theSocket = new ServerSocket();
+        theSocket.bind(null, 5);
+        theSocket.close();
+
+        // Address that we have already bound to
+        theSocket = new ServerSocket();
+        ServerSocket theSocket2 = new ServerSocket();
+        try {
+            theAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0);
+            theSocket.bind(theAddress, 5);
+            SocketAddress inuseAddress = theSocket.getLocalSocketAddress();
+            theSocket2.bind(inuseAddress, 5);
+            fail("No exception binding to address that is not available");
+        } catch (IOException ex) {
+            // expected
+        }
+        theSocket.close();
+        theSocket2.close();
+
+        // validate we get ioException when we try to bind to address we
+        // cannot bind to
+        theSocket = new ServerSocket();
+        try {
+            theSocket.bind(new InetSocketAddress(InetAddress
+                    .getByAddress(Support_Configuration.nonLocalAddressBytes),
+                    0), 5);
+            fail("No exception was thrown when binding to bad address");
+        } catch (IOException ex) {
+        }
+        theSocket.close();
+
+        // now validate case where we pass in an unsupported subclass of
+        // SocketAddress
+        theSocket = new ServerSocket();
+        try {
+            theSocket.bind(new mySocketAddress(), 5);
+            fail("Binding using unsupported SocketAddress subclass should have thrown exception");
+        } catch (IllegalArgumentException ex) {
+        }
+        theSocket.close();
+
+        // now validate that backlog is respected. We have to do a test that
+        // checks if it is a least a certain number as some platforms make
+        // it higher than we request. Unfortunately non-server versions of
+        // windows artificially limit the backlog to 5 and 5 is the
+        // historical default so it is not a great test.
+        theSocket = new ServerSocket();
+        theAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0);
+        theSocket.bind(theAddress, 4);
+        localAddress = theSocket.getLocalSocketAddress();
+        Socket theSockets[] = new Socket[4];
+        int i = 0;
+        try {
+            for (i = 0; i < 4; i++) {
+                theSockets[i] = new Socket();
+                theSockets[i].connect(localAddress);
+            }
+        } catch (ConnectException ex) {
+            fail("Backlog does not seem to be respected in bind:" + i + ":"
+                    + ex.toString());
+        }
+
+        for (i = 0; i < 4; i++) {
+            theSockets[i].close();
+        }
+
+        theSocket.close();
+        servSock.close();
+    }
+
+    /**
+     * java.net.ServerSocket#getLocalSocketAddress()
+     */
+    public void test_getLocalSocketAddress() throws Exception {
+        // set up server connect and then validate that we get the right
+        // response for the local address
+        ServerSocket theSocket = new ServerSocket(0, 5, InetAddress
+                .getLocalHost());
+        int portNumber = theSocket.getLocalPort();
+        assertTrue("Returned incorrect InetSocketAddress(1):"
+                + theSocket.getLocalSocketAddress().toString()
+                + "Expected: "
+                + (new InetSocketAddress(InetAddress.getLocalHost(),
+                portNumber)).toString(), theSocket
+                .getLocalSocketAddress().equals(
+                        new InetSocketAddress(InetAddress.getLocalHost(),
+                                portNumber)));
+        theSocket.close();
+
+        // now create a socket that is not bound and validate we get the
+        // right answer
+        theSocket = new ServerSocket();
+        assertNull(
+                "Returned incorrect InetSocketAddress -unbound socket- Expected null",
+                theSocket.getLocalSocketAddress());
+
+        // now bind the socket and make sure we get the right answer
+        theSocket
+                .bind(new InetSocketAddress(InetAddress.getLocalHost(), 0));
+        int localPort = theSocket.getLocalPort();
+        assertEquals("Returned incorrect InetSocketAddress(2):", theSocket
+                .getLocalSocketAddress(), new InetSocketAddress(InetAddress
+                .getLocalHost(), localPort));
+        theSocket.close();
+    }
+
+    /**
+     * java.net.ServerSocket#isBound()
+     */
+    public void test_isBound() throws IOException {
+        InetAddress addr = InetAddress.getLocalHost();
+        ServerSocket serverSocket = new ServerSocket();
+        assertFalse("Socket indicated bound when it should be (1)",
+                serverSocket.isBound());
+
+        // now bind and validate bound ok
+        serverSocket.bind(new InetSocketAddress(addr, 0));
+        assertTrue("Socket indicated  not bound when it should be (1)",
+                serverSocket.isBound());
+        serverSocket.close();
+
+        // now do with some of the other constructors
+        serverSocket = new ServerSocket(0);
+        assertTrue("Socket indicated  not bound when it should be (2)",
+                serverSocket.isBound());
+        serverSocket.close();
+
+        serverSocket = new ServerSocket(0, 5, addr);
+        assertTrue("Socket indicated  not bound when it should be (3)",
+                serverSocket.isBound());
+        serverSocket.close();
+
+        serverSocket = new ServerSocket(0, 5);
+        assertTrue("Socket indicated  not bound when it should be (4)",
+                serverSocket.isBound());
+        serverSocket.close();
+    }
+
+    /**
+     * java.net.ServerSocket#isClosed()
+     */
+    public void test_isClosed() throws IOException {
+        InetAddress addr = InetAddress.getLocalHost();
+        ServerSocket serverSocket = new ServerSocket(0, 5, addr);
+
+        // validate isClosed returns expected values
+        assertFalse("Socket should indicate it is not closed(1):", serverSocket
+                .isClosed());
+        serverSocket.close();
+        assertTrue("Socket should indicate it is closed(1):", serverSocket
+                .isClosed());
+
+        // now do with some of the other constructors
+        serverSocket = new ServerSocket(0);
+        assertFalse("Socket should indicate it is not closed(1):", serverSocket
+                .isClosed());
+        serverSocket.close();
+        assertTrue("Socket should indicate it is closed(1):", serverSocket
+                .isClosed());
+
+        serverSocket = new ServerSocket(0, 5, addr);
+        assertFalse("Socket should indicate it is not closed(1):", serverSocket
+                .isClosed());
+        serverSocket.close();
+        assertTrue("Socket should indicate it is closed(1):", serverSocket
+                .isClosed());
+
+        serverSocket = new ServerSocket(0, 5);
+        assertFalse("Socket should indicate it is not closed(1):", serverSocket
+                .isClosed());
+        serverSocket.close();
+        assertTrue("Socket should indicate it is closed(1):", serverSocket
+                .isClosed());
+    }
+
+    /*
+     * Regression HARMONY-6090
+     */
+    public void test_defaultValueReuseAddress() throws Exception {
+        String platform = System.getProperty("os.name").toLowerCase(Locale.US);
+        if (!platform.startsWith("windows")) {
+            // on Unix
+            assertTrue(new ServerSocket().getReuseAddress());
+            assertTrue(new ServerSocket(0).getReuseAddress());
+            assertTrue(new ServerSocket(0, 50).getReuseAddress());
+            assertTrue(new ServerSocket(0, 50, InetAddress.getLocalHost()).getReuseAddress());
+        } else {
+            // on Windows
+            assertFalse(new ServerSocket().getReuseAddress());
+            assertFalse(new ServerSocket(0).getReuseAddress());
+            assertFalse(new ServerSocket(0, 50).getReuseAddress());
+            assertFalse(new ServerSocket(0, 50, InetAddress.getLocalHost()).getReuseAddress());
+        }
+    }
+
+    public void test_setReuseAddressZ() throws Exception {
+        // set up server and connect
+        InetSocketAddress anyAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0);
+        ServerSocket serverSocket = new ServerSocket();
+        serverSocket.setReuseAddress(false);
+        serverSocket.bind(anyAddress);
+        SocketAddress theAddress = serverSocket.getLocalSocketAddress();
+
+        // make a connection to the server, then close the server
+        Socket theSocket = new Socket();
+        theSocket.connect(theAddress);
+        Socket stillActiveSocket = serverSocket.accept();
+        serverSocket.close();
+
+        // now try to rebind the server which should fail with
+        // setReuseAddress to false. On windows platforms the bind is
+        // allowed even then reUseAddress is false so our test uses
+        // the platform to determine what the expected result is.
+        String platform = System.getProperty("os.name");
+        try {
+            serverSocket = new ServerSocket();
+            serverSocket.setReuseAddress(false);
+            serverSocket.bind(theAddress);
+            fail("No exception when setReuseAddress is false and we bind:" + theAddress.toString());
+        } catch (IOException expected) {
+        }
+        stillActiveSocket.close();
+        theSocket.close();
+
+        // now test case were we set it to true
+        anyAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0);
+        serverSocket = new ServerSocket();
+        serverSocket.setReuseAddress(true);
+        serverSocket.bind(anyAddress);
+        theAddress = serverSocket.getLocalSocketAddress();
+
+        // make a connection to the server, then close the server
+        theSocket = new Socket();
+        theSocket.connect(theAddress);
+        stillActiveSocket = serverSocket.accept();
+        serverSocket.close();
+
+        // now try to rebind the server which should pass with
+        // setReuseAddress to true
+        try {
+            serverSocket = new ServerSocket();
+            serverSocket.setReuseAddress(true);
+            serverSocket.bind(theAddress);
+        } catch (IOException ex) {
+            fail("Unexpected exception when setReuseAddress is true and we bind:"
+                    + theAddress.toString() + ":" + ex.toString());
+        }
+        stillActiveSocket.close();
+        theSocket.close();
+
+        // now test default case were we expect this to work regardless of
+        // the value set
+        anyAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0);
+        serverSocket = new ServerSocket();
+        serverSocket.bind(anyAddress);
+        theAddress = serverSocket.getLocalSocketAddress();
+
+        // make a connection to the server, then close the server
+        theSocket = new Socket();
+        theSocket.connect(theAddress);
+        stillActiveSocket = serverSocket.accept();
+        serverSocket.close();
+
+        // now try to rebind the server which should pass
+        try {
+            serverSocket = new ServerSocket();
+            serverSocket.bind(theAddress);
+        } catch (IOException ex) {
+            fail("Unexpected exception when setReuseAddress is the default case and we bind:"
+                    + theAddress.toString() + ":" + ex.toString());
+        }
+        stillActiveSocket.close();
+        theSocket.close();
+    }
+
+    public void test_getReuseAddress() throws Exception {
+        ServerSocket theSocket = new ServerSocket();
+        theSocket.setReuseAddress(true);
+        assertTrue("getReuseAddress false when it should be true", theSocket.getReuseAddress());
+        theSocket.setReuseAddress(false);
+        assertFalse("getReuseAddress true when it should be False", theSocket.getReuseAddress());
+    }
+
+    public void test_setReceiveBufferSizeI() throws Exception {
+        // now validate case where we try to set to 0
+        ServerSocket theSocket = new ServerSocket();
+        try {
+            theSocket.setReceiveBufferSize(0);
+            fail("No exception when receive buffer size set to 0");
+        } catch (IllegalArgumentException ex) {
+        }
+        theSocket.close();
+
+        // now validate case where we try to set to a negative value
+        theSocket = new ServerSocket();
+        try {
+            theSocket.setReceiveBufferSize(-1000);
+            fail("No exception when receive buffer size set to -1000");
+        } catch (IllegalArgumentException ex) {
+        }
+        theSocket.close();
+
+        // now just try to set a good value to make sure it is set and there
+        // are not exceptions
+        theSocket = new ServerSocket();
+        theSocket.setReceiveBufferSize(1000);
+        theSocket.close();
+    }
+
+    public void test_getReceiveBufferSize() throws Exception {
+        ServerSocket theSocket = new ServerSocket();
+
+        // since the value returned is not necessary what we set we are
+        // limited in what we can test
+        // just validate that it is not 0 or negative
+        assertFalse("get Buffer size returns 0:", 0 == theSocket.getReceiveBufferSize());
+        assertFalse("get Buffer size returns  a negative value:", 0 > theSocket.getReceiveBufferSize());
+    }
+
+    public void test_getChannel() throws Exception {
+        assertNull(new ServerSocket().getChannel());
+    }
+
+    public void test_setPerformancePreference_Int_Int_Int() throws Exception {
+        ServerSocket theSocket = new ServerSocket();
+        theSocket.setPerformancePreferences(1, 1, 1);
+    }
+
+    /**
+     * 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 {
+            if (s != null)
+                s.close();
+            if (sconn != null)
+                sconn.close();
+            if (t != null)
+                t.interrupt();
+        } catch (Exception e) {
+        }
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void startClient(int port) {
+        t = new Thread(new SSClient(port), "SSClient");
+        t.start();
+        try {
+            Thread.sleep(1000);
+        } catch (InterruptedException e) {
+            System.out.println("Exception during startClinet()" + e.toString());
+        }
+    }
+
+    /**
+     * java.net.ServerSocket#implAccept
+     */
+    public void test_implAcceptLjava_net_Socket() throws Exception {
+        // regression test for Harmony-1235
+        try {
+            new MockServerSocket().mockImplAccept(new MockSocket(
+                    new MockSocketImpl()));
+        } catch (SocketException e) {
+            // expected
+        }
+    }
+
+    static class MockSocketImpl extends SocketImpl {
+        protected void create(boolean arg0) throws IOException {
+            // empty
+        }
+
+        protected void connect(String arg0, int arg1) throws IOException {
+            // empty
+        }
+
+        protected void connect(InetAddress arg0, int arg1) throws IOException {
+            // empty
+        }
+
+        protected void connect(SocketAddress arg0, int arg1) throws IOException {
+            // empty
+        }
+
+        protected void bind(InetAddress arg0, int arg1) throws IOException {
+            // empty
+        }
+
+        protected void listen(int arg0) throws IOException {
+            // empty
+        }
+
+        protected void accept(SocketImpl arg0) throws IOException {
+            // empty
+        }
+
+        protected InputStream getInputStream() throws IOException {
+            return null;
+        }
+
+        protected OutputStream getOutputStream() throws IOException {
+            return null;
+        }
+
+        protected int available() throws IOException {
+            return 0;
+        }
+
+        protected void close() throws IOException {
+            // empty
+        }
+
+        protected void sendUrgentData(int arg0) throws IOException {
+            // empty
+        }
+
+        public void setOption(int arg0, Object arg1) throws SocketException {
+            // empty
+        }
+
+        public Object getOption(int arg0) throws SocketException {
+            return null;
+        }
+    }
+
+    static class MockSocket extends Socket {
+        public MockSocket(SocketImpl impl) throws SocketException {
+            super(impl);
+        }
+    }
+
+    static class MockServerSocket extends ServerSocket {
+        public MockServerSocket() throws Exception {
+            super();
+        }
+
+        public void mockImplAccept(Socket s) throws Exception {
+            super.implAccept(s);
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/SocketExceptionTest.java b/luni/src/test/java/tests/api/java/net/SocketExceptionTest.java
new file mode 100644
index 0000000..8f54494
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/SocketExceptionTest.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 tests.api.java.net;
+
+import java.net.SocketException;
+
+public class SocketExceptionTest extends junit.framework.TestCase {
+
+    /**
+     * java.net.SocketException#SocketException()
+     */
+    public void test_Constructor() {
+        try {
+            if (true) {
+                throw new SocketException();
+            }
+            fail("Failed to generate expected exception");
+        } catch (SocketException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.net.SocketException#SocketException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        try {
+            if (true) {
+                throw new SocketException("Some error message");
+            }
+            fail("Failed to generate expected exception");
+        } catch (SocketException e) {
+            // Expected
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/SocketImplTest.java b/luni/src/test/java/tests/api/java/net/SocketImplTest.java
new file mode 100644
index 0000000..0be87b6
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/SocketImplTest.java
@@ -0,0 +1,155 @@
+/*
+ *  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.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketImpl;
+
+public class SocketImplTest extends junit.framework.TestCase {
+
+    /**
+     * java.net.SocketImpl#SocketImpl()
+     */
+    public void test_Constructor_fd() {
+        // Regression test for HARMONY-1117
+        MockSocketImpl mockSocketImpl = new MockSocketImpl();
+        assertNull(mockSocketImpl.getFileDescriptor());
+    }
+
+    /**
+     * java.net.SocketImpl#setPerformancePreference()
+     */
+    public void test_setPerformancePreference_Int_Int_Int() {
+        MockSocketImpl theSocket = new MockSocketImpl();
+        theSocket.setPerformancePreference(1, 1, 1);
+    }
+
+    /**
+     * java.net.SocketImpl#shutdownOutput()
+     */
+    public void test_shutdownOutput() {
+        MockSocketImpl s = new MockSocketImpl();
+        try {
+            s.shutdownOutput();
+            fail("This method is still not implemented yet,It should throw IOException.");
+        } catch (IOException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.net.SocketImpl#shutdownInput()
+     */
+    public void test_shutdownInput() {
+        MockSocketImpl s = new MockSocketImpl();
+        try {
+            s.shutdownInput();
+            fail("This method is still not implemented yet,It should throw IOException.");
+        } catch (IOException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.net.SocketImpl#supportsUrgentData()
+     */
+    public void test_supportsUrgentData() {
+        MockSocketImpl s = new MockSocketImpl();
+        assertFalse(s.testSupportsUrgentData());
+    }
+
+    // the mock class for test, leave all methods empty
+    class MockSocketImpl extends SocketImpl {
+
+        protected void accept(SocketImpl newSocket) throws IOException {
+        }
+
+        protected int available() throws IOException {
+            return 0;
+        }
+
+        protected void bind(InetAddress address, int port) throws IOException {
+        }
+
+        protected void close() throws IOException {
+        }
+
+        protected void connect(String host, int port) throws IOException {
+        }
+
+        protected void connect(InetAddress address, int port)
+                throws IOException {
+        }
+
+        protected void create(boolean isStreaming) throws IOException {
+        }
+
+        protected InputStream getInputStream() throws IOException {
+            return null;
+        }
+
+        public Object getOption(int optID) throws SocketException {
+            return null;
+        }
+
+        protected OutputStream getOutputStream() throws IOException {
+            return null;
+        }
+
+        protected void listen(int backlog) throws IOException {
+        }
+
+        public void setOption(int optID, Object val) throws SocketException {
+        }
+
+        protected void connect(SocketAddress remoteAddr, int timeout)
+                throws IOException {
+        }
+
+        protected void sendUrgentData(int value) throws IOException {
+        }
+
+        public void setPerformancePreference(int connectionTime, int latency,
+                int bandwidth) {
+            super.setPerformancePreferences(connectionTime, latency, bandwidth);
+        }
+
+        public FileDescriptor getFileDescriptor() {
+            return super.getFileDescriptor();
+        }
+
+        public void shutdownOutput() throws IOException {
+            super.shutdownOutput();
+        }
+
+        public void shutdownInput() throws IOException {
+            super.shutdownInput();
+        }
+
+        public boolean testSupportsUrgentData() {
+            return super.supportsUrgentData();
+        }
+
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/SocketTest.java b/luni/src/test/java/tests/api/java/net/SocketTest.java
new file mode 100644
index 0000000..fafc80c
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/SocketTest.java
@@ -0,0 +1,1636 @@
+/*
+ *  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.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ConnectException;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketImpl;
+import java.net.SocketImplFactory;
+import java.net.SocketTimeoutException;
+import java.net.UnknownHostException;
+import java.security.Permission;
+import java.util.Arrays;
+import java.util.Locale;
+
+import tests.support.Support_Configuration;
+
+public class SocketTest extends junit.framework.TestCase {
+    private class ClientThread implements Runnable {
+
+        public void run() {
+            try {
+                Socket socket = new Socket();
+                InetSocketAddress addr = new InetSocketAddress(host, port);
+                socket.connect(addr);
+
+                socket.close();
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private class ServerThread implements Runnable {
+        private static final int FIRST_TIME = 1;
+
+        private static final int SECOND_TIME = 2;
+
+        private int backlog = 10;
+
+        public boolean ready = false;
+
+        private int serverSocketConstructor = 0;
+
+        public void run() {
+            try {
+
+                ServerSocket socket = null;
+                switch (serverSocketConstructor) {
+                    case FIRST_TIME:
+                        socket = new ServerSocket(port, backlog,
+                                new InetSocketAddress(host, port).getAddress());
+                        port = socket.getLocalPort();
+                        break;
+                    case SECOND_TIME:
+                        socket = new ServerSocket(port, backlog);
+                        host = socket.getInetAddress().getHostName();
+                        port = socket.getLocalPort();
+                        break;
+                    default:
+                        socket = new ServerSocket();
+                        break;
+                }
+
+                synchronized (this) {
+                    ready = true;
+                    this.notifyAll();
+                }
+
+                socket.setSoTimeout(5000);
+                Socket client = socket.accept();
+                client.close();
+                socket.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            } catch (Throwable e) {
+                e.printStackTrace();
+            }
+        }
+
+        public synchronized void waitCreated() throws Exception {
+            while (!ready) {
+                this.wait();
+            }
+        }
+    }
+
+    boolean interrupted;
+
+    String host = "localhost";
+    int port;
+
+    Thread t;
+
+    private void connectTestImpl(int ssConsType) throws Exception {
+        ServerThread server = new ServerThread();
+        server.serverSocketConstructor = ssConsType;
+        Thread serverThread = new Thread(server);
+        serverThread.start();
+        server.waitCreated();
+
+        ClientThread client = new ClientThread();
+        Thread clientThread = new Thread(client);
+        clientThread.start();
+        try {
+            serverThread.join();
+            clientThread.join();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    protected void tearDown() {
+        try {
+            if (t != null) {
+                t.interrupt();
+            }
+        } catch (Exception e) {
+        }
+        this.t = null;
+        this.interrupted = false;
+    }
+
+    /**
+     * java.net.Socket#bind(java.net.SocketAddress)
+     */
+    public void test_bindLjava_net_SocketAddress() throws IOException {
+
+        @SuppressWarnings("serial")
+        class UnsupportedSocketAddress extends SocketAddress {
+            public UnsupportedSocketAddress() {
+            }
+        }
+
+        // Address we cannot bind to
+        Socket theSocket = new Socket();
+        InetSocketAddress bogusAddress = new InetSocketAddress(InetAddress
+                .getByAddress(Support_Configuration.nonLocalAddressBytes), 42);
+        try {
+            theSocket.bind(bogusAddress);
+            fail("No exception when binding to bad address");
+        } catch (IOException ex) {
+            // Expected
+        }
+        theSocket.close();
+
+        // Now create a socket that is not bound and then bind it
+        theSocket = new Socket();
+        theSocket.bind(new InetSocketAddress(InetAddress.getLocalHost(), 0));
+        int portNumber = theSocket.getLocalPort();
+
+        // Validate that the localSocketAddress reflects the address we
+        // bound to
+        assertEquals("Local address not correct after bind",
+                new InetSocketAddress(InetAddress.getLocalHost(), portNumber),
+                theSocket.getLocalSocketAddress());
+
+        // Make sure we can now connect and that connections appear to come
+        // from the address we bound to.
+        InetSocketAddress theAddress = new InetSocketAddress(InetAddress
+                .getLocalHost(), 0);
+        ServerSocket server = new ServerSocket();
+        server.bind(theAddress);
+        int sport = server.getLocalPort();
+        InetSocketAddress boundAddress = new InetSocketAddress(InetAddress
+                .getLocalHost(), sport);
+
+        theSocket.connect(boundAddress);
+        Socket worker = server.accept();
+        assertEquals(
+                "Returned Remote address from server connected to does not match expected local address",
+                new InetSocketAddress(InetAddress.getLocalHost(), portNumber),
+                worker.getRemoteSocketAddress());
+        theSocket.close();
+        worker.close();
+        server.close();
+
+        // Validate if we pass in null that it picks an address for us and
+        // all is ok
+        theSocket = new Socket();
+        theSocket.bind(null);
+        assertNotNull("Bind with null did not work", theSocket
+                .getLocalSocketAddress());
+        theSocket.close();
+
+        // now check the error conditions
+
+        // Address that we have already bound to
+        theSocket = new Socket();
+        theAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0);
+        theSocket.bind(theAddress);
+
+        Socket theSocket2 = new Socket();
+        try {
+            theSocket2.bind(theSocket.getLocalSocketAddress());
+            fail("No exception binding to address that is not available");
+        } catch (IOException ex) {
+            // Expected
+        }
+        theSocket.close();
+        theSocket2.close();
+
+        // Unsupported SocketAddress subclass
+        theSocket = new Socket();
+        try {
+            theSocket.bind(new UnsupportedSocketAddress());
+            fail("No exception when binding using unsupported SocketAddress subclass");
+        } catch (IllegalArgumentException ex) {
+            // Expected
+        }
+        theSocket.close();
+    }
+
+    /**
+     * java.net.Socket#bind(java.net.SocketAddress)
+     */
+    public void test_bindLjava_net_SocketAddress_Proxy() throws IOException {
+        // The Proxy will not impact on the bind operation. It can be assigned
+        // with any address.
+        Proxy proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(
+                "127.0.0.1", 0));
+        Socket socket = new Socket(proxy);
+
+        InetAddress address = InetAddress.getByName("localhost");
+        socket.bind(new InetSocketAddress(address, 0));
+
+        assertEquals(address, socket.getLocalAddress());
+        assertTrue(0 != socket.getLocalPort());
+
+        socket.close();
+    }
+
+    public void test_close() throws IOException {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+
+        client.setSoLinger(false, 100);
+
+        client.close();
+        try {
+            client.getOutputStream();
+            fail("Failed to close socket");
+        } catch (IOException expected) {
+        }
+
+        server.close();
+    }
+
+    public void test_connect_unknownhost() throws Exception {
+        Socket socket = new Socket();
+        try {
+            socket.connect(new InetSocketAddress("unknownhost.invalid", 12345));
+            fail();
+        } catch (UnknownHostException expected) {
+        }
+    }
+
+    public void test_connect_unresolved() throws IOException {
+        Socket socket = new Socket();
+        InetSocketAddress unresolved = InetSocketAddress.createUnresolved("www.apache.org", 80);
+        try {
+            socket.connect(unresolved);
+            fail();
+        } catch (UnknownHostException expected) {
+        }
+        try {
+            socket.connect(unresolved, 123);
+            fail();
+        } catch (UnknownHostException expected) {
+        }
+    }
+
+    public void test_connectLjava_net_SocketAddress() throws Exception {
+
+        @SuppressWarnings("serial")
+        class UnsupportedSocketAddress extends SocketAddress {
+            public UnsupportedSocketAddress() {
+            }
+        }
+
+        Socket theSocket = new Socket();
+        try {
+            theSocket.connect(null);
+            fail("No exception for null arg");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            theSocket.connect(new UnsupportedSocketAddress());
+            fail("No exception for invalid socket address");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            theSocket.connect(new InetSocketAddress(InetAddress
+                    .getByAddress(new byte[] { 0, 0, 0, 0 }), 42));
+            fail("No exception with non-connectable address");
+        } catch (ConnectException e) {
+            // Expected
+        }
+
+        // now validate that we get a connect exception if we try to connect to
+        // an address on which nobody is listening
+        theSocket = new Socket();
+        try {
+            theSocket.connect(new InetSocketAddress(InetAddress.getLocalHost(),
+                    0));
+            fail("No exception when connecting to address nobody listening on");
+        } catch (ConnectException e) {
+            // Expected
+        }
+
+        // Now validate that we can actually connect when somebody is listening
+        ServerSocket server = new ServerSocket(0);
+        InetSocketAddress boundAddress = new InetSocketAddress(InetAddress
+                .getLocalHost(), server.getLocalPort());
+        Socket client = new Socket();
+        client.connect(boundAddress);
+
+        // validate that when a socket is connected that it answers
+        // correctly to related queries
+        assertTrue("Wrong connected status", client.isConnected());
+        assertFalse("Wrong closed status", client.isClosed());
+        assertTrue("Wrong bound status", client.isBound());
+        assertFalse("Wrong input shutdown status", client.isInputShutdown());
+        assertFalse("Wrong output shutdown status", client.isOutputShutdown());
+        assertTrue("Local port was 0", client.getLocalPort() != 0);
+
+        client.close();
+        server.close();
+
+        // Now validate that we get the right exception if we connect when we
+        // are already connected
+        server = new ServerSocket(0);
+        boundAddress = new InetSocketAddress(InetAddress.getLocalHost(), server
+                .getLocalPort());
+        client = new Socket();
+        client.connect(boundAddress);
+
+        try {
+            client.connect(boundAddress);
+            fail("No exception when we try to connect on a connected socket: ");
+        } catch (SocketException e) {
+            // Expected
+        }
+        client.close();
+        server.close();
+    }
+
+    /**
+     * Regression for Harmony-2503
+     */
+    public void test_connectLjava_net_SocketAddress_AnyAddress()
+            throws Exception {
+        connectTestImpl(ServerThread.FIRST_TIME);
+        connectTestImpl(ServerThread.SECOND_TIME);
+    }
+
+    /**
+     * java.net.Socket#connect(java.net.SocketAddress, int)
+     */
+    public void test_connectLjava_net_SocketAddressI() throws Exception {
+
+        @SuppressWarnings("serial")
+        class UnsupportedSocketAddress extends SocketAddress {
+            public UnsupportedSocketAddress() {
+            }
+        }
+
+        // Start by validating the error checks
+        Socket theSocket = new Socket();
+        try {
+            theSocket.connect(new InetSocketAddress(0), -100);
+            fail("No exception for negative timeout");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            theSocket.connect(null, 0);
+            fail("No exception for null address");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            theSocket.connect(new UnsupportedSocketAddress(), 1000);
+            fail("No exception for invalid socket address type");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        SocketAddress nonConnectableAddress = new InetSocketAddress(InetAddress
+                .getByAddress(new byte[] { 0, 0, 0, 0 }), 0);
+        try {
+            theSocket.connect(nonConnectableAddress, 1000);
+            fail("No exception when non Connectable Address passed in: ");
+        } catch (SocketException e) {
+            // Expected
+        }
+
+        // Now validate that we get a connect exception if we try to connect to
+        // an address on which nobody is listening
+        theSocket = new Socket();
+        try {
+            theSocket.connect(new InetSocketAddress(InetAddress.getLocalHost(),
+                    0), 0);
+            fail("No exception when connecting to address nobody listening on");
+        } catch (ConnectException e) {
+            // Expected
+        }
+        theSocket.close();
+
+        // Now validate that we can actually connect when somebody is listening
+        ServerSocket server = new ServerSocket(0);
+        InetSocketAddress boundAddress = new InetSocketAddress(InetAddress
+                .getLocalHost(), server.getLocalPort());
+        Socket client = new Socket();
+        client.connect(boundAddress, 0);
+
+        // Validate that when a socket is connected that it answers
+        // correctly to related queries
+        assertTrue("Wrong connected status", client.isConnected());
+        assertFalse("Wrong closed status", client.isClosed());
+        assertTrue("Wrong bound status", client.isBound());
+        assertFalse("Wrong input shutdown status", client.isInputShutdown());
+        assertFalse("Wrong output shutdown status", client.isOutputShutdown());
+        assertTrue("Local port was 0", client.getLocalPort() != 0);
+
+        client.close();
+        server.close();
+
+        // Now validate that we get a connect exception if we try to connect to
+        // an address on which nobody is listening
+        theSocket = new Socket();
+        SocketAddress nonListeningAddress = new InetSocketAddress(InetAddress
+                .getLocalHost(), 42);
+        try {
+            theSocket.connect(nonListeningAddress, 1000);
+            fail("No exception when connecting to address nobody listening on");
+        } catch (ConnectException e) {
+            // Expected
+        } catch (SocketTimeoutException e) {
+            // The other possibility is that the system timed us out.
+        }
+        theSocket.close();
+
+        // Now validate that we get the right exception if we connect when we
+        // are already connected
+        server = new ServerSocket(0);
+        boundAddress = new InetSocketAddress(InetAddress.getLocalHost(), server
+                .getLocalPort());
+        client = new Socket();
+        client.connect(boundAddress, 10000);
+
+        try {
+            client.connect(boundAddress, 10000);
+            fail("No exception when we try to connect on a connected socket: ");
+        } catch (SocketException e) {
+            // Expected
+        }
+        client.close();
+        server.close();
+    }
+
+    /**
+     * java.net.Socket#Socket()
+     */
+    public void test_Constructor() {
+        // create the socket and then validate some basic state
+        Socket s = new Socket();
+        assertFalse("new socket should not be connected", s.isConnected());
+        assertFalse("new socket should not be bound", s.isBound());
+        assertFalse("new socket should not be closed", s.isClosed());
+        assertFalse("new socket should not be in InputShutdown", s
+                .isInputShutdown());
+        assertFalse("new socket should not be in OutputShutdown", s
+                .isOutputShutdown());
+    }
+
+    /**
+     * java.net.Socket#Socket(java.lang.String, int)
+     */
+    public void test_ConstructorLjava_lang_StringI() throws IOException {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server
+                .getLocalPort());
+
+        assertEquals("Failed to create socket", server.getLocalPort(), client
+                .getPort());
+
+        // Regression for HARMONY-946
+        ServerSocket ss = new ServerSocket(0);
+        Socket s = new Socket("0.0.0.0", ss.getLocalPort());
+        ss.close();
+        s.close();
+    }
+
+    /**
+     * java.net.Socket#Socket(java.lang.String, int,
+     *java.net.InetAddress, int)
+     */
+    public void test_ConstructorLjava_lang_StringILjava_net_InetAddressI()
+            throws IOException {
+
+        ServerSocket server = new ServerSocket(0);
+        int serverPort = server.getLocalPort();
+        Socket client = new Socket(InetAddress.getLocalHost().getHostName(),
+                serverPort, InetAddress.getLocalHost(), 0);
+        assertTrue("Failed to create socket", client.getPort() == serverPort);
+        client.close();
+
+        Socket theSocket = null;
+        try {
+            theSocket = new Socket("127.0.0.1", serverPort, InetAddress
+                    .getLocalHost(), 0);
+        } catch (IOException e) {
+            // check here if InetAddress.getLocalHost() is returning the
+            // loopback address, if so that is likely the cause of the failure
+            assertFalse(
+                    "Misconfiguration - local host is the loopback address",
+                    InetAddress.getLocalHost().isLoopbackAddress());
+            throw e;
+        }
+
+        assertTrue(theSocket.isConnected());
+
+        try {
+            new Socket("127.0.0.1", serverPort, theSocket.getLocalAddress(),
+                    theSocket.getLocalPort());
+            fail("Was able to create two sockets on same port");
+        } catch (IOException e) {
+            // Expected
+        }
+
+        theSocket.close();
+        server.close();
+    }
+
+    @SuppressWarnings("deprecation")
+    public void test_ConstructorLjava_lang_StringIZ() throws IOException {
+        ServerSocket server = new ServerSocket(0);
+        int serverPort = server.getLocalPort();
+        Socket client = new Socket(InetAddress.getLocalHost().getHostAddress(),
+                serverPort, true);
+
+        assertEquals("Failed to create socket", serverPort, client.getPort());
+        client.close();
+
+        client = new Socket(InetAddress.getLocalHost().getHostName(),
+                serverPort, false);
+        client.close();
+        server.close();
+    }
+
+    /**
+     * java.net.Socket#Socket(java.net.InetAddress, int)
+     */
+    public void test_ConstructorLjava_net_InetAddressI() throws IOException {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server
+                .getLocalPort());
+
+        assertEquals("Failed to create socket", server.getLocalPort(), client
+                .getPort());
+
+        client.close();
+        server.close();
+    }
+
+    /**
+     * java.net.Socket#Socket(java.net.InetAddress, int,
+     *java.net.InetAddress, int)
+     */
+    public void test_ConstructorLjava_net_InetAddressILjava_net_InetAddressI()
+            throws IOException {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server
+                .getLocalPort(), InetAddress.getLocalHost(), 0);
+        assertNotSame("Failed to create socket", 0, client.getLocalPort());
+    }
+
+    /**
+     * java.net.Socket#Socket(java.net.InetAddress, int, boolean)
+     */
+    @SuppressWarnings("deprecation")
+    public void test_ConstructorLjava_net_InetAddressIZ() throws IOException {
+        ServerSocket server = new ServerSocket(0);
+        int serverPort = server.getLocalPort();
+
+        Socket client = new Socket(InetAddress.getLocalHost(), serverPort, true);
+        assertEquals("Failed to create socket", serverPort, client.getPort());
+
+        client = new Socket(InetAddress.getLocalHost(), serverPort, false);
+        client.close();
+    }
+
+    /**
+     * java.net.Socket#Socket(Proxy)
+     */
+    public void test_ConstructorLjava_net_Proxy_Exception() {
+
+        SocketAddress addr1 = InetSocketAddress.createUnresolved("127.0.0.1",
+                80);
+        SocketAddress addr2 = new InetSocketAddress("localhost", 80);
+
+        Proxy proxy1 = new Proxy(Proxy.Type.HTTP, addr1);
+        // IllegalArgumentException test
+        try {
+            new Socket(proxy1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        Proxy proxy2 = new Proxy(Proxy.Type.SOCKS, addr1);
+        // should not throw any exception
+        new Socket(proxy2);
+        new Socket(Proxy.NO_PROXY);
+    }
+
+    /**
+     * java.net.Socket#getChannel()
+     */
+    public void test_getChannel() {
+        assertNull(new Socket().getChannel());
+    }
+
+    /**
+     * java.net.Socket#getInetAddress()
+     */
+    public void test_getInetAddress() throws IOException {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server
+                .getLocalPort());
+
+        assertTrue("Returned incorrect InetAdrees", client.getInetAddress()
+                .equals(InetAddress.getLocalHost()));
+
+        client.close();
+        server.close();
+    }
+
+    /**
+     * java.net.Socket#getInputStream()
+     */
+    public void test_getInputStream() throws IOException {
+        // Simple fetch test
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server
+                .getLocalPort());
+        InputStream is = client.getInputStream();
+        assertNotNull("Failed to get stream", is);
+        is.close();
+        client.close();
+        server.close();
+    }
+
+    private boolean isUnix() {
+        String osName = System.getProperty("os.name");
+
+        // only comparing ASCII, so assume english locale
+        osName = (osName == null ? null : osName.toLowerCase(Locale.ENGLISH));
+
+        if (osName != null && osName.startsWith("windows")) { //$NON-NLS-1$
+            return false;
+        }
+        return true;
+    }
+
+    public void test_getKeepAlive() throws Exception {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort(), null, 0);
+
+        client.setKeepAlive(true);
+        assertTrue("getKeepAlive false when it should be true", client.getKeepAlive());
+
+        client.setKeepAlive(false);
+        assertFalse("getKeepAlive true when it should be False", client.getKeepAlive());
+    }
+
+    public void test_getLocalAddress() throws IOException {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+
+        assertTrue("Returned incorrect InetAddress", client.getLocalAddress()
+                .equals(InetAddress.getLocalHost()));
+
+        client = new Socket();
+        client.bind(new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 0));
+        assertTrue(client.getLocalAddress().isAnyLocalAddress());
+
+        client.close();
+        server.close();
+    }
+
+    /**
+     * java.net.Socket#getLocalPort()
+     */
+    public void test_getLocalPort() throws IOException {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server
+                .getLocalPort());
+
+        assertNotSame("Returned incorrect port", 0, client.getLocalPort());
+
+        client.close();
+        server.close();
+    }
+
+    public void test_getLocalSocketAddress() throws IOException {
+        // set up server connect and then validate that we get the right
+        // response for the local address
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server
+                .getLocalPort());
+        int clientPort = client.getLocalPort();
+
+        assertEquals("Returned incorrect InetSocketAddress(1):",
+                new InetSocketAddress(InetAddress.getLocalHost(), clientPort),
+                client.getLocalSocketAddress());
+        client.close();
+        server.close();
+
+        // now create a socket that is not bound and validate we get the
+        // right answer
+        client = new Socket();
+        assertNull(
+                "Returned incorrect InetSocketAddress -unbound socket- Expected null",
+                client.getLocalSocketAddress());
+
+        // now bind the socket and make sure we get the right answer
+        client.bind(new InetSocketAddress(InetAddress.getLocalHost(), 0));
+        clientPort = client.getLocalPort();
+        assertEquals("Returned incorrect InetSocketAddress(2):",
+                new InetSocketAddress(InetAddress.getLocalHost(), clientPort),
+                client.getLocalSocketAddress());
+        client.close();
+
+        // now validate the behaviour when the any address is returned
+        client = new Socket();
+        client.bind(new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 0));
+        assertTrue(((InetSocketAddress) client.getLocalSocketAddress()).getAddress().isAnyLocalAddress());
+        client.close();
+
+        // now validate the same for getLocalAddress
+        client = new Socket();
+        client.bind(new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 0));
+        assertTrue(client.getLocalAddress().isAnyLocalAddress());
+        client.close();
+    }
+
+    public void test_getOOBInline() throws Exception {
+        Socket theSocket = new Socket();
+
+        theSocket.setOOBInline(true);
+        assertTrue("expected OOBIline to be true", theSocket.getOOBInline());
+
+        theSocket.setOOBInline(false);
+        assertFalse("expected OOBIline to be false", theSocket.getOOBInline());
+
+        theSocket.setOOBInline(false);
+        assertFalse("expected OOBIline to be false", theSocket.getOOBInline());
+    }
+
+    /**
+     * java.net.Socket#getOutputStream()
+     */
+    @SuppressWarnings("deprecation")
+    public void test_getOutputStream() throws IOException {
+        // Simple fetch test
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server
+                .getLocalPort());
+        OutputStream os = client.getOutputStream();
+        assertNotNull("Failed to get stream", os);
+        os.close();
+        client.close();
+        server.close();
+
+        // Simple read/write test over the IO streams
+        final ServerSocket sinkServer = new ServerSocket(0);
+        Runnable runnable = new Runnable() {
+            public void run() {
+                try {
+                    Socket worker = sinkServer.accept();
+                    sinkServer.close();
+                    InputStream in = worker.getInputStream();
+                    in.read();
+                    in.close();
+                    worker.close();
+                } catch (IOException e) {
+                    fail();
+                }
+            }
+        };
+        Thread thread = new Thread(runnable, "Socket.getOutputStream");
+        thread.start();
+
+        Socket pingClient = new Socket(InetAddress.getLocalHost(), sinkServer
+                .getLocalPort());
+
+        // Busy wait until the client is connected.
+        int c = 0;
+        while (!pingClient.isConnected()) {
+            try {
+                Thread.sleep(200);
+            } catch (InterruptedException e) {
+            }
+            if (++c > 4) {
+                fail("thread is not alive");
+            }
+        }
+
+        // Write some data to the server
+        OutputStream out = pingClient.getOutputStream();
+        out.write(new byte[256]);
+
+        // Wait for the server to finish
+        Thread.yield();
+        c = 0;
+        while (thread.isAlive()) {
+            try {
+                Thread.sleep(200);
+            } catch (InterruptedException e) {
+            }
+            if (++c > 4) {
+                fail("read call did not exit");
+            }
+        }
+
+        // Subsequent writes should throw an exception
+        try {
+            // The output buffer may remain valid until the close completes
+            for (int i = 0; i < 400; i++) {
+                out.write(new byte[256]);
+            }
+            fail("write to closed socket did not cause exception");
+        } catch (IOException e) {
+            // Expected
+        }
+
+        out.close();
+        pingClient.close();
+        sinkServer.close();
+
+        // Regression test for HARMONY-873
+        ServerSocket ss2 = new ServerSocket(0);
+        Socket s = new Socket("127.0.0.1", ss2.getLocalPort());
+        ss2.accept();
+        s.shutdownOutput();
+        try {
+            s.getOutputStream();
+            fail("should throw SocketException");
+        } catch (SocketException e) {
+            // expected
+        }
+    }
+
+    public void test_getPort() throws IOException {
+        ServerSocket server = new ServerSocket(0);
+        int serverPort = server.getLocalPort();
+        Socket client = new Socket(InetAddress.getLocalHost(), serverPort);
+
+        assertEquals("Returned incorrect port", serverPort, client.getPort());
+
+        client.close();
+        server.close();
+    }
+
+    public void test_getReceiveBufferSize() throws Exception {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+        client.setReceiveBufferSize(130);
+
+        assertTrue("Incorrect buffer size", client.getReceiveBufferSize() >= 130);
+
+        client.close();
+        server.close();
+    }
+
+    /**
+     * java.net.Socket#getRemoteSocketAddress()
+     */
+    public void test_getRemoteSocketAddress() throws IOException {
+        // set up server connect and then validate that we get the right
+        // response for the remote address
+        ServerSocket server = new ServerSocket(0);
+        int serverPort = server.getLocalPort();
+        Socket client = new Socket(InetAddress.getLocalHost(), serverPort);
+
+        assertEquals("Returned incorrect InetSocketAddress(1):",
+                new InetSocketAddress(InetAddress.getLocalHost(), serverPort),
+                client.getRemoteSocketAddress());
+        client.close();
+
+        // now create one that is not connected and validate that we get the
+        // right answer
+        Socket theSocket = new Socket();
+        theSocket.bind(new InetSocketAddress(InetAddress.getLocalHost(), 0));
+        assertNull("Returned incorrect InetSocketAddress -unconnected socket:",
+                theSocket.getRemoteSocketAddress());
+
+        // now connect and validate we get the right answer
+        theSocket.connect(new InetSocketAddress(InetAddress.getLocalHost(),
+                serverPort));
+        assertEquals("Returned incorrect InetSocketAddress(2):",
+                new InetSocketAddress(InetAddress.getLocalHost(), serverPort),
+                theSocket.getRemoteSocketAddress());
+        theSocket.close();
+
+        server.close();
+    }
+
+    public void test_getReuseAddress() throws Exception {
+        Socket theSocket = new Socket();
+        theSocket.setReuseAddress(true);
+        assertTrue("getReuseAddress false when it should be true", theSocket.getReuseAddress());
+        theSocket.setReuseAddress(false);
+        assertFalse("getReuseAddress true when it should be False", theSocket.getReuseAddress());
+    }
+
+    public void test_getSendBufferSize() throws Exception {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+        client.setSendBufferSize(134);
+        assertTrue("Incorrect buffer size", client.getSendBufferSize() >= 134);
+        client.close();
+        server.close();
+    }
+
+    public void test_getSoLinger() throws Exception {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+        client.setSoLinger(true, 200);
+        assertEquals("Returned incorrect linger", 200, client.getSoLinger());
+        client.setSoLinger(false, 0);
+        client.close();
+        server.close();
+    }
+
+    public void test_getSoTimeout() throws Exception {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+        client.setSoTimeout(100);
+        assertEquals("Returned incorrect sotimeout", 100, client.getSoTimeout());
+        client.close();
+        server.close();
+    }
+
+    public void test_getTcpNoDelay() throws Exception {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+
+        boolean bool = !client.getTcpNoDelay();
+        client.setTcpNoDelay(bool);
+        assertTrue("Failed to get no delay setting: " + client.getTcpNoDelay(), client.getTcpNoDelay() == bool);
+
+        client.close();
+        server.close();
+    }
+
+    public void test_getTrafficClass() throws Exception {
+        /*
+         * We cannot actually check that the values are set as if a platform
+         * does not support the option then it may come back unset even
+         * though we set it so just get the value to make sure we can get it
+         */
+        int trafficClass = new Socket().getTrafficClass();
+        assertTrue(0 <= trafficClass);
+        assertTrue(trafficClass <= 255);
+    }
+
+    /**
+     * java.net.Socket#isBound()
+     */
+    public void test_isBound() throws IOException {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server
+                .getLocalPort());
+        Socket worker = server.accept();
+
+        assertTrue("Socket indicated  not bound when it should be (1)", client
+                .isBound());
+        worker.close();
+        client.close();
+        server.close();
+
+        client = new Socket();
+        assertFalse("Socket indicated bound when it was not (2)", client
+                .isBound());
+
+        server = new ServerSocket();
+        server.bind(new InetSocketAddress(InetAddress.getLocalHost(), 0));
+        InetSocketAddress boundAddress = new InetSocketAddress(server
+                .getInetAddress(), server.getLocalPort());
+        client.connect(boundAddress);
+        worker = server.accept();
+        assertTrue("Socket indicated not bound when it should be (2)", client
+                .isBound());
+        worker.close();
+        client.close();
+        server.close();
+
+        // now test when we bind explicitly
+        InetSocketAddress theLocalAddress = new InetSocketAddress(InetAddress
+                .getLocalHost(), 0);
+        client = new Socket();
+        assertFalse("Socket indicated bound when it was not (3)", client
+                .isBound());
+        client.bind(theLocalAddress);
+        assertTrue("Socket indicated not bound when it should be (3a)", client
+                .isBound());
+        client.close();
+        assertTrue("Socket indicated not bound when it should be (3b)", client
+                .isBound());
+    }
+
+    /**
+     * java.net.Socket#isClosed()
+     */
+    public void test_isClosed() throws IOException {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server
+                .getLocalPort());
+        Socket worker = server.accept();
+
+        // validate isClosed returns expected values
+        assertFalse("Socket should indicate it is not closed(1):", client
+                .isClosed());
+        client.close();
+        assertTrue("Socket should indicate it is closed(1):", client.isClosed());
+
+        // validate that isClosed works ok for sockets returned from
+        // ServerSocket.accept()
+        assertFalse("Accepted Socket should indicate it is not closed:", worker
+                .isClosed());
+        worker.close();
+        assertTrue("Accepted Socket should indicate it is closed:", worker
+                .isClosed());
+
+        // and finally for the server socket
+        assertFalse("Server Socket should indicate it is not closed:", server
+                .isClosed());
+        server.close();
+        assertTrue("Server Socket should indicate it is closed:", server
+                .isClosed());
+    }
+
+    /**
+     * java.net.Socket#isConnected()
+     */
+    public void test_isConnected() throws IOException {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server
+                .getLocalPort());
+        Socket worker = server.accept();
+
+        assertTrue("Socket indicated  not connected when it should be", client
+                .isConnected());
+        client.close();
+        worker.close();
+        server.close();
+
+        // now do it with the new constructors and revalidate
+        InetSocketAddress theAddress = new InetSocketAddress(InetAddress
+                .getLocalHost(), 0);
+        client = new Socket();
+        assertFalse("Socket indicated connected when it was not", client
+                .isConnected());
+
+        server = new ServerSocket();
+        server.bind(theAddress);
+        InetSocketAddress boundAddress = new InetSocketAddress(server
+                .getInetAddress(), server.getLocalPort());
+        client.connect(boundAddress);
+        worker = server.accept();
+        assertTrue("Socket indicated  not connected when it should be", client
+                .isConnected());
+        client.close();
+        worker.close();
+        server.close();
+    }
+
+    /**
+     * java.net.Socket#isInputShutdown()
+     */
+    public void test_isInputShutdown() throws IOException {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server
+                .getLocalPort());
+
+        Socket worker = server.accept();
+        InputStream theInput = client.getInputStream();
+        OutputStream theOutput = worker.getOutputStream();
+
+        // make sure we get the right answer with newly connected socket
+        assertFalse("Socket indicated input shutdown when it should not have",
+                client.isInputShutdown());
+
+        // shutdown the output
+        client.shutdownInput();
+
+        // make sure we get the right answer once it is shut down
+        assertTrue(
+                "Socket indicated input was NOT shutdown when it should have been",
+                client.isInputShutdown());
+
+        client.close();
+        worker.close();
+        server.close();
+
+        // make sure we get the right answer for closed sockets
+        assertFalse(
+                "Socket indicated input was shutdown when socket was closed",
+                worker.isInputShutdown());
+
+        theInput.close();
+        theOutput.close();
+    }
+
+    /**
+     * java.net.Socket#isOutputShutdown()
+     */
+    public void test_isOutputShutdown() throws IOException {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server
+                .getLocalPort());
+
+        Socket worker = server.accept();
+        InputStream theInput = client.getInputStream();
+        OutputStream theOutput = worker.getOutputStream();
+
+        // make sure we get the right answer with newly connected socket
+        assertFalse("Socket indicated output shutdown when it should not have",
+                worker.isOutputShutdown());
+
+        // shutdown the output
+        worker.shutdownOutput();
+
+        // make sure we get the right answer once it is shut down
+        assertTrue(
+                "Socket indicated output was NOT shutdown when it should have been",
+                worker.isOutputShutdown());
+
+        client.close();
+        worker.close();
+        server.close();
+
+        // make sure we get the right answer for closed sockets
+        assertFalse(
+                "Socket indicated output was output shutdown when the socket was closed",
+                client.isOutputShutdown());
+
+        theInput.close();
+        theOutput.close();
+    }
+
+    /**
+     * java.net.Socket#sendUrgentData(int)
+     */
+    public void test_sendUrgentDataI() throws Exception {
+        /*
+         * Some platforms may not support urgent data in this case we will not
+         * run these tests. For now run on all platforms until we find those
+         * that do not support urgent data
+         */
+        String platform = System.getProperty("os.name");
+        if (platform.equals("Dummy")) {
+            return;
+        }
+
+        /*
+         * Test 1: Validate that when OOBInline is false that any urgent data is
+         * silently ignored
+         */
+        InetAddress localHost = InetAddress.getLocalHost();
+        ServerSocket server = new ServerSocket(0, 5, localHost);
+        SocketAddress serverAddress = new InetSocketAddress(localHost, server
+                .getLocalPort());
+
+        Socket client = new Socket();
+        client.setOOBInline(false);
+
+        client.connect(serverAddress);
+        Socket worker = server.accept();
+        worker.setTcpNoDelay(true);
+        OutputStream theOutput = worker.getOutputStream();
+
+        // Send the regular data
+        byte[] sendBytes = new String("Test").getBytes();
+        theOutput.write(sendBytes);
+        theOutput.flush();
+
+        // Send the urgent data byte which should not be received
+        worker.sendUrgentData("UrgentData".getBytes()[0]);
+        theOutput.write(sendBytes);
+        worker.shutdownOutput();
+        worker.close();
+
+        // Try to read the bytes back
+        int totalBytesRead = 0;
+        byte[] myBytes = new byte[100];
+        InputStream theInput = client.getInputStream();
+        while (true) {
+            int bytesRead = theInput.read(myBytes, totalBytesRead,
+                    myBytes.length - totalBytesRead);
+            if (bytesRead == -1) {
+                break;
+            }
+            totalBytesRead = totalBytesRead + bytesRead;
+        }
+
+        client.close();
+        server.close();
+
+        byte[] expectBytes = new byte[2 * sendBytes.length];
+        System.arraycopy(sendBytes, 0, expectBytes, 0, sendBytes.length);
+        System.arraycopy(sendBytes, 0, expectBytes, sendBytes.length,
+                sendBytes.length);
+
+        byte[] resultBytes = new byte[totalBytesRead];
+        System.arraycopy(myBytes, 0, resultBytes, 0, totalBytesRead);
+
+        assertTrue("Urgent data was received", Arrays.equals(expectBytes,
+                resultBytes));
+
+        /*
+         * Test 2: Now validate that urgent data is received as expected. Expect
+         * that it should be between the two writes.
+         */
+        server = new ServerSocket(0, 5, localHost);
+        serverAddress = new InetSocketAddress(localHost, server.getLocalPort());
+
+        client = new Socket();
+        client.setOOBInline(true);
+
+        client.connect(serverAddress);
+        worker = server.accept();
+        worker.setTcpNoDelay(true);
+        theOutput = worker.getOutputStream();
+
+        // Send the regular data
+        sendBytes = new String("Test - Urgent Data").getBytes();
+        theOutput.write(sendBytes);
+
+        // Send the urgent data (one byte) which should be received
+        client.setOOBInline(true);
+        byte urgentByte = "UrgentData".getBytes()[0];
+        worker.sendUrgentData(urgentByte);
+
+        // Send more data, the urgent byte must stay in position
+        theOutput.write(sendBytes);
+        worker.shutdownOutput();
+        worker.close();
+
+        // Try to read the bytes back
+        totalBytesRead = 0;
+        myBytes = new byte[100];
+        theInput = client.getInputStream();
+        while (true) {
+            int bytesRead = theInput.read(myBytes, totalBytesRead,
+                    myBytes.length - totalBytesRead);
+            if (bytesRead == -1) {
+                break;
+            }
+            totalBytesRead = totalBytesRead + bytesRead;
+        }
+
+        client.close();
+        server.close();
+
+        expectBytes = new byte[2 * sendBytes.length + 1];
+        System.arraycopy(sendBytes, 0, expectBytes, 0, sendBytes.length);
+        expectBytes[sendBytes.length] = urgentByte;
+        System.arraycopy(sendBytes, 0, expectBytes, sendBytes.length + 1,
+                sendBytes.length);
+
+        resultBytes = new byte[totalBytesRead];
+        System.arraycopy(myBytes, 0, resultBytes, 0, totalBytesRead);
+
+        assertTrue("Urgent data was not received with one urgent byte", Arrays
+                .equals(expectBytes, resultBytes));
+
+        /*
+         * Test 3: Now validate that urgent data is received as expected. Expect
+         * that it should be between the two writes.
+         */
+        server = new ServerSocket(0, 5, localHost);
+        serverAddress = new InetSocketAddress(localHost, server.getLocalPort());
+
+        client = new Socket();
+        client.setOOBInline(true);
+
+        client.connect(serverAddress);
+        worker = server.accept();
+        worker.setTcpNoDelay(true);
+        theOutput = worker.getOutputStream();
+
+        // Send the regular data
+        sendBytes = new String("Test - Urgent Data").getBytes();
+        theOutput.write(sendBytes);
+
+        // Send the urgent data (one byte) which should be received
+        client.setOOBInline(true);
+        byte urgentByte1 = "UrgentData".getBytes()[0];
+        byte urgentByte2 = "UrgentData".getBytes()[1];
+        worker.sendUrgentData(urgentByte1);
+        worker.sendUrgentData(urgentByte2);
+
+        // Send more data, the urgent byte must stay in position
+        theOutput.write(sendBytes);
+        worker.shutdownOutput();
+        worker.close();
+
+        // Try to read the bytes back
+        totalBytesRead = 0;
+        myBytes = new byte[100];
+        theInput = client.getInputStream();
+        while (true) {
+            int bytesRead = theInput.read(myBytes, totalBytesRead,
+                    myBytes.length - totalBytesRead);
+            if (bytesRead == -1) {
+                break;
+            }
+            totalBytesRead = totalBytesRead + bytesRead;
+        }
+
+        client.close();
+        server.close();
+
+        expectBytes = new byte[2 * sendBytes.length + 2];
+        System.arraycopy(sendBytes, 0, expectBytes, 0, sendBytes.length);
+        expectBytes[sendBytes.length] = urgentByte1;
+        expectBytes[sendBytes.length + 1] = urgentByte2;
+        System.arraycopy(sendBytes, 0, expectBytes, sendBytes.length + 2,
+                sendBytes.length);
+
+        resultBytes = new byte[totalBytesRead];
+        System.arraycopy(myBytes, 0, resultBytes, 0, totalBytesRead);
+
+        assertTrue("Urgent data was not received with two urgent bytes", Arrays
+                .equals(expectBytes, resultBytes));
+
+        /*
+         * Test 4: Now test the case where there is only urgent data.
+         */
+        server = new ServerSocket(0, 5, localHost);
+        serverAddress = new InetSocketAddress(localHost, server.getLocalPort());
+
+        client = new Socket();
+        client.setOOBInline(true);
+
+        client.connect(serverAddress);
+        worker = server.accept();
+        worker.setTcpNoDelay(true);
+
+        // Send the urgent data (one byte) which should be received
+        client.setOOBInline(true);
+        urgentByte = "UrgentData".getBytes()[0];
+        worker.sendUrgentData(urgentByte);
+        worker.close();
+
+        // Try to read the bytes back
+        theInput = client.getInputStream();
+        int byteRead = theInput.read();
+
+        client.close();
+        server.close();
+
+        assertEquals("Sole urgent data was not received",
+                (int) (urgentByte & 0xff), byteRead);
+    }
+
+    /**
+     * java.net.Socket#setKeepAlive(boolean)
+     */
+    public void test_setKeepAliveZ() throws IOException {
+
+        class TestSocket extends Socket {
+            public TestSocket(SocketImpl impl) throws SocketException {
+                super(impl);
+            }
+        }
+
+        // There is not really a good test for this as it is there to detect
+        // crashed machines. Just make sure we can set it
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+
+        client.setKeepAlive(true);
+        client.setKeepAlive(false);
+        client.close();
+        server.close();
+
+        // Regression test for HARMONY-1136
+        new TestSocket((SocketImpl) null).setKeepAlive(true);
+    }
+
+    public void test_setOOBInlineZ() throws Exception {
+        Socket theSocket = new Socket();
+        theSocket.setOOBInline(true);
+        assertTrue("expected OOBIline to be true", theSocket.getOOBInline());
+    }
+
+    public void test_setPerformancePreference_Int_Int_Int() throws IOException {
+        Socket theSocket = new Socket();
+        theSocket.setPerformancePreferences(1, 1, 1);
+    }
+
+    public void test_setReceiveBufferSizeI() throws Exception {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+
+        client.setReceiveBufferSize(130);
+        assertTrue("Incorrect buffer size", client.getReceiveBufferSize() >= 130);
+
+        client.close();
+        server.close();
+    }
+
+    public void test_setReuseAddressZ() throws Exception {
+        Socket theSocket = new Socket();
+        theSocket.setReuseAddress(false);
+        // Bind to any available port on the given address
+        theSocket.bind(new InetSocketAddress(InetAddress.getLocalHost(), 0));
+        InetSocketAddress localAddress1 = new InetSocketAddress(theSocket.getLocalAddress(), theSocket.getLocalPort());
+
+        Socket theSocket2 = new Socket();
+        theSocket2.setReuseAddress(false);
+
+        /*
+         * Try to invoke a bind while the port is busy (TIME_WAIT). Note
+         * that we may not succeed, which will cause the test to pass
+         * without testing the reuseaddr behavior.
+         */
+        theSocket.close();
+        theSocket2.bind(localAddress1);
+
+        theSocket2.close();
+    }
+
+    public void test_setSendBufferSizeI() throws Exception {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+        client.setSendBufferSize(134);
+        assertTrue("Incorrect buffer size", client.getSendBufferSize() >= 134);
+        client.close();
+        server.close();
+    }
+
+    public void test_setSocketImplFactoryLjava_net_SocketImplFactory() {
+        // Cannot test as setting will cause the factory to be changed for
+        // all subsequent sockets
+    }
+
+    public void test_setSoLingerZI() throws IOException {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+        client.setSoLinger(true, 500);
+        assertEquals("Set incorrect linger", 500, client.getSoLinger());
+        client.setSoLinger(false, 0);
+        client.close();
+        server.close();
+    }
+
+    public void test_setSoTimeoutI() throws Exception {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+        client.setSoTimeout(100);
+        assertEquals("Set incorrect sotimeout", 100, client.getSoTimeout());
+        client.close();
+        server.close();
+    }
+
+    public void test_setTcpNoDelayZ() throws Exception {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+
+        boolean bool;
+        client.setTcpNoDelay(bool = !client.getTcpNoDelay());
+        assertTrue("Failed to set no delay setting: " + client.getTcpNoDelay(), client.getTcpNoDelay() == bool);
+
+        client.close();
+        server.close();
+    }
+
+    public void test_setTrafficClassI() throws Exception {
+        int IPTOS_LOWCOST = 0x2;
+        int IPTOS_RELIABILTY = 0x4;
+        int IPTOS_THROUGHPUT = 0x8;
+        int IPTOS_LOWDELAY = 0x10;
+
+        Socket theSocket = new Socket();
+
+        // validate that value set must be between 0 and 255
+        try {
+            theSocket.setTrafficClass(256);
+            fail("No exception was thrown when traffic class set to 256");
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            theSocket.setTrafficClass(-1);
+            fail("No exception was thrown when traffic class set to -1");
+        } catch (IllegalArgumentException expected) {
+        }
+
+        // now validate that we can set it to some good values
+        theSocket.setTrafficClass(IPTOS_LOWCOST);
+        theSocket.setTrafficClass(IPTOS_RELIABILTY);
+        theSocket.setTrafficClass(IPTOS_THROUGHPUT);
+        theSocket.setTrafficClass(IPTOS_LOWDELAY);
+    }
+
+    @SuppressWarnings("deprecation")
+    public void test_shutdownInput() throws IOException {
+        ServerSocket server = new ServerSocket(0);
+        int port = server.getLocalPort();
+        Socket client = new Socket(InetAddress.getLocalHost(), port);
+
+        Socket worker = server.accept();
+        worker.setTcpNoDelay(true);
+
+        InputStream theInput = client.getInputStream();
+        OutputStream theOutput = worker.getOutputStream();
+
+        // shutdown the input
+        client.shutdownInput();
+
+        // send the regular data
+        String sendString = new String("Test");
+        theOutput.write(sendString.getBytes());
+        theOutput.flush();
+
+        // RI fails here. It is a RI bug not to return 0 to indicate EOF
+        assertEquals(0, theInput.available());
+
+        client.close();
+        server.close();
+
+        // Regression test for HARMONY-2944
+        // Port 0 is not allowed to be used in connect() on some platforms,
+        // Since server has been closed here, so the port is free now
+        Socket s = new Socket("0.0.0.0", port, false);
+        s.shutdownInput();
+        try {
+            s.shutdownInput();
+            fail("should throw SocketException");
+        } catch (SocketException se) {
+            // Expected
+        }
+        s.close();
+    }
+
+    /**
+     * java.net.Socket#shutdownOutput()
+     */
+    @SuppressWarnings("deprecation")
+    public void test_shutdownOutput() throws IOException {
+        ServerSocket server = new ServerSocket(0);
+        int port = server.getLocalPort();
+        Socket client = new Socket(InetAddress.getLocalHost(), port);
+
+        Socket worker = server.accept();
+        OutputStream theOutput = worker.getOutputStream();
+
+        // shutdown the output
+        worker.shutdownOutput();
+
+        // send the regular data
+        String sendString = new String("Test");
+        try {
+            theOutput.write(sendString.getBytes());
+            theOutput.flush();
+            fail("No exception when writing on socket with output shutdown");
+        } catch (IOException e) {
+            // Expected
+        }
+
+        client.close();
+        server.close();
+
+        // Regression test for HARMONY-2944
+        // Port 0 is not allowed to be used in connect() on some platforms,
+        // Since server has been closed here, so the port is free now
+        Socket s = new Socket("0.0.0.0", port, false);
+        s.shutdownOutput();
+        try {
+            s.shutdownOutput();
+            fail("should throw SocketException");
+        } catch (SocketException se) {
+            // Expected
+        }
+        s.close();
+    }
+
+    public void test_toString() throws IOException {
+        ServerSocket server = new ServerSocket(0);
+        Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+        // RI has "addr" and "localport" instead of "address" and "localPort".
+        String expected = "Socket[address=" + InetAddress.getLocalHost()
+                + ",port=" + client.getPort() + ",localPort="
+                + client.getLocalPort() + "]";
+        assertEquals(expected, client.toString());
+        client.close();
+        server.close();
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/SocketTimeoutExceptionTest.java b/luni/src/test/java/tests/api/java/net/SocketTimeoutExceptionTest.java
new file mode 100644
index 0000000..76193e2
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/SocketTimeoutExceptionTest.java
@@ -0,0 +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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES 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.SocketTimeoutException;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class SocketTimeoutExceptionTest extends junit.framework.TestCase {
+
+    /**
+     * {@link java.net.SocketTimeoutException#SocketTimeoutException()}
+     */
+    public void test_Constructor() {
+        SocketTimeoutException e = new SocketTimeoutException();
+        assertNull(e.getMessage());
+        assertNull(e.getLocalizedMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * {@link java.net.SocketTimeoutException#SocketTimeoutException(String)}
+     */
+    public void test_ConstructorLjava_lang_String() {
+        SocketTimeoutException e = new SocketTimeoutException("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+        SerializationTest.verifySelf(new SocketTimeoutException());
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+        SerializationTest.verifyGolden(this, new SocketTimeoutException());
+    }
+
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/net/TestServerSocketInit.java b/luni/src/test/java/tests/api/java/net/TestServerSocketInit.java
new file mode 100644
index 0000000..5727d7e
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/TestServerSocketInit.java
@@ -0,0 +1,30 @@
+/*
+ *  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.io.IOException;
+import java.net.ServerSocket;
+
+public class TestServerSocketInit {
+
+    public static void main(String[] args) throws IOException {
+        ServerSocket serverSocket = new ServerSocket();
+        serverSocket.setReuseAddress(true);
+        serverSocket.close();
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/URISyntaxExceptionTest.java b/luni/src/test/java/tests/api/java/net/URISyntaxExceptionTest.java
new file mode 100644
index 0000000..9a06d06
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/URISyntaxExceptionTest.java
@@ -0,0 +1,115 @@
+/* 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.URISyntaxException;
+import java.util.Locale;
+
+public class URISyntaxExceptionTest extends junit.framework.TestCase {
+
+    /**
+     * java.net.URISyntaxException#URISyntaxException(java.lang.String,
+     *java.lang.String, int)
+     */
+    public void test_ConstructorLjava_lang_StringLjava_lang_StringI() {
+        try {
+            new URISyntaxException(null, "problem", 2);
+            fail("Expected NullPointerException");
+        } catch (NullPointerException npe) {
+            // Expected
+        }
+
+        try {
+            new URISyntaxException("str", null, 2);
+            fail("Expected NullPointerException");
+        } catch (NullPointerException npe) {
+            // Expected
+        }
+
+        try {
+            new URISyntaxException("str", "problem", -2);
+            fail("Expected IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // Expected
+        }
+
+        URISyntaxException e = new URISyntaxException("str", "problem", 2);
+        assertEquals("returned incorrect reason", "problem", e.getReason());
+        assertEquals("returned incorrect input", "str", e.getInput());
+        assertEquals("returned incorrect index", 2, e.getIndex());
+    }
+
+    /**
+     * java.net.URISyntaxException#URISyntaxException(java.lang.String,
+     *java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_StringLjava_lang_String() {
+        try {
+            new URISyntaxException(null, "problem");
+            fail("Expected NullPointerException");
+        } catch (NullPointerException npe) {
+            // Expected
+        }
+
+        try {
+            new URISyntaxException("str", null);
+            fail("Expected NullPointerException");
+        } catch (NullPointerException npe) {
+            // Expected
+        }
+
+        URISyntaxException e = new URISyntaxException("str", "problem");
+        assertEquals("returned incorrect reason", "problem", e.getReason());
+        assertEquals("returned incorrect input", "str", e.getInput());
+        assertEquals("returned incorrect index", -1, e.getIndex());
+    }
+
+    /**
+     * java.net.URISyntaxException#getIndex()
+     */
+    public void test_getIndex() {
+        // see constructor tests
+    }
+
+    /**
+     * java.net.URISyntaxException#getReason()
+     */
+    public void test_getReason() {
+        // see constructor tests
+    }
+
+    /**
+     * java.net.URISyntaxException#getInput()
+     */
+    public void test_getInput() {
+        // see constructor tests
+    }
+
+    /**
+     * java.net.URISyntaxException#getMessage()
+     */
+    public void test_getMessage() {
+        Locale.setDefault(Locale.US);
+        URISyntaxException e = new URISyntaxException("str", "problem", 3);
+        assertEquals("Returned incorrect message", "problem at index 3: str", e
+                .getMessage());
+
+        e = new URISyntaxException("str", "problem");
+        assertEquals("Returned incorrect message", "problem: str", e
+                .getMessage());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/URITest.java b/luni/src/test/java/tests/api/java/net/URITest.java
new file mode 100644
index 0000000..51ae52f
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/URITest.java
@@ -0,0 +1,1841 @@
+/*
+ *  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.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import junit.framework.TestCase;
+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;
+    }
+
+    /**
+     * java.net.URI#URI(java.lang.String)
+     */
+    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());
+        }
+
+        // Regression test for HARMONY-25
+        // 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) {
+            // Expected
+        }
+
+        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) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.net.URI#URI(java.lang.String)
+     */
+    public void test_URI_String() {
+        try {
+            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());
+        }
+    }
+
+    /**
+     * 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
+        }
+    }
+
+    /**
+     * 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
+     * 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
+     * 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
+     * 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
+        }
+    }
+
+    /**
+     * 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
+     * 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);
+    }
+
+    /**
+     * 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
+        }
+    }
+
+    /**
+     * 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
+     * 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));
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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
+        }
+    }
+
+    /**
+     * 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]);
+            }
+        }
+    }
+
+    /**
+     * 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]);
+            }
+        }
+    }
+
+    /**
+     * 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]);
+            }
+        }
+    }
+
+    /**
+     * 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]);
+        }
+    }
+
+    /**
+     * 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
+        }
+    }
+
+    /**
+     * 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]);
+            }
+        }
+    }
+
+    /**
+     * 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]);
+            }
+        }
+    }
+
+    /**
+     * 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]);
+            }
+        }
+    }
+
+    /**
+     * 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]);
+            }
+        }
+    }
+
+    /**
+     * 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]);
+            }
+        }
+
+    }
+
+    /**
+     * 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]);
+            }
+        }
+    }
+
+    /**
+     * 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]);
+            }
+        }
+    }
+
+    /**
+     * 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]);
+            }
+        }
+    }
+
+    /**
+     * 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]);
+            }
+        }
+
+    }
+
+    /**
+     * 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]);
+            }
+        }
+    }
+
+    /**
+     * 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());
+        }
+
+    }
+
+    /**
+     * 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);
+        }
+    }
+
+    /**
+     * 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);
+        }
+    }
+
+    /**
+     * java.net.URI#normalize()
+     */
+    public void test_normalize() throws Exception {
+        // normal
+        testNormalize("/", "/");
+        testNormalize("/a", "/a");
+        testNormalize("/a/b", "/a/b");
+        testNormalize("/a/b/c", "/a/b/c");
+        // single, '.'
+        testNormalize("/.", "/");
+        testNormalize("/./", "/");
+        testNormalize("/./.", "/");
+        testNormalize("/././", "/");
+        testNormalize("/./a", "/a");
+        testNormalize("/./a/", "/a/");
+        testNormalize("/././a", "/a");
+        testNormalize("/././a/", "/a/");
+        testNormalize("/a/.", "/a/");
+        testNormalize("/a/./", "/a/");
+        testNormalize("/a/./.", "/a/");
+        testNormalize("/a/./b", "/a/b");
+        // double, '..'
+        testNormalize("/a/..", "/");
+        testNormalize("/a/../", "/");
+        testNormalize("/a/../b", "/b");
+        testNormalize("/a/../b/..", "/");
+        testNormalize("/a/../b/../", "/");
+        testNormalize("/a/../b/../c", "/c");
+        testNormalize("/..", "/..");
+        testNormalize("/../", "/../");
+        testNormalize("/../..", "/../..");
+        testNormalize("/../../", "/../../");
+        testNormalize("/../a", "/../a");
+        testNormalize("/../a/", "/../a/");
+        testNormalize("/../../a", "/../../a");
+        testNormalize("/../../a/", "/../../a/");
+        testNormalize("/a/b/../../c", "/c");
+        testNormalize("/a/b/../..", "/");
+        testNormalize("/a/b/../../", "/");
+        testNormalize("/a/b/../../c", "/c");
+        testNormalize("/a/b/c/../../../d", "/d");
+        testNormalize("/a/b/..", "/a/");
+        testNormalize("/a/b/../", "/a/");
+        testNormalize("/a/b/../c", "/a/c");
+        // miscellaneous
+        testNormalize("/a/b/.././../../c/./d/../e", "/../c/e");
+        testNormalize("/a/../../.c././../././c/d/../g/..", "/../c/");
+        // '.' in the middle of segments
+        testNormalize("/a./b", "/a./b");
+        testNormalize("/.a/b", "/.a/b");
+        testNormalize("/a.b/c", "/a.b/c");
+        testNormalize("/a/b../c", "/a/b../c");
+        testNormalize("/a/..b/c", "/a/..b/c");
+        testNormalize("/a/b..c/d", "/a/b..c/d");
+        // no leading slash, miscellaneous
+        testNormalize("", "");
+        testNormalize("a", "a");
+        testNormalize("a/b", "a/b");
+        testNormalize("a/b/c", "a/b/c");
+        testNormalize("../", "../");
+        testNormalize(".", "");
+        testNormalize("..", "..");
+        testNormalize("../g", "../g");
+        testNormalize("g/a/../../b/c/./g", "b/c/g");
+        testNormalize("a/b/.././../../c/./d/../e", "../c/e");
+        testNormalize("a/../../.c././../././c/d/../g/..", "../c/");
+    }
+
+    private void testNormalize(String original, String expected) throws URISyntaxException {
+        assertEquals(expected, new URI(original).normalize().toString());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * java.net.URI#relativize(java.net.URI)
+     */
+    public void test_relativizeLjava_net_URI() throws URISyntaxException {
+        // rel = opaque
+        testRelativize("http://www.google.com/dir1/dir2", "mailto:test", "mailto:test");
+        // base = opaque
+        testRelativize("mailto:test", "http://www.google.com", "http://www.google.com");
+        // different authority
+        testRelativize("http://www.eclipse.org/dir1", "http://www.google.com/dir1/dir2",
+                "http://www.google.com/dir1/dir2");
+        // different scheme
+        testRelativize("http://www.google.com", "ftp://www.google.com", "ftp://www.google.com");
+        testRelativize("http://www.google.com/dir1/dir2/",
+                "http://www.google.com/dir3/dir4/file.txt",
+                "http://www.google.com/dir3/dir4/file.txt");
+        testRelativize("http://www.google.com/dir1/", "http://www.google.com/dir1/dir2/file.txt",
+                "dir2/file.txt");
+        testRelativize("./dir1/", "./dir1/hi", "hi");
+        testRelativize("/dir1/./dir2", "/dir1/./dir2/hi", "dir2/hi");
+        testRelativize("/dir1/dir2/..", "/dir1/dir2/../hi", "hi");
+        testRelativize("/dir1/dir2/..", "/dir1/dir2/hi", "dir2/hi");
+        testRelativize("/dir1/dir2/", "/dir1/dir3/../dir2/text", "text");
+        testRelativize("//www.google.com", "//www.google.com/dir1/file", "/dir1/file");
+        testRelativize("/dir1", "/dir1/hi", "dir1/hi");
+        testRelativize("/dir1/", "/dir1/hi", "hi");
+
+        URI a = new URI("http://host/dir");
+        URI b = new URI("http://host/dir/file?query");
+        assertEquals("Assert 0: URI relativized incorrectly,",
+                new URI("dir/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));
+
+        // Both URIs with empty hosts
+        b = new URI("file:///~/second");
+        assertEquals("Assert 3: URI relativized incorrectly,", new URI("second"), a.relativize(b));
+        assertEquals("Assert 4: URI relativized incorrectly,", new URI("first"), b.relativize(a));
+    }
+
+    private void testRelativize(String base, String target, String expected)
+            throws URISyntaxException {
+        assertEquals(expected, new URI(base).relativize(new URI(target)).toString());
+    }
+
+    // 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("test/location", relative.getSchemeSpecificPart());
+        assertNull(relative.getScheme());
+    }
+
+    /**
+     * 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("dir/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:///~/thesaurus");
+        assertEquals("relativized incorrectly,", new URI("thesaurus"), a.relativize(b));
+        assertEquals("relativized incorrectly,", new URI("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");
+        assertEquals(new URI("ws/p1"), one.relativize(two));
+
+        one = new URI("file:/C:/test/ws/");
+        assertEquals(new URI("p1"), one.relativize(two));
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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);
+            }
+        }
+    }
+
+    /**
+     * 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]));
+        }
+    }
+
+    /**
+     * 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]));
+        }
+    }
+
+    /**
+     * 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
+            }
+        }
+    }
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+        URI uri = new URI("http://harmony.apache.org/");
+
+        SerializationTest.verifySelf(uri);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/URLDecoderTest.java b/luni/src/test/java/tests/api/java/net/URLDecoderTest.java
new file mode 100644
index 0000000..d0489d5
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/URLDecoderTest.java
@@ -0,0 +1,64 @@
+/*
+ *  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.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+
+import junit.framework.TestCase;
+import tests.support.Support_Configuration;
+
+public class URLDecoderTest extends TestCase {
+
+    /**
+     * java.net.URLDecoder#URLDecoder()
+     */
+    public void test_Constructor() throws Exception {
+        URLDecoder ud = new URLDecoder();
+        assertNotNull("Constructor failed.", ud);
+    }
+
+    /**
+     * java.net.URLDecoder#decode(java.lang.String)
+     */
+    public void test_decodeLjava_lang_String() throws Exception {
+        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));
+    }
+
+    /**
+     * java.net.URLDecoder#decode(java.lang.String, java.lang.String)
+     */
+    public void test_decodeLjava_lang_String_Ljava_lang_String() {
+        // Regression for HARMONY-467
+        try {
+            URLDecoder.decode("", "");
+            fail("UnsupportedEncodingException expected");
+        } catch (UnsupportedEncodingException e) {
+            // Expected
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/URLTest.java b/luni/src/test/java/tests/api/java/net/URLTest.java
new file mode 100644
index 0000000..71d315c
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/URLTest.java
@@ -0,0 +1,1285 @@
+/*
+ *  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 junit.framework.TestCase;
+import tests.support.resource.Support_Resources;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.SocketAddress;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+import java.util.ArrayList;
+import java.util.List;
+
+public class URLTest extends TestCase {
+
+    public static class MyHandler extends URLStreamHandler {
+        protected URLConnection openConnection(URL u)
+                throws IOException {
+            return null;
+        }
+    }
+
+    URL u;
+
+    URL u1;
+
+    URL u2;
+
+    URL u3;
+
+    URL u4;
+
+    URL u5;
+
+    URL u6;
+
+    boolean caught = false;
+
+    static boolean isSelectCalled;
+
+    /**
+     * java.net.URL#URL(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() throws IOException {
+        // Tests for multiple URL instantiation basic parsing test
+        u = new URL(
+                "http://www.yahoo1.com:8080/dir1/dir2/test.cgi?point1.html#anchor1");
+        assertEquals("u returns a wrong protocol", "http", u.getProtocol());
+        assertEquals("u returns a wrong host", "www.yahoo1.com", u.getHost());
+        assertEquals("u returns a wrong port", 8080, u.getPort());
+        assertEquals("u returns a wrong file",
+                "/dir1/dir2/test.cgi?point1.html", u.getFile());
+        assertEquals("u returns a wrong anchor", "anchor1", u.getRef());
+
+        // test for no file
+        u1 = new URL("http://www.yahoo2.com:9999");
+        assertEquals("u1 returns a wrong protocol", "http", u1.getProtocol());
+        assertEquals("u1 returns a wrong host", "www.yahoo2.com", u1.getHost());
+        assertEquals("u1 returns a wrong port", 9999, u1.getPort());
+        assertTrue("u1 returns a wrong file", u1.getFile().equals(""));
+        assertNull("u1 returns a wrong anchor", u1.getRef());
+
+        // test for no port
+        u2 = new URL(
+                "http://www.yahoo3.com/dir1/dir2/test.cgi?point1.html#anchor1");
+        assertEquals("u2 returns a wrong protocol", "http", u2.getProtocol());
+        assertEquals("u2 returns a wrong host", "www.yahoo3.com", u2.getHost());
+        assertEquals("u2 returns a wrong port", -1, u2.getPort());
+        assertEquals("u2 returns a wrong file",
+                "/dir1/dir2/test.cgi?point1.html", u2.getFile());
+        assertEquals("u2 returns a wrong anchor", "anchor1", u2.getRef());
+
+        // test for no port
+        URL u2a = new URL("file://www.yahoo3.com/dir1/dir2/test.cgi#anchor1");
+        assertEquals("u2a returns a wrong protocol", "file", u2a.getProtocol());
+        assertEquals("u2a returns a wrong host", "www.yahoo3.com", u2a
+                .getHost());
+        assertEquals("u2a returns a wrong port", -1, u2a.getPort());
+        assertEquals("u2a returns a wrong file", "/dir1/dir2/test.cgi", u2a
+                .getFile());
+        assertEquals("u2a returns a wrong anchor", "anchor1", u2a.getRef());
+
+        // test for no file, no port
+        u3 = new URL("http://www.yahoo4.com/");
+        assertEquals("u3 returns a wrong protocol", "http", u3.getProtocol());
+        assertEquals("u3 returns a wrong host", "www.yahoo4.com", u3.getHost());
+        assertEquals("u3 returns a wrong port", -1, u3.getPort());
+        assertEquals("u3 returns a wrong file", "/", u3.getFile());
+        assertNull("u3 returns a wrong anchor", u3.getRef());
+
+        // test for no file, no port
+        URL u3a = new URL("file://www.yahoo4.com/");
+        assertEquals("u3a returns a wrong protocol", "file", u3a.getProtocol());
+        assertEquals("u3a returns a wrong host", "www.yahoo4.com", u3a
+                .getHost());
+        assertEquals("u3a returns a wrong port", -1, u3a.getPort());
+        assertEquals("u3a returns a wrong file", "/", u3a.getFile());
+        assertNull("u3a returns a wrong anchor", u3a.getRef());
+
+        // test for no file, no port
+        URL u3b = new URL("file://www.yahoo4.com");
+        assertEquals("u3b returns a wrong protocol", "file", u3b.getProtocol());
+        assertEquals("u3b returns a wrong host", "www.yahoo4.com", u3b
+                .getHost());
+        assertEquals("u3b returns a wrong port", -1, u3b.getPort());
+        assertTrue("u3b returns a wrong file", u3b.getFile().equals(""));
+        assertNull("u3b returns a wrong anchor", u3b.getRef());
+
+        // test for non-port ":" and wierd characters occurrences
+        u4 = new URL(
+                "http://www.yahoo5.com/di!@$%^&*()_+r1/di:::r2/test.cgi?point1.html#anchor1");
+        assertEquals("u4 returns a wrong protocol", "http", u4.getProtocol());
+        assertEquals("u4 returns a wrong host", "www.yahoo5.com", u4.getHost());
+        assertEquals("u4 returns a wrong port", -1, u4.getPort());
+        assertEquals("u4 returns a wrong file",
+                "/di!@$%^&*()_+r1/di:::r2/test.cgi?point1.html", u4.getFile());
+        assertEquals("u4 returns a wrong anchor", "anchor1", u4.getRef());
+
+        u5 = new URL("file:/testing.tst");
+        assertEquals("u5 returns a wrong protocol", "file", u5.getProtocol());
+        assertTrue("u5 returns a wrong host", u5.getHost().equals(""));
+        assertEquals("u5 returns a wrong port", -1, u5.getPort());
+        assertEquals("u5 returns a wrong file", "/testing.tst", u5.getFile());
+        assertNull("u5 returns a wrong anchor", u5.getRef());
+
+        URL u5a = new URL("file:testing.tst");
+        assertEquals("u5a returns a wrong protocol", "file", u5a.getProtocol());
+        assertTrue("u5a returns a wrong host", u5a.getHost().equals(""));
+        assertEquals("u5a returns a wrong port", -1, u5a.getPort());
+        assertEquals("u5a returns a wrong file", "testing.tst", u5a.getFile());
+        assertNull("u5a returns a wrong anchor", u5a.getRef());
+
+        URL u6 = new URL("http://host:/file");
+        assertEquals("u6 return a wrong port", -1, u6.getPort());
+
+        URL u7 = new URL("file:../../file.txt");
+        assertTrue("u7 returns a wrong file: " + u7.getFile(), u7.getFile()
+                .equals("../../file.txt"));
+
+        URL u8 = new URL("http://[fec0::1:20d:60ff:fe24:7410]:35/file.txt");
+        assertTrue("u8 returns a wrong protocol " + u8.getProtocol(), u8
+                .getProtocol().equals("http"));
+        assertTrue("u8 returns a wrong host " + u8.getHost(), u8.getHost()
+                .equals("[fec0::1:20d:60ff:fe24:7410]"));
+        assertTrue("u8 returns a wrong port " + u8.getPort(),
+                u8.getPort() == 35);
+        assertTrue("u8 returns a wrong file " + u8.getFile(), u8.getFile()
+                .equals("/file.txt"));
+        assertNull("u8 returns a wrong anchor " + u8.getRef(), u8.getRef());
+
+        URL u9 = new URL("file://[fec0::1:20d:60ff:fe24:7410]/file.txt#sogood");
+        assertTrue("u9 returns a wrong protocol " + u9.getProtocol(), u9
+                .getProtocol().equals("file"));
+        assertTrue("u9 returns a wrong host " + u9.getHost(), u9.getHost()
+                .equals("[fec0::1:20d:60ff:fe24:7410]"));
+        assertTrue("u9 returns a wrong port " + u9.getPort(),
+                u9.getPort() == -1);
+        assertTrue("u9 returns a wrong file " + u9.getFile(), u9.getFile()
+                .equals("/file.txt"));
+        assertTrue("u9 returns a wrong anchor " + u9.getRef(), u9.getRef()
+                .equals("sogood"));
+
+        URL u10 = new URL("file://[fec0::1:20d:60ff:fe24:7410]");
+        assertTrue("u10 returns a wrong protocol " + u10.getProtocol(), u10
+                .getProtocol().equals("file"));
+        assertTrue("u10 returns a wrong host " + u10.getHost(), u10.getHost()
+                .equals("[fec0::1:20d:60ff:fe24:7410]"));
+        assertTrue("u10 returns a wrong port " + u10.getPort(),
+                u10.getPort() == -1);
+
+        URL u11 = new URL("file:////file.txt");
+        assertNull("u11 returns a wrong authority " + u11.getAuthority(), u11
+                .getAuthority());
+        assertTrue("u11 returns a wrong file " + u11.getFile(), u11.getFile()
+                .equals("////file.txt"));
+
+        URL u12 = new URL("file:///file.txt");
+        assertTrue("u12 returns a wrong authority", u12.getAuthority().equals(
+                ""));
+        assertTrue("u12 returns a wrong file " + u12.getFile(), u12.getFile()
+                .equals("/file.txt"));
+
+
+        // test for error catching
+
+        // Bad HTTP format - no "//"
+        u = new URL(
+                "http:www.yahoo5.com::22/dir1/di:::r2/test.cgi?point1.html#anchor1");
+
+        caught = false;
+        try {
+            u = new URL(
+                    "http://www.yahoo5.com::22/dir1/di:::r2/test.cgi?point1.html#anchor1");
+        } catch (MalformedURLException e) {
+            caught = true;
+        }
+        assertTrue("Should have throw MalformedURLException", caught);
+
+        // unknown protocol
+        try {
+            u = new URL("myProtocol://www.yahoo.com:22");
+        } catch (MalformedURLException e) {
+            caught = true;
+        }
+        assertTrue("3 Failed to throw MalformedURLException", caught);
+
+        caught = false;
+        // no protocol
+        try {
+            u = new URL("www.yahoo.com");
+        } catch (MalformedURLException e) {
+            caught = true;
+        }
+        assertTrue("4 Failed to throw MalformedURLException", caught);
+
+        caught = false;
+
+        URL u1 = null;
+        try {
+            // No leading or trailing spaces.
+            u1 = new URL("file:/some/path");
+            assertEquals("5 got wrong file length1", 10, u1.getFile().length());
+
+            // Leading spaces.
+            u1 = new URL("  file:/some/path");
+            assertEquals("5 got wrong file length2", 10, u1.getFile().length());
+
+            // Trailing spaces.
+            u1 = new URL("file:/some/path  ");
+            assertEquals("5 got wrong file length3", 10, u1.getFile().length());
+
+            // Leading and trailing.
+            u1 = new URL("  file:/some/path ");
+            assertEquals("5 got wrong file length4", 10, u1.getFile().length());
+
+            // in-place spaces.
+            u1 = new URL("  file:  /some/path ");
+            assertEquals("5 got wrong file length5", 12, u1.getFile().length());
+
+        } catch (MalformedURLException e) {
+            fail("5 Did not expect the exception " + e);
+        }
+
+        // testing jar protocol with relative path
+        // to make sure it's not canonicalized
+        try {
+            String file = "file:/a!/b/../d";
+
+            u = new URL("jar:" + file);
+            assertEquals("Wrong file (jar protocol, relative path)", file, u
+                    .getFile());
+        } catch (MalformedURLException e) {
+            fail("Unexpected exception (jar protocol, relative path)" + e);
+        }
+    }
+
+    /**
+     * java.net.URL#URL(java.net.URL, java.lang.String)
+     */
+    public void test_ConstructorLjava_net_URLLjava_lang_String()
+            throws Exception {
+        // Test for method java.net.URL(java.net.URL, java.lang.String)
+        u = new URL("http://www.yahoo.com");
+        URL uf = new URL("file://www.yahoo.com");
+        // basic ones
+        u1 = new URL(u, "file.java");
+        assertEquals("1 returns a wrong protocol", "http", u1.getProtocol());
+        assertEquals("1 returns a wrong host", "www.yahoo.com", u1.getHost());
+        assertEquals("1 returns a wrong port", -1, u1.getPort());
+        assertEquals("1 returns a wrong file", "/file.java", u1.getFile());
+        assertNull("1 returns a wrong anchor", u1.getRef());
+
+        URL u1f = new URL(uf, "file.java");
+        assertEquals("1f returns a wrong protocol", "file", u1f.getProtocol());
+        assertEquals("1f returns a wrong host", "www.yahoo.com", u1f.getHost());
+        assertEquals("1f returns a wrong port", -1, u1f.getPort());
+        assertEquals("1f returns a wrong file", "/file.java", u1f.getFile());
+        assertNull("1f returns a wrong anchor", u1f.getRef());
+
+        u1 = new URL(u, "dir1/dir2/../file.java");
+        assertEquals("3 returns a wrong protocol", "http", u1.getProtocol());
+        assertTrue("3 returns a wrong host: " + u1.getHost(), u1.getHost()
+                .equals("www.yahoo.com"));
+        assertEquals("3 returns a wrong port", -1, u1.getPort());
+        assertEquals("3 returns a wrong file", "/dir1/dir2/../file.java", u1
+                .getFile());
+        assertNull("3 returns a wrong anchor", u1.getRef());
+
+        u1 = new URL(u, "http:dir1/dir2/../file.java");
+        assertEquals("3a returns a wrong protocol", "http", u1.getProtocol());
+        assertTrue("3a returns a wrong host: " + u1.getHost(), u1.getHost()
+                .equals(""));
+        assertEquals("3a returns a wrong port", -1, u1.getPort());
+        assertEquals("3a returns a wrong file", "dir1/dir2/../file.java", u1
+                .getFile());
+        assertNull("3a returns a wrong anchor", u1.getRef());
+
+        u = new URL("http://www.apache.org/testing/");
+        u1 = new URL(u, "file.java");
+        assertEquals("4 returns a wrong protocol", "http", u1.getProtocol());
+        assertEquals("4 returns a wrong host", "www.apache.org", u1.getHost());
+        assertEquals("4 returns a wrong port", -1, u1.getPort());
+        assertEquals("4 returns a wrong file", "/testing/file.java", u1
+                .getFile());
+        assertNull("4 returns a wrong anchor", u1.getRef());
+
+        uf = new URL("file://www.apache.org/testing/");
+        u1f = new URL(uf, "file.java");
+        assertEquals("4f returns a wrong protocol", "file", u1f.getProtocol());
+        assertEquals("4f returns a wrong host", "www.apache.org", u1f.getHost());
+        assertEquals("4f returns a wrong port", -1, u1f.getPort());
+        assertEquals("4f returns a wrong file", "/testing/file.java", u1f
+                .getFile());
+        assertNull("4f returns a wrong anchor", u1f.getRef());
+
+        uf = new URL("file:/testing/");
+        u1f = new URL(uf, "file.java");
+        assertEquals("4fa returns a wrong protocol", "file", u1f.getProtocol());
+        assertTrue("4fa returns a wrong host", u1f.getHost().equals(""));
+        assertEquals("4fa returns a wrong port", -1, u1f.getPort());
+        assertEquals("4fa returns a wrong file", "/testing/file.java", u1f
+                .getFile());
+        assertNull("4fa returns a wrong anchor", u1f.getRef());
+
+        uf = new URL("file:testing/");
+        u1f = new URL(uf, "file.java");
+        assertEquals("4fb returns a wrong protocol", "file", u1f.getProtocol());
+        assertTrue("4fb returns a wrong host", u1f.getHost().equals(""));
+        assertEquals("4fb returns a wrong port", -1, u1f.getPort());
+        assertEquals("4fb returns a wrong file", "testing/file.java", u1f
+                .getFile());
+        assertNull("4fb returns a wrong anchor", u1f.getRef());
+
+        u1f = new URL(uf, "file:file.java");
+        assertEquals("4fc returns a wrong protocol", "file", u1f.getProtocol());
+        assertTrue("4fc returns a wrong host", u1f.getHost().equals(""));
+        assertEquals("4fc returns a wrong port", -1, u1f.getPort());
+        assertEquals("4fc returns a wrong file", "file.java", u1f.getFile());
+        assertNull("4fc returns a wrong anchor", u1f.getRef());
+
+        u1f = new URL(uf, "file:");
+        assertEquals("4fd returns a wrong protocol", "file", u1f.getProtocol());
+        assertTrue("4fd returns a wrong host", u1f.getHost().equals(""));
+        assertEquals("4fd returns a wrong port", -1, u1f.getPort());
+        assertTrue("4fd returns a wrong file", u1f.getFile().equals(""));
+        assertNull("4fd returns a wrong anchor", u1f.getRef());
+
+        u = new URL("http://www.apache.org/testing");
+        u1 = new URL(u, "file.java");
+        assertEquals("5 returns a wrong protocol", "http", u1.getProtocol());
+        assertEquals("5 returns a wrong host", "www.apache.org", u1.getHost());
+        assertEquals("5 returns a wrong port", -1, u1.getPort());
+        assertEquals("5 returns a wrong file", "/file.java", u1.getFile());
+        assertNull("5 returns a wrong anchor", u1.getRef());
+
+        uf = new URL("file://www.apache.org/testing");
+        u1f = new URL(uf, "file.java");
+        assertEquals("5f returns a wrong protocol", "file", u1f.getProtocol());
+        assertEquals("5f returns a wrong host", "www.apache.org", u1f.getHost());
+        assertEquals("5f returns a wrong port", -1, u1f.getPort());
+        assertEquals("5f returns a wrong file", "/file.java", u1f.getFile());
+        assertNull("5f returns a wrong anchor", u1f.getRef());
+
+        uf = new URL("file:/testing");
+        u1f = new URL(uf, "file.java");
+        assertEquals("5fa returns a wrong protocol", "file", u1f.getProtocol());
+        assertTrue("5fa returns a wrong host", u1f.getHost().equals(""));
+        assertEquals("5fa returns a wrong port", -1, u1f.getPort());
+        assertEquals("5fa returns a wrong file", "/file.java", u1f.getFile());
+        assertNull("5fa returns a wrong anchor", u1f.getRef());
+
+        uf = new URL("file:testing");
+        u1f = new URL(uf, "file.java");
+        assertEquals("5fb returns a wrong protocol", "file", u1f.getProtocol());
+        assertTrue("5fb returns a wrong host", u1f.getHost().equals(""));
+        assertEquals("5fb returns a wrong port", -1, u1f.getPort());
+        assertEquals("5fb returns a wrong file", "file.java", u1f.getFile());
+        assertNull("5fb returns a wrong anchor", u1f.getRef());
+
+        u = new URL("http://www.apache.org/testing/foobaz");
+        u1 = new URL(u, "/file.java");
+        assertEquals("6 returns a wrong protocol", "http", u1.getProtocol());
+        assertEquals("6 returns a wrong host", "www.apache.org", u1.getHost());
+        assertEquals("6 returns a wrong port", -1, u1.getPort());
+        assertEquals("6 returns a wrong file", "/file.java", u1.getFile());
+        assertNull("6 returns a wrong anchor", u1.getRef());
+
+        uf = new URL("file://www.apache.org/testing/foobaz");
+        u1f = new URL(uf, "/file.java");
+        assertEquals("6f returns a wrong protocol", "file", u1f.getProtocol());
+        assertEquals("6f returns a wrong host", "www.apache.org", u1f.getHost());
+        assertEquals("6f returns a wrong port", -1, u1f.getPort());
+        assertEquals("6f returns a wrong file", "/file.java", u1f.getFile());
+        assertNull("6f returns a wrong anchor", u1f.getRef());
+
+        u = new URL("http://www.apache.org:8000/testing/foobaz");
+        u1 = new URL(u, "/file.java");
+        assertEquals("7 returns a wrong protocol", "http", u1.getProtocol());
+        assertEquals("7 returns a wrong host", "www.apache.org", u1.getHost());
+        assertEquals("7 returns a wrong port", 8000, u1.getPort());
+        assertEquals("7 returns a wrong file", "/file.java", u1.getFile());
+        assertNull("7 returns a wrong anchor", u1.getRef());
+
+        u = new URL("http://www.apache.org/index.html");
+        u1 = new URL(u, "#bar");
+        assertEquals("8 returns a wrong host", "www.apache.org", u1.getHost());
+        assertEquals("8 returns a wrong file", "/index.html", u1.getFile());
+        assertEquals("8 returns a wrong anchor", "bar", u1.getRef());
+
+        u = new URL("http://www.apache.org/index.html#foo");
+        u1 = new URL(u, "http:#bar");
+        assertEquals("9 returns a wrong host", "www.apache.org", u1.getHost());
+        assertEquals("9 returns a wrong file", "/index.html", u1.getFile());
+        assertEquals("9 returns a wrong anchor", "bar", u1.getRef());
+
+        u = new URL("http://www.apache.org/index.html");
+        u1 = new URL(u, "");
+        assertEquals("10 returns a wrong host", "www.apache.org", u1.getHost());
+        assertEquals("10 returns a wrong file", "/index.html", u1.getFile());
+        assertNull("10 returns a wrong anchor", u1.getRef());
+
+        uf = new URL("file://www.apache.org/index.html");
+        u1f = new URL(uf, "");
+        assertEquals("10f returns a wrong host", "www.apache.org", u1.getHost());
+        assertEquals("10f returns a wrong file", "/index.html", u1.getFile());
+        assertNull("10f returns a wrong anchor", u1.getRef());
+
+        u = new URL("http://www.apache.org/index.html");
+        u1 = new URL(u, "http://www.apache.org");
+        assertEquals("11 returns a wrong host", "www.apache.org", u1.getHost());
+        assertTrue("11 returns a wrong file", u1.getFile().equals(""));
+        assertNull("11 returns a wrong anchor", u1.getRef());
+
+        // test for question mark processing
+        u = new URL("http://www.foo.com/d0/d1/d2/cgi-bin?foo=bar/baz");
+
+        // test for relative file and out of bound "/../" processing
+        u1 = new URL(u, "../dir1/./dir2/../file.java");
+        assertTrue("A) returns a wrong file: " + u1.getFile(), u1.getFile()
+                .equals("/d0/d1/dir1/file.java"));
+
+        // test for absolute and relative file processing
+        u1 = new URL(u, "/../dir1/./dir2/../file.java");
+        assertEquals("B) returns a wrong file", "/../dir1/./dir2/../file.java",
+                u1.getFile());
+
+        try {
+            // u should raise a MalFormedURLException because u, the context is
+            // null
+            u = null;
+            u1 = new URL(u, "file.java");
+            fail("didn't throw the expected MalFormedURLException");
+        } catch (MalformedURLException e) {
+            // valid
+        }
+
+        // Regression test for HARMONY-3258
+        // testing jar context url with relative file
+        try {
+            // check that relative path with null context is not canonicalized
+            String spec = "jar:file:/a!/b/../d";
+            URL ctx = null;
+            u = new URL(ctx, spec);
+            assertEquals("1 Wrong file (jar protocol, relative path)", spec, u
+                    .toString());
+
+            spec = "../d";
+            ctx = new URL("jar:file:/a!/b");
+            u = new URL(ctx, spec);
+            assertEquals("2 Wrong file (jar protocol, relative path)",
+                    "file:/a!/d", u.getFile());
+
+            spec = "../d";
+            ctx = new URL("jar:file:/a!/b/c");
+            u = new URL(ctx, spec);
+            assertEquals("3 Wrong file (jar protocol, relative path)",
+                    "file:/a!/d", u.getFile());
+
+            spec = "../d";
+            ctx = new URL("jar:file:/a!/b/c/d");
+            u = new URL(ctx, spec);
+            assertEquals("4 Wrong file (jar protocol, relative path)",
+                    "file:/a!/b/d", u.getFile());
+
+            // added the real example
+            spec = "../pdf/PDF.settings";
+            ctx = new URL(
+                    "jar:file:/C:/Program%20Files/Netbeans-5.5/ide7/modules/org-netbeans-modules-utilities.jar!/org/netbeans/modules/utilities/Layer.xml");
+            u = new URL(ctx, spec);
+            assertEquals(
+                    "5 Wrong file (jar protocol, relative path)",
+                    "file:/C:/Program%20Files/Netbeans-5.5/ide7/modules/org-netbeans-modules-utilities.jar!/org/netbeans/modules/pdf/PDF.settings",
+                    u.getFile());
+        } catch (MalformedURLException e) {
+            fail("Testing jar protocol, relative path failed: " + e);
+        }
+    }
+
+    /**
+     * java.net.URL#URL(java.net.URL, java.lang.String,
+     *java.net.URLStreamHandler)
+     */
+    public void test_ConstructorLjava_net_URLLjava_lang_StringLjava_net_URLStreamHandler()
+            throws Exception {
+        // Test for method java.net.URL(java.net.URL, java.lang.String,
+        // java.net.URLStreamHandler)
+        u = new URL("http://www.yahoo.com");
+        // basic ones
+        u1 = new URL(u, "file.java", new MyHandler());
+        assertEquals("1 returns a wrong protocol", "http", u1.getProtocol());
+        assertEquals("1 returns a wrong host", "www.yahoo.com", u1.getHost());
+        assertEquals("1 returns a wrong port", -1, u1.getPort());
+        assertEquals("1 returns a wrong file", "/file.java", u1.getFile());
+        assertNull("1 returns a wrong anchor", u1.getRef());
+
+        u1 = new URL(u, "systemresource:/+/FILE0/test.java", new MyHandler());
+        assertEquals("2 returns a wrong protocol", "systemresource", u1
+                .getProtocol());
+        assertTrue("2 returns a wrong host", u1.getHost().equals(""));
+        assertEquals("2 returns a wrong port", -1, u1.getPort());
+        assertEquals("2 returns a wrong file", "/+/FILE0/test.java", u1
+                .getFile());
+        assertNull("2 returns a wrong anchor", u1.getRef());
+
+        u1 = new URL(u, "dir1/dir2/../file.java", null);
+        assertEquals("3 returns a wrong protocol", "http", u1.getProtocol());
+        assertEquals("3 returns a wrong host", "www.yahoo.com", u1.getHost());
+        assertEquals("3 returns a wrong port", -1, u1.getPort());
+        assertEquals("3 returns a wrong file", "/dir1/dir2/../file.java", u1
+                .getFile());
+        assertNull("3 returns a wrong anchor", u1.getRef());
+
+        // test for question mark processing
+        u = new URL("http://www.foo.com/d0/d1/d2/cgi-bin?foo=bar/baz");
+
+        // test for relative file and out of bound "/../" processing
+        u1 = new URL(u, "../dir1/dir2/../file.java", new MyHandler());
+        assertTrue("A) returns a wrong file: " + u1.getFile(), u1.getFile()
+                .equals("/d0/d1/dir1/file.java"));
+
+        // test for absolute and relative file processing
+        u1 = new URL(u, "/../dir1/dir2/../file.java", null);
+        assertEquals("B) returns a wrong file", "/../dir1/dir2/../file.java",
+                u1.getFile());
+
+        URL one;
+        try {
+            one = new URL("http://www.ibm.com");
+        } catch (MalformedURLException ex) {
+            // Should not happen.
+            throw new RuntimeException(ex.getMessage());
+        }
+        try {
+            new URL(one, (String) null);
+            fail("Specifying null spec on URL constructor should throw MalformedURLException");
+        } catch (MalformedURLException e) {
+            // expected
+        }
+
+        try {
+            // u should raise a MalFormedURLException because u, the context is
+            // null
+            u = null;
+            u1 = new URL(u, "file.java", new MyHandler());
+        } catch (MalformedURLException e) {
+            return;
+        }
+        fail("didn't throw expected MalFormedURLException");
+    }
+
+    /**
+     * java.net.URL#URL(java.lang.String, java.lang.String,
+     *java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_StringLjava_lang_StringLjava_lang_String()
+            throws MalformedURLException {
+
+        u = new URL("http", "www.yahoo.com", "test.html#foo");
+        assertEquals("http", u.getProtocol());
+        assertEquals("www.yahoo.com", u.getHost());
+        assertEquals(-1, u.getPort());
+        assertEquals("test.html", u.getFile());
+        assertEquals("foo", u.getRef());
+
+        // Strange behavior in reference, the hostname contains a ':' so it gets
+        // wrapped in '[', ']'
+        URL testURL = new URL("http", "www.apache.org:8080", "test.html#anch");
+        assertEquals("wrong protocol", "http", testURL.getProtocol());
+        assertEquals("wrong host", "[www.apache.org:8080]", testURL.getHost());
+        assertEquals("wrong port", -1, testURL.getPort());
+        assertEquals("wrong file", "test.html", testURL.getFile());
+        assertEquals("wrong anchor", "anch", testURL.getRef());
+    }
+
+    /**
+     * java.net.URL#URL(java.lang.String, java.lang.String, int,
+     *java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_StringLjava_lang_StringILjava_lang_String()
+            throws MalformedURLException {
+        u = new URL("http", "www.yahoo.com", 8080, "test.html#foo");
+        assertEquals("SSIS returns a wrong protocol", "http", u.getProtocol());
+        assertEquals("SSIS returns a wrong host", "www.yahoo.com", u.getHost());
+        assertEquals("SSIS returns a wrong port", 8080, u.getPort());
+        assertEquals("SSIS returns a wrong file", "test.html", u.getFile());
+        assertTrue("SSIS returns a wrong anchor: " + u.getRef(), u.getRef()
+                .equals("foo"));
+
+        // Regression for HARMONY-83
+        new URL("http", "apache.org", 123456789, "file");
+        try {
+            new URL("http", "apache.org", -123, "file");
+            fail("Assert 0: Negative port should throw exception");
+        } catch (MalformedURLException e) {
+            // expected
+        }
+
+    }
+
+    /**
+     * java.net.URL#URL(java.lang.String, java.lang.String, int,
+     *java.lang.String, java.net.URLStreamHandler)
+     */
+    public void test_ConstructorLjava_lang_StringLjava_lang_StringILjava_lang_StringLjava_net_URLStreamHandler()
+            throws Exception {
+        // Test for method java.net.URL(java.lang.String, java.lang.String, int,
+        // java.lang.String, java.net.URLStreamHandler)
+        u = new URL("http", "www.yahoo.com", 8080, "test.html#foo", null);
+        assertEquals("SSISH1 returns a wrong protocol", "http", u.getProtocol());
+        assertEquals("SSISH1 returns a wrong host", "www.yahoo.com", u
+                .getHost());
+        assertEquals("SSISH1 returns a wrong port", 8080, u.getPort());
+        assertEquals("SSISH1 returns a wrong file", "test.html", u.getFile());
+        assertTrue("SSISH1 returns a wrong anchor: " + u.getRef(), u.getRef()
+                .equals("foo"));
+
+        u = new URL("http", "www.yahoo.com", 8080, "test.html#foo",
+                new MyHandler());
+        assertEquals("SSISH2 returns a wrong protocol", "http", u.getProtocol());
+        assertEquals("SSISH2 returns a wrong host", "www.yahoo.com", u
+                .getHost());
+        assertEquals("SSISH2 returns a wrong port", 8080, u.getPort());
+        assertEquals("SSISH2 returns a wrong file", "test.html", u.getFile());
+        assertTrue("SSISH2 returns a wrong anchor: " + u.getRef(), u.getRef()
+                .equals("foo"));
+    }
+
+    /**
+     * java.net.URL#equals(java.lang.Object)
+     */
+    public void test_equalsLjava_lang_Object() throws MalformedURLException {
+        u = new URL("http://www.apache.org:8080/dir::23??????????test.html");
+        u1 = new URL("http://www.apache.org:8080/dir::23??????????test.html");
+        assertTrue("A) equals returns false for two identical URLs", u
+                .equals(u1));
+        assertTrue("return true for null comparison", !u1.equals(null));
+        u = new URL("ftp://www.apache.org:8080/dir::23??????????test.html");
+        assertTrue("Returned true for non-equal URLs", !u.equals(u1));
+
+        // Regression for HARMONY-6556
+        u = new URL("file", null, 0, "/test.txt");
+        u1 = new URL("file", null, 0, "/test.txt");
+        assertEquals(u, u1);
+
+        u = new URL("file", "first.invalid", 0, "/test.txt");
+        u1 = new URL("file", "second.invalid", 0, "/test.txt");
+        assertFalse(u.equals(u1));
+
+        u = new URL("file", "harmony.apache.org", 0, "/test.txt");
+        u1 = new URL("file", "www.apache.org", 0, "/test.txt");
+        assertEquals(u, u1);
+    }
+
+    /**
+     * java.net.URL#sameFile(java.net.URL)
+     */
+    public void test_sameFileLjava_net_URL() throws Exception {
+        // Test for method boolean java.net.URL.sameFile(java.net.URL)
+        u = new URL("http://www.yahoo.com");
+        u1 = new URL("http", "www.yahoo.com", "");
+        assertTrue("Should be the same1", u.sameFile(u1));
+        u = new URL("http://www.yahoo.com/dir1/dir2/test.html#anchor1");
+        u1 = new URL("http://www.yahoo.com/dir1/dir2/test.html#anchor2");
+        assertTrue("Should be the same ", u.sameFile(u1));
+
+        // regression test for Harmony-1040
+        u = new URL("file", null, -1, "/d:/somedir/");
+        u1 = new URL("file:/d:/somedir/");
+        assertFalse(u.sameFile(u1));
+
+        // regression test for Harmony-2136
+        URL url1 = new URL("file:///anyfile");
+        URL url2 = new URL("file://localhost/anyfile");
+        assertTrue(url1.sameFile(url2));
+
+        url1 = new URL("http:///anyfile");
+        url2 = new URL("http://localhost/anyfile");
+        assertFalse(url1.sameFile(url2));
+
+        url1 = new URL("ftp:///anyfile");
+        url2 = new URL("ftp://localhost/anyfile");
+        assertFalse(url1.sameFile(url2));
+
+        url1 = new URL("jar:file:///anyfile.jar!/");
+        url2 = new URL("jar:file://localhost/anyfile.jar!/");
+        assertFalse(url1.sameFile(url2));
+    }
+
+    /**
+     * java.net.URL#getContent()
+     */
+    public void test_getContent() {
+        // Test for method java.lang.Object java.net.URL.getContent()
+        byte[] ba;
+        InputStream is;
+        String s;
+        File resources = Support_Resources.createTempFolder();
+        try {
+            Support_Resources.copyFile(resources, null, "hyts_htmltest.html");
+            u = new URL("file", "", resources.getAbsolutePath()
+                    + "/hyts_htmltest.html");
+            u.openConnection();
+            is = (InputStream) u.getContent();
+            is.read(ba = new byte[4096]);
+            s = new String(ba);
+            assertTrue(
+                    "Incorrect content "
+                            + u
+                            + " does not contain: \" A Seemingly Non Important String \"",
+                    s.indexOf("A Seemingly Non Important String") >= 0);
+        } catch (IOException e) {
+            fail("IOException thrown : " + e.getMessage());
+        } finally {
+            // Support_Resources.deleteTempFolder(resources);
+        }
+    }
+
+    /**
+     * java.net.URL#getContent(class[])
+     */
+    public void test_getContent_LJavaLangClass() throws Exception {
+        byte[] ba;
+        InputStream is;
+        String s;
+
+        File resources = Support_Resources.createTempFolder();
+
+        Support_Resources.copyFile(resources, null, "hyts_htmltest.html");
+        u = new URL("file", "", resources.getAbsolutePath()
+                + "/hyts_htmltest.html");
+        u.openConnection();
+
+        is = (InputStream) u.getContent(new Class[] { Object.class });
+        is.read(ba = new byte[4096]);
+        s = new String(ba);
+        assertTrue("Incorrect content " + u
+                + " does not contain: \" A Seemingly Non Important String \"",
+                s.indexOf("A Seemingly Non Important String") >= 0);
+
+    }
+
+    /**
+     * java.net.URL#openStream()
+     */
+    public void test_openStream() throws Exception {
+        // Regression test for Harmony-1700
+        URL BASE = URLTest.class.getClassLoader().getResource(
+                URLTest.class.getPackage().getName().replace('.',
+                        File.separatorChar)
+                        + "/lf.jar");
+        URL url = new URL("jar:" + BASE + "!/foo.jar!/Bugs/HelloWorld.class");
+        try {
+            url.openStream();
+            fail("should throw FNFE.");
+        } catch (java.io.FileNotFoundException e) {
+            // Expected
+        }
+
+        // Test for method java.io.InputStream java.net.URL.openStream()
+        File resources = Support_Resources.createTempFolder();
+        Support_Resources.copyFile(resources, null, "hyts_htmltest.html");
+        u = new URL("file", "", resources.getAbsolutePath()
+                + "/hyts_htmltest.html");
+        // HTTP connection
+        InputStream is1 = u.openStream();
+        assertTrue("Unable to read from stream", is1.read() != 0);
+        is1.close();
+
+        boolean exception = false;
+        try {
+            u = new URL("file:///nonexistenttestdir/tstfile");
+            u.openStream();
+        } catch (IOException e) {
+            // Correct behaviour
+            exception = true;
+        }
+        assertTrue("openStream succeeded for non existent resource", exception);
+    }
+
+    /**
+     * java.net.URL#openConnection()
+     */
+    public void test_openConnection() {
+        // Test for method java.net.URLConnection java.net.URL.openConnection()
+        try {
+            u = new URL("systemresource:/FILE4/+/types.properties");
+            URLConnection uConn = u.openConnection();
+            assertNotNull("u.openConnection() returns null", uConn);
+        } catch (Exception e) {
+        }
+    }
+
+    /**
+     * java.net.URL#toString()
+     */
+    public void test_toString() {
+        // Test for method java.lang.String java.net.URL.toString()
+        try {
+            u1 = new URL("http://www.yahoo2.com:9999");
+            u = new URL(
+                    "http://www.yahoo1.com:8080/dir1/dir2/test.cgi?point1.html#anchor1");
+            assertEquals(
+                    "a) Does not return the right url string",
+
+                    "http://www.yahoo1.com:8080/dir1/dir2/test.cgi?point1.html#anchor1",
+                    u.toString());
+            assertEquals("b) Does not return the right url string",
+                    "http://www.yahoo2.com:9999", u1.toString());
+            assertTrue("c) Does not return the right url string", u
+                    .equals(new URL(u.toString())));
+        } catch (Exception e) {
+        }
+    }
+
+    /**
+     * java.net.URL#toExternalForm()
+     */
+    public void test_toExternalForm() {
+        // Test for method java.lang.String java.net.URL.toExternalForm()
+        try {
+            u1 = new URL("http://www.yahoo2.com:9999");
+            u = new URL(
+                    "http://www.yahoo1.com:8080/dir1/dir2/test.cgi?point1.html#anchor1");
+            assertEquals(
+                    "a) Does not return the right url string",
+
+                    "http://www.yahoo1.com:8080/dir1/dir2/test.cgi?point1.html#anchor1",
+                    u.toString());
+            assertEquals("b) Does not return the right url string",
+                    "http://www.yahoo2.com:9999", u1.toString());
+            assertTrue("c) Does not return the right url string", u
+                    .equals(new URL(u.toString())));
+
+            u = new URL("http:index");
+            assertEquals("2 wrong external form", "http:index", u
+                    .toExternalForm());
+
+            u = new URL("http", null, "index");
+            assertEquals("2 wrong external form", "http:index", u
+                    .toExternalForm());
+        } catch (Exception e) {
+        }
+    }
+
+    /**
+     * java.net.URL#getFile()
+     */
+    public void test_getFile() throws Exception {
+        // Test for method java.lang.String java.net.URL.getFile()
+        u = new URL("http", "www.yahoo.com:8080", 1233,
+                "test/!@$%^&*/test.html#foo");
+        assertEquals("returns a wrong file", "test/!@$%^&*/test.html", u
+                .getFile());
+        u = new URL("http", "www.yahoo.com:8080", 1233, "");
+        assertTrue("returns a wrong file", u.getFile().equals(""));
+    }
+
+    /**
+     * java.net.URL#getHost()
+     */
+    public void test_getHost() throws MalformedURLException {
+        // Regression for HARMONY-60
+        String ipv6Host = "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210";
+        URL url = new URL("http", ipv6Host, -1, "myfile");
+        assertEquals(("[" + ipv6Host + "]"), url.getHost());
+    }
+
+    /**
+     * java.net.URL#getPort()
+     */
+    public void test_getPort() throws Exception {
+        // Test for method int java.net.URL.getPort()
+        u = new URL("http://member12.c++.com:9999");
+        assertTrue("return wrong port number " + u.getPort(),
+                u.getPort() == 9999);
+        u = new URL("http://member12.c++.com:9999/");
+        assertEquals("return wrong port number", 9999, u.getPort());
+    }
+
+    /**
+     * @throws MalformedURLException
+     * java.net.URL#getDefaultPort()
+     */
+    public void test_getDefaultPort() throws MalformedURLException {
+        u = new URL("http://member12.c++.com:9999");
+        assertEquals(80, u.getDefaultPort());
+        u = new URL("ftp://member12.c++.com:9999/");
+        assertEquals(21, u.getDefaultPort());
+    }
+
+    /**
+     * java.net.URL#getProtocol()
+     */
+    public void test_getProtocol() throws Exception {
+        // Test for method java.lang.String java.net.URL.getProtocol()
+        u = new URL("http://www.yahoo2.com:9999");
+        assertTrue("u returns a wrong protocol: " + u.getProtocol(), u
+                .getProtocol().equals("http"));
+    }
+
+    /**
+     * java.net.URL#getRef()
+     */
+    public void test_getRef() {
+        // Test for method java.lang.String java.net.URL.getRef()
+        try {
+            u1 = new URL("http://www.yahoo2.com:9999");
+            u = new URL(
+                    "http://www.yahoo1.com:8080/dir1/dir2/test.cgi?point1.html#anchor1");
+            assertEquals("returns a wrong anchor1", "anchor1", u.getRef());
+            assertNull("returns a wrong anchor2", u1.getRef());
+            u1 = new URL("http://www.yahoo2.com#ref");
+            assertEquals("returns a wrong anchor3", "ref", u1.getRef());
+            u1 = new URL("http://www.yahoo2.com/file#ref1#ref2");
+            assertEquals("returns a wrong anchor4", "ref1#ref2", u1.getRef());
+        } catch (MalformedURLException e) {
+            fail("Incorrect URL format : " + e.getMessage());
+        }
+    }
+
+    /**
+     * java.net.URL#getAuthority()
+     */
+    public void test_getAuthority() throws MalformedURLException {
+        URL testURL = new URL("http", "hostname", 80, "/java?q1#ref");
+        assertEquals("hostname:80", testURL.getAuthority());
+        assertEquals("hostname", testURL.getHost());
+        assertNull(testURL.getUserInfo());
+        assertEquals("/java?q1", testURL.getFile());
+        assertEquals("/java", testURL.getPath());
+        assertEquals("q1", testURL.getQuery());
+        assertEquals("ref", testURL.getRef());
+
+        testURL = new URL("http", "u:p@home", 80, "/java?q1#ref");
+        assertEquals("[u:p@home]:80", testURL.getAuthority());
+        assertEquals("[u:p@home]", testURL.getHost());
+        assertNull(testURL.getUserInfo());
+        assertEquals("/java?q1", testURL.getFile());
+        assertEquals("/java", testURL.getPath());
+        assertEquals("q1", testURL.getQuery());
+        assertEquals("ref", testURL.getRef());
+
+        testURL = new URL("http", "home", -1, "/java");
+        assertEquals("wrong authority2", "home", testURL.getAuthority());
+        assertNull("wrong userInfo2", testURL.getUserInfo());
+        assertEquals("wrong host2", "home", testURL.getHost());
+        assertEquals("wrong file2", "/java", testURL.getFile());
+        assertEquals("wrong path2", "/java", testURL.getPath());
+        assertNull("wrong query2", testURL.getQuery());
+        assertNull("wrong ref2", testURL.getRef());
+    }
+
+    /**
+     * java.net.URL#toURL()
+     */
+    public void test_toURI() throws Exception {
+        u = new URL("http://www.apache.org");
+        URI uri = u.toURI();
+        assertTrue(u.equals(uri.toURL()));
+    }
+
+    /**
+     * java.net.URL#openConnection()
+     */
+    public void test_openConnection_FileProtocal() throws Exception {
+        // Regression test for Harmony-5779
+        String basedir = new File("temp.java").getAbsolutePath();
+        String fileUrlString = "file://localhost/" + basedir;
+        URLConnection conn = new URL(fileUrlString).openConnection();
+        assertEquals("file", conn.getURL().getProtocol());
+        assertEquals(new File(basedir), new File(conn.getURL().getFile()));
+
+        String nonLocalUrlString = "file://anything/" + basedir;
+        conn = new URL(nonLocalUrlString).openConnection();
+        assertEquals("ftp", conn.getURL().getProtocol());
+        assertEquals(new File(basedir), new File(conn.getURL().getFile()));
+    }
+
+    /**
+     * URLStreamHandler implementation class necessary for tests.
+     */
+    private class TestURLStreamHandler extends URLStreamHandler {
+        public URLConnection openConnection(URL arg0) throws IOException {
+            try {
+                return arg0.openConnection();
+            } catch (Throwable e) {
+                return null;
+            }
+        }
+
+        public URLConnection openConnection(URL arg0, Proxy proxy)
+                throws IOException {
+            return super.openConnection(u, proxy);
+        }
+    }
+
+    /**
+     * Check NPE throwing in constructor when protocol argument is null and
+     * URLStreamHandler argument is initialized.
+     */
+    public void test_ConstructorLnullLjava_lang_StringILjava_lang_StringLjava_net_URLStreamHandler()
+            throws Exception {
+        // Regression for HARMONY-1131
+        TestURLStreamHandler lh = new TestURLStreamHandler();
+
+        try {
+            new URL(null, "1", 0, "file", lh);
+            fail("NullPointerException expected, but nothing was thrown!");
+        } catch (NullPointerException e) {
+            // Expected NullPointerException
+        }
+
+    }
+
+    /**
+     * Check NPE throwing in constructor when protocol argument is null and
+     * URLStreamHandler argument is null.
+     */
+    public void test_ConstructorLnullLjava_lang_StringILjava_lang_StringLnull()
+            throws Exception {
+        // Regression for HARMONY-1131
+        try {
+            new URL(null, "1", 0, "file", null);
+            fail("NullPointerException expected, but nothing was thrown!");
+        } catch (NullPointerException e) {
+            // Expected NullPointerException
+        }
+    }
+
+    /**
+     * Check NPE throwing in constructor with 4 params when protocol argument is
+     * null.
+     */
+    public void test_ConstructorLnullLjava_lang_StringILjava_lang_String()
+            throws Exception {
+        // Regression for HARMONY-1131
+        try {
+            new URL(null, "1", 0, "file");
+            fail("NullPointerException expected, but nothing was thrown!");
+        } catch (NullPointerException e) {
+            // Expected NullPointerException
+        }
+    }
+
+    /**
+     * Check NPE throwing in constructor with 3 params when protocol argument is
+     * null.
+     */
+    public void test_ConstructorLnullLjava_lang_StringLjava_lang_String()
+            throws Exception {
+        // Regression for HARMONY-1131
+        try {
+            new URL(null, "1", "file");
+            fail("NullPointerException expected, but nothing was thrown!");
+        } catch (NullPointerException e) {
+            // Expected NullPointerException
+        }
+    }
+
+    public void test_toExternalForm_Absolute() throws MalformedURLException {
+        String strURL = "http://localhost?name=value";
+        URL url = new URL(strURL);
+        assertEquals(strURL, url.toExternalForm());
+
+        strURL = "http://localhost?name=value/age=12";
+        url = new URL(strURL);
+        assertEquals(strURL, url.toExternalForm());
+    }
+
+    public void test_toExternalForm_Relative() throws MalformedURLException {
+        String strURL = "http://a/b/c/d;p?q";
+        String ref = "?y";
+        URL url = new URL(new URL(strURL), ref);
+        assertEquals("http://a/b/c/?y", url.toExternalForm());
+    }
+
+    // Regression test for HARMONY-6254
+
+    // Bogus handler forces file part of URL to be null
+    static class MyHandler2 extends URLStreamHandler {
+
+        @Override
+        protected URLConnection openConnection(URL arg0) throws IOException {
+            return null;
+        }
+
+        @Override
+        protected void setURL(URL u, String protocol, String host, int port,
+                String authority, String userInfo, String file, String query,
+                String ref) {
+            super.setURL(u, protocol, host, port, authority, userInfo,
+                    (String) null, query, ref);
+        }
+    }
+
+    // Test special case of external form with null file part (HARMONY-6254)
+    public void test_toExternalForm_Null() throws IOException {
+        URLStreamHandler myHandler = new MyHandler2();
+        URL url = new URL(null, "foobar://example.com/foobar", myHandler);
+        String s = url.toExternalForm();
+        assertEquals("Got wrong URL external form", "foobar://example.com", s);
+    }
+
+    static class MockProxySelector extends ProxySelector {
+
+        public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
+            System.out.println("connection failed");
+        }
+
+        public List<Proxy> select(URI uri) {
+            isSelectCalled = true;
+            ArrayList<Proxy> proxyList = new ArrayList<Proxy>(1);
+            proxyList.add(Proxy.NO_PROXY);
+            return proxyList;
+        }
+    }
+
+    static class MyURLStreamHandler extends URLStreamHandler {
+
+        @Override
+        protected URLConnection openConnection(URL arg0) throws IOException {
+            return null;
+        }
+
+        public void parse(URL url, String spec, int start, int end) {
+            parseURL(url, spec, start, end);
+        }
+    }
+
+    static class MyURLStreamHandlerFactory implements URLStreamHandlerFactory {
+
+        public static MyURLStreamHandler handler = new MyURLStreamHandler();
+
+        public URLStreamHandler createURLStreamHandler(String arg0) {
+            handler = new MyURLStreamHandler();
+            return handler;
+        }
+
+    }
+
+    // Regression test for harmony-2941
+    public void test_URLStreamHandler_parseURL() throws MalformedURLException {
+        URL url = new URL("http://localhost");
+        MyURLStreamHandler handler = MyURLStreamHandlerFactory.handler;
+        try {
+            handler.parse(url, "//", 0, Integer.MIN_VALUE);
+            fail("Should throw SIOOBE.");
+        } catch (StringIndexOutOfBoundsException e) {
+            // expected;
+        }
+        try {
+            handler.parse(url, "1234//", 4, Integer.MIN_VALUE);
+            fail("Should throw SIOOBE.");
+        } catch (StringIndexOutOfBoundsException e) {
+            // expected;
+        }
+        try {
+            handler.parse(url, "1", -1, 0);
+            fail("Should throw SIOOBE.");
+        } catch (StringIndexOutOfBoundsException e) {
+            // expected;
+        }
+        try {
+            handler.parse(url, "1", 3, 2);
+            fail("Should throw SecurityException.");
+        } catch (SecurityException e) {
+            // expected;
+        }
+
+        try {
+            handler.parse(url, "11", 1, Integer.MIN_VALUE);
+            fail("Should throw SecurityException.");
+        } catch (SecurityException e) {
+            // expected;
+        }
+
+        // Regression tests for HARMONY-6499
+        try {
+            handler.parse(url, "any", 10, Integer.MIN_VALUE);
+            fail("Should throw StringIndexOutOfBoundsException");
+        } catch (StringIndexOutOfBoundsException e) {
+            // expected;
+        }
+
+        try {
+            handler.parse(url, "any", 10, Integer.MIN_VALUE + 1);
+            fail("Should throw StringIndexOutOfBoundsException");
+        } catch (StringIndexOutOfBoundsException e) {
+            // expected;
+        }
+
+        try {
+            handler.parse(url, "any", Integer.MIN_VALUE, Integer.MIN_VALUE);
+            fail("Should throw StringIndexOutOfBoundsException");
+        } catch (StringIndexOutOfBoundsException e) {
+            // expected;
+        }
+
+        try {
+            handler.parse(url, "any", Integer.MIN_VALUE, 2);
+            fail("Should throw StringIndexOutOfBoundsException");
+        } catch (StringIndexOutOfBoundsException e) {
+            // expected;
+        }
+
+        try {
+            handler.parse(url, "any", -1, 2);
+            fail("Should throw StringIndexOutOfBoundsException");
+        } catch (StringIndexOutOfBoundsException e) {
+            // expected;
+        }
+
+        try {
+            handler.parse(url, "any", -1, -1);
+            fail("Should throw SecurityException");
+        } catch (SecurityException e) {
+            // expected;
+        }
+    }
+
+    /**
+     * java.net.URL#URL(String, String, String)
+     */
+    public void test_java_protocol_handler_pkgs_prop()
+            throws MalformedURLException {
+        // Regression test for Harmony-3094
+        final String HANDLER_PKGS = "java.protocol.handler.pkgs";
+        String pkgs = System.getProperty(HANDLER_PKGS);
+        System.setProperty(HANDLER_PKGS,
+                "fake|org.apache.harmony.luni.tests.java.net");
+
+        try {
+            new URL("test_protocol", "", "fake.jar");
+        } finally {
+            if (pkgs == null) {
+                System.clearProperty(HANDLER_PKGS);
+            } else {
+                System.setProperty(HANDLER_PKGS, pkgs);
+            }
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/UnknownHostExceptionTest.java b/luni/src/test/java/tests/api/java/net/UnknownHostExceptionTest.java
new file mode 100644
index 0000000..d113e92
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/UnknownHostExceptionTest.java
@@ -0,0 +1,68 @@
+/*
+ *  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.UnknownHostException;
+
+import junit.framework.TestCase;
+
+public class UnknownHostExceptionTest extends TestCase {
+
+    /**
+     * java.net.UnknownHostException#UnknownHostException()
+     */
+    public void test_Constructor() {
+        try {
+            if (true) {
+                throw new UnknownHostException();
+            }
+            fail("Failed to generate Exception");
+        } catch (UnknownHostException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.net.UnknownHostException#UnknownHostException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        try {
+            if (true) {
+                throw new UnknownHostException("test");
+            }
+            fail("Failed to generate Exception");
+        } catch (UnknownHostException e) {
+            assertEquals("Threw exception with incorrect message", "test", e
+                    .getMessage());
+        }
+    }
+
+    /**
+     * 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() {
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/net/UnknownServiceExceptionTest.java b/luni/src/test/java/tests/api/java/net/UnknownServiceExceptionTest.java
new file mode 100644
index 0000000..416a9ff
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/UnknownServiceExceptionTest.java
@@ -0,0 +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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES 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.UnknownServiceException;
+
+import junit.framework.TestCase;
+
+public class UnknownServiceExceptionTest extends TestCase {
+
+    /**
+     * java.net.UnknownServiceException#UnknownServiceException()
+     */
+    public void test_Constructor() {
+        try {
+            if (true) {
+                throw new UnknownServiceException();
+            }
+            fail("Exception not thrown");
+        } catch (UnknownServiceException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.net.UnknownServiceException#UnknownServiceException(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        try {
+            if (true) {
+                throw new UnknownServiceException("test");
+            }
+            fail("Constructor failed");
+        } catch (UnknownServiceException e) {
+            assertEquals("Wrong exception message", "test", e.getMessage());
+        }
+    }
+
+    /**
+     * 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() {
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/AbstractCollectionTest.java b/luni/src/test/java/tests/api/java/util/AbstractCollectionTest.java
new file mode 100644
index 0000000..d38e1d9
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/AbstractCollectionTest.java
@@ -0,0 +1,345 @@
+/*
+ *  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.util;
+
+import java.util.AbstractCollection;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import junit.framework.TestCase;
+
+public class AbstractCollectionTest extends TestCase {
+
+    /**
+     * java.util.AbstractCollection#add(java.lang.Object)
+     */
+    public void test_addLjava_lang_Object() {
+        AbstractCollection<Object> ac = new AbstractCollection<Object>() {
+
+            @Override
+            public Iterator<Object> iterator() {
+                fail("iterator should not get called");
+                return null;
+            }
+
+            @Override
+            public int size() {
+                fail("size should not get called");
+                return 0;
+            }
+
+        };
+        try {
+            ac.add(null);
+        } catch (UnsupportedOperationException e) {
+        }
+    }
+
+    /**
+     * java.util.AbstractCollection#addAll(java.util.Collection)
+     */
+    public void test_addAllLjava_util_Collection() {
+        final Collection<String> fixtures = Arrays.asList("0", "1", "2");
+        AbstractCollection<String> ac = new AbstractCollection<String>() {
+
+            @Override
+            public boolean add(String object) {
+                assertTrue(fixtures.contains(object));
+                return true;
+            }
+
+            @Override
+            public Iterator<String> iterator() {
+                fail("iterator should not get called");
+                return null;
+            }
+
+            @Override
+            public int size() {
+                fail("size should not get called");
+                return 0;
+            }
+
+        };
+        assertTrue(ac.addAll(fixtures));
+    }
+
+    /**
+     * java.util.AbstractCollection#containsAll(java.util.Collection)
+     */
+    public void test_containsAllLjava_util_Collection() {
+        final Collection<String> fixtures = Arrays.asList("0", "1", "2");
+        AbstractCollection<String> ac = new AbstractCollection<String>() {
+
+            @Override
+            public boolean contains(Object object) {
+                assertTrue(fixtures.contains(object));
+                return true;
+            }
+
+            @Override
+            public Iterator<String> iterator() {
+                fail("iterator should not get called");
+                return null;
+            }
+
+            @Override
+            public int size() {
+                fail("size should not get called");
+                return 0;
+            }
+
+        };
+        assertTrue(ac.containsAll(fixtures));
+    }
+
+    /**
+     * java.util.AbstractCollection#isEmpty()
+     */
+    public void test_isEmpty() {
+        final boolean[] sizeCalled = new boolean[1];
+        AbstractCollection<Object> ac = new AbstractCollection<Object>() {
+            @Override
+            public Iterator<Object> iterator() {
+                fail("iterator should not get called");
+                return null;
+            }
+
+            @Override
+            public int size() {
+                sizeCalled[0] = true;
+                return 0;
+            }
+        };
+        assertTrue(ac.isEmpty());
+        assertTrue(sizeCalled[0]);
+    }
+
+    /**
+     * java.util.AbstractCollection#removeAll(java.util.Collection)
+     */
+    public void test_removeAllLjava_util_Collection() {
+        final String[] removed = new String[3];
+        AbstractCollection<String> ac = new AbstractCollection<String>() {
+
+            @Override
+            public Iterator<String> iterator() {
+                return new Iterator<String>() {
+                    String[] values = new String[] { "0", "1", "2" };
+                    int index;
+
+                    public boolean hasNext() {
+                        return index < values.length;
+                    }
+
+                    public String next() {
+                        return values[index++];
+                    }
+
+                    public void remove() {
+                        removed[index - 1] = values[index - 1];
+                    }
+
+                };
+            }
+
+            @Override
+            public int size() {
+                fail("size should not get called");
+                return 0;
+            }
+
+        };
+        assertTrue(ac.removeAll(Arrays.asList("0", "1", "2")));
+        for (String r : removed) {
+            if (!"0".equals(r) && !"1".equals(r) && !"2".equals(r)) {
+                fail("an unexpected element was removed");
+            }
+        }
+    }
+
+    /**
+     * java.util.AbstractCollection#retainAll(java.util.Collection)
+     */
+    public void test_retainAllLjava_util_Collection() {
+        final String[] removed = new String[1];
+        AbstractCollection<String> ac = new AbstractCollection<String>() {
+
+            @Override
+            public Iterator<String> iterator() {
+                return new Iterator<String>() {
+                    String[] values = new String[] { "0", "1", "2" };
+                    int index;
+
+                    public boolean hasNext() {
+                        return index < values.length;
+                    }
+
+                    public String next() {
+                        return values[index++];
+                    }
+
+                    public void remove() {
+                        removed[index - 1] = values[index - 1];
+                    }
+
+                };
+            }
+
+            @Override
+            public int size() {
+                fail("size should not get called");
+                return 0;
+            }
+
+        };
+        assertTrue(ac.retainAll(Arrays.asList("1", "2")));
+        assertEquals("0", removed[0]);
+    }
+
+    /**
+     * java.util.AbstractCollection#toArray()
+     */
+    public void test_toArray() {
+        AbstractCollection<String> ac = new AbstractCollection<String>() {
+            @Override
+            public Iterator<String> iterator() {
+                return new Iterator<String>() {
+                    String[] values = new String[] { "0", "1", "2" };
+                    int index;
+
+                    public boolean hasNext() {
+                        return index < values.length;
+                    }
+
+                    public String next() {
+                        return values[index++];
+                    }
+
+                    public void remove() {
+                        fail("remove should not get called");
+                    }
+
+                };
+            }
+
+            @Override
+            public int size() {
+                return 3;
+            }
+        };
+
+        Object[] array = ac.toArray();
+        assertEquals(3, array.length);
+        for (Object o : array) {
+            if (!"0".equals(o) && !"1".equals(o) && !"2".equals(o)) {
+                fail("an unexpected element was removed");
+            }
+        }
+    }
+
+    /**
+     * java.util.AbstractCollection#toArray(java.lang.Object[])
+     */
+    public void test_toArray$Ljava_lang_Object() {
+        AbstractCollection<String> ac = new AbstractCollection<String>() {
+            @Override
+            public Iterator<String> iterator() {
+                return new Iterator<String>() {
+                    String[] values = new String[] { "0", "1", "2" };
+                    int index;
+
+                    public boolean hasNext() {
+                        return index < values.length;
+                    }
+
+                    public String next() {
+                        return values[index++];
+                    }
+
+                    public void remove() {
+                        fail("remove should not get called");
+                    }
+
+                };
+            }
+
+            @Override
+            public int size() {
+                return 3;
+            }
+        };
+        try {
+            ac.toArray(null);
+            fail("No expected NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            ac.toArray(new StringBuffer[ac.size()]);
+            fail("No expected ArrayStoreException");
+        } catch (ArrayStoreException e) {
+            // expected
+        }
+
+        String[] a = new String[3];
+        assertSame(a, ac.toArray(a));
+
+        a = new String[0];
+        assertNotSame(a, ac.toArray(a));
+        a = ac.toArray(a);
+        assertEquals(3, a.length);
+
+        CharSequence[] csa = new CharSequence[3];
+        ac.toArray(csa);
+        assertEquals(3, csa.length);
+        assertEquals("0", csa[0]);
+        assertEquals("1", csa[1]);
+        assertEquals("2", csa[2]);
+    }
+
+    /**
+     * java.util.AbstractCollection#toString()
+     */
+    public void test_toString() {
+        // see HARMONY-1522
+        // collection that returns null iterator(this is against the spec.)
+        AbstractCollection<?> c = new AbstractCollection<Object>() {
+            @Override
+            public int size() {
+                // return non-zero value to pass 'isEmpty' check
+                return 1;
+            }
+
+            @Override
+            public Iterator<Object> iterator() {
+                // this violates the spec.
+                return null;
+            }
+        };
+
+        try {
+            // AbstractCollection.toString() doesn't verify
+            // whether iterator() returns null value or not
+            c.toString();
+            fail("No expected NullPointerException");
+        } catch (NullPointerException e) {
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/ArrayDequeTest.java b/luni/src/test/java/tests/api/java/util/ArrayDequeTest.java
new file mode 100644
index 0000000..bf28414
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/ArrayDequeTest.java
@@ -0,0 +1,932 @@
+/*
+ *  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.util;
+
+import java.io.Serializable;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+public class ArrayDequeTest extends TestCase {
+
+    private Object testObjOne;
+
+    private Object testObjTwo;
+
+    private Object testObjThree;
+
+    private Object testObjFour;
+
+    private Object testObjLast;
+
+    private ArrayDeque<Object> testQue;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        testObjOne = new Object();
+        testObjTwo = new Object();
+        testObjThree = new Object();
+        testObjFour = new Object();
+        testObjLast = new Object();
+        testQue = new ArrayDeque<Object>();
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#ArrayDeque()}
+     */
+    public void test_Constructor() throws Exception {
+        assertEquals(0, new ArrayDeque<Object>().size());
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#ArrayDeque(java.util.Collection)}
+     */
+    public void test_Constructor_LCollection() throws Exception {
+        assertEquals(0, new ArrayDeque<Object>(new ArrayList<Object>()).size());
+        try {
+            new ArrayDeque<Object>(null);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#ArrayDeque(int)}
+     */
+    public void test_Constructor_Int() throws Exception {
+        assertEquals(0, new ArrayDeque<Object>(8).size());
+        ArrayDeque<Object> zeroCapQue = new ArrayDeque<Object>(0);
+        assertEquals(0, zeroCapQue.size());
+        zeroCapQue.add(testObjOne);
+        assertEquals(1, zeroCapQue.size());
+        assertEquals(0, new ArrayDeque<Object>(0).size());
+        ArrayDeque<Object> negCapQue = new ArrayDeque<Object>(-1);
+        assertEquals(0, negCapQue.size());
+        negCapQue.add(testObjOne);
+        assertEquals(1, negCapQue.size());
+        ArrayDeque<Object> oneCapQue = new ArrayDeque<Object>(1);
+        assertEquals(0, oneCapQue.size());
+        oneCapQue.add(testObjOne);
+        assertEquals(1, oneCapQue.size());
+        oneCapQue.add(testObjOne);
+        assertEquals(2, oneCapQue.size());
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#addFirst(Object)}
+     */
+    public void test_addFirst() throws Exception {
+        testQue.addFirst(testObjOne);
+        assertEquals(1, testQue.size());
+        assertEquals(testObjOne, testQue.peek());
+        testQue.addFirst(testObjOne);
+        assertEquals(2, testQue.size());
+        assertEquals(testObjOne, testQue.peek());
+        testQue.addFirst(testObjTwo);
+        assertEquals(3, testQue.size());
+        assertEquals(testObjTwo, testQue.peek());
+        assertEquals(testObjOne, testQue.getLast());
+        try {
+            testQue.addFirst(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#addLast(Object)}
+     */
+    public void test_addLast() throws Exception {
+        testQue.addLast(testObjOne);
+        assertEquals(1, testQue.size());
+        assertEquals(testObjOne, testQue.peek());
+        testQue.addLast(testObjOne);
+        assertEquals(2, testQue.size());
+        assertEquals(testObjOne, testQue.peek());
+        testQue.addLast(testObjTwo);
+        assertEquals(3, testQue.size());
+        assertEquals(testObjOne, testQue.peek());
+        assertEquals(testObjTwo, testQue.getLast());
+        try {
+            testQue.addLast(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#offerFirst(Object)}
+     */
+    public void test_offerFirst() throws Exception {
+        assertTrue(testQue.offerFirst(testObjOne));
+        assertEquals(1, testQue.size());
+        assertEquals(testObjOne, testQue.peek());
+        assertTrue(testQue.offerFirst(testObjOne));
+        assertEquals(2, testQue.size());
+        assertEquals(testObjOne, testQue.peek());
+        assertTrue(testQue.offerFirst(testObjTwo));
+        assertEquals(3, testQue.size());
+        assertEquals(testObjTwo, testQue.peek());
+        assertEquals(testObjOne, testQue.getLast());
+        try {
+            testQue.offerFirst(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#offerLast(Object)}
+     */
+    public void test_offerLast() throws Exception {
+        assertTrue(testQue.offerLast(testObjOne));
+        assertEquals(1, testQue.size());
+        assertEquals(testObjOne, testQue.peek());
+        assertTrue(testQue.offerLast(testObjOne));
+        assertEquals(2, testQue.size());
+        assertEquals(testObjOne, testQue.peek());
+        assertTrue(testQue.offerLast(testObjTwo));
+        assertEquals(3, testQue.size());
+        assertEquals(testObjOne, testQue.peek());
+        assertEquals(testObjTwo, testQue.getLast());
+        try {
+            testQue.offerLast(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#removeFirst()}
+     */
+    public void test_removeFirst() throws Exception {
+        assertTrue(testQue.offerLast(testObjOne));
+        assertTrue(testQue.offerLast(testObjTwo));
+        assertTrue(testQue.offerLast(testObjThree));
+        assertEquals(3, testQue.size());
+        assertEquals(testObjOne, testQue.removeFirst());
+        assertEquals(2, testQue.size());
+        assertEquals(testObjTwo, testQue.removeFirst());
+        assertEquals(testObjThree, testQue.removeFirst());
+        assertEquals(0, testQue.size());
+        try {
+            testQue.removeFirst();
+            fail("should throw NoSuchElementException ");
+        } catch (NoSuchElementException e) {
+            // expected
+        }
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#removeLast()}
+     */
+    public void test_removeLast() throws Exception {
+        assertTrue(testQue.offerLast(testObjOne));
+        assertTrue(testQue.offerLast(testObjTwo));
+        assertTrue(testQue.offerLast(testObjThree));
+        assertEquals(3, testQue.size());
+        assertEquals(testObjThree, testQue.removeLast());
+        assertEquals(2, testQue.size());
+        assertEquals(testObjTwo, testQue.removeLast());
+        assertEquals(testObjOne, testQue.removeLast());
+        assertEquals(0, testQue.size());
+        try {
+            testQue.removeLast();
+            fail("should throw NoSuchElementException ");
+        } catch (NoSuchElementException e) {
+            // expected
+        }
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#pollFirst()}
+     */
+    public void test_pollFirst() throws Exception {
+        assertTrue(testQue.offerLast(testObjOne));
+        assertTrue(testQue.offerLast(testObjTwo));
+        assertTrue(testQue.offerLast(testObjThree));
+        assertEquals(3, testQue.size());
+        assertEquals(testObjOne, testQue.pollFirst());
+        assertEquals(2, testQue.size());
+        assertEquals(testObjTwo, testQue.pollFirst());
+        assertEquals(testObjThree, testQue.pollFirst());
+        assertEquals(0, testQue.size());
+        assertNull(testQue.pollFirst());
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#peekLast()}
+     */
+    public void test_pollLast() throws Exception {
+        assertTrue(testQue.offerLast(testObjOne));
+        assertTrue(testQue.offerLast(testObjTwo));
+        assertTrue(testQue.offerLast(testObjThree));
+        assertEquals(3, testQue.size());
+        assertEquals(testObjThree, testQue.pollLast());
+        assertEquals(2, testQue.size());
+        assertEquals(testObjTwo, testQue.pollLast());
+        assertEquals(testObjOne, testQue.pollLast());
+        assertEquals(0, testQue.size());
+        assertNull(testQue.pollFirst());
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#getFirst()}
+     */
+    public void test_getFirst() throws Exception {
+        assertTrue(testQue.offerLast(testObjOne));
+        assertTrue(testQue.offerLast(testObjTwo));
+        assertTrue(testQue.offerLast(testObjThree));
+        assertEquals(3, testQue.size());
+        assertEquals(testObjOne, testQue.getFirst());
+        assertEquals(3, testQue.size());
+        assertEquals(testObjOne, testQue.pollFirst());
+        assertEquals(testObjTwo, testQue.getFirst());
+        assertEquals(testObjTwo, testQue.pollFirst());
+        assertEquals(testObjThree, testQue.pollFirst());
+        assertEquals(0, testQue.size());
+        try {
+            testQue.getFirst();
+            fail("should throw NoSuchElementException ");
+        } catch (NoSuchElementException e) {
+            // expected
+        }
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#getLast()}
+     */
+    public void test_getLast() throws Exception {
+        assertTrue(testQue.offerLast(testObjOne));
+        assertTrue(testQue.offerLast(testObjTwo));
+        assertTrue(testQue.offerLast(testObjThree));
+        assertEquals(3, testQue.size());
+        assertEquals(testObjThree, testQue.getLast());
+        assertEquals(3, testQue.size());
+        assertEquals(testObjThree, testQue.pollLast());
+        assertEquals(testObjTwo, testQue.getLast());
+        assertEquals(testObjTwo, testQue.pollLast());
+        assertEquals(testObjOne, testQue.pollLast());
+        assertEquals(0, testQue.size());
+        try {
+            testQue.getLast();
+            fail("should throw NoSuchElementException ");
+        } catch (NoSuchElementException e) {
+            // expected
+        }
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#peekFirst()}
+     */
+    public void test_peekFirst() throws Exception {
+        assertTrue(testQue.offerLast(testObjOne));
+        assertTrue(testQue.offerLast(testObjTwo));
+        assertTrue(testQue.offerLast(testObjThree));
+        assertEquals(3, testQue.size());
+        assertEquals(testObjOne, testQue.peekFirst());
+        assertEquals(3, testQue.size());
+        assertEquals(testObjOne, testQue.pollFirst());
+        assertEquals(testObjTwo, testQue.peekFirst());
+        assertEquals(testObjTwo, testQue.pollFirst());
+        assertEquals(testObjThree, testQue.pollFirst());
+        assertEquals(0, testQue.size());
+        assertEquals(null, testQue.peekFirst());
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#peekLast()}
+     */
+    public void test_peekLast() throws Exception {
+        assertTrue(testQue.offerLast(testObjOne));
+        assertTrue(testQue.offerLast(testObjTwo));
+        assertTrue(testQue.offerLast(testObjThree));
+        assertEquals(3, testQue.size());
+        assertEquals(testObjThree, testQue.peekLast());
+        assertEquals(3, testQue.size());
+        assertEquals(testObjThree, testQue.pollLast());
+        assertEquals(testObjTwo, testQue.peekLast());
+        assertEquals(testObjTwo, testQue.pollLast());
+        assertEquals(testObjOne, testQue.pollLast());
+        assertEquals(0, testQue.size());
+        assertNull(testQue.peekLast());
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#removeFirstOccurrence(Object)}
+     */
+    public void test_removeFirstOccurrence() throws Exception {
+        assertTrue(testQue.offerLast(testObjOne));
+        assertTrue(testQue.offerLast(testObjTwo));
+        assertTrue(testQue.offerLast(testObjOne));
+        assertTrue(testQue.offerLast(testObjThree));
+        assertTrue(testQue.offerLast(testObjOne));
+        assertEquals(5, testQue.size());
+        assertTrue(testQue.removeFirstOccurrence(testObjOne));
+        assertFalse(testQue.removeFirstOccurrence(testObjFour));
+        assertEquals(testObjTwo, testQue.peekFirst());
+        assertEquals(testObjOne, testQue.peekLast());
+        assertEquals(4, testQue.size());
+        assertTrue(testQue.removeFirstOccurrence(testObjOne));
+        assertEquals(3, testQue.size());
+        assertEquals(testObjOne, testQue.peekLast());
+        assertTrue(testQue.removeFirstOccurrence(testObjOne));
+        assertEquals(2, testQue.size());
+        assertEquals(testObjThree, testQue.peekLast());
+        assertFalse(testQue.removeFirstOccurrence(testObjOne));
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#removeLastOccurrence(Object)}
+     */
+    public void test_removeLastOccurrence() throws Exception {
+        assertTrue(testQue.offerLast(testObjOne));
+        assertTrue(testQue.offerLast(testObjTwo));
+        assertTrue(testQue.offerLast(testObjOne));
+        assertTrue(testQue.offerLast(testObjThree));
+        assertTrue(testQue.offerLast(testObjOne));
+        assertEquals(5, testQue.size());
+        assertTrue(testQue.removeLastOccurrence(testObjOne));
+        assertFalse(testQue.removeLastOccurrence(testObjFour));
+        assertEquals(testObjOne, testQue.peekFirst());
+        assertEquals(testObjThree, testQue.peekLast());
+        assertEquals(4, testQue.size());
+        assertTrue(testQue.removeLastOccurrence(testObjOne));
+        assertEquals(3, testQue.size());
+        assertEquals(testObjOne, testQue.peekFirst());
+        assertEquals(testObjThree, testQue.peekLast());
+        assertTrue(testQue.removeLastOccurrence(testObjOne));
+        assertEquals(2, testQue.size());
+        assertEquals(testObjThree, testQue.peekLast());
+        assertFalse(testQue.removeLastOccurrence(testObjOne));
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#add(Object)}
+     */
+    public void test_add() throws Exception {
+        assertTrue(testQue.add(testObjOne));
+        assertTrue(testQue.add(testObjTwo));
+        assertTrue(testQue.add(testObjOne));
+        assertTrue(testQue.add(testObjThree));
+        assertEquals(testObjOne, testQue.peekFirst());
+        assertEquals(testObjThree, testQue.peekLast());
+        try {
+            testQue.add(null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#offer(Object)}
+     */
+    public void test_offer() throws Exception {
+        assertTrue(testQue.offer(testObjOne));
+        assertTrue(testQue.offer(testObjTwo));
+        assertTrue(testQue.offer(testObjOne));
+        assertTrue(testQue.offer(testObjThree));
+        assertEquals(testObjOne, testQue.peekFirst());
+        assertEquals(testObjThree, testQue.peekLast());
+        try {
+            testQue.offer(null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#remove()}
+     */
+    public void test_remove() throws Exception {
+        assertTrue(testQue.offerLast(testObjOne));
+        assertTrue(testQue.offerLast(testObjTwo));
+        assertTrue(testQue.offerLast(testObjThree));
+        assertEquals(3, testQue.size());
+        assertEquals(testObjOne, testQue.remove());
+        assertEquals(2, testQue.size());
+        assertEquals(testObjTwo, testQue.remove());
+        assertEquals(testObjThree, testQue.remove());
+        assertEquals(0, testQue.size());
+        try {
+            testQue.remove();
+            fail("should throw NoSuchElementException ");
+        } catch (NoSuchElementException e) {
+            // expected
+        }
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#poll()}
+     */
+    public void test_poll() throws Exception {
+        assertTrue(testQue.offerLast(testObjOne));
+        assertTrue(testQue.offerLast(testObjTwo));
+        assertTrue(testQue.offerLast(testObjThree));
+        assertEquals(3, testQue.size());
+        assertEquals(testObjOne, testQue.poll());
+        assertEquals(2, testQue.size());
+        assertEquals(testObjTwo, testQue.poll());
+        assertEquals(testObjThree, testQue.poll());
+        assertEquals(0, testQue.size());
+        assertNull(testQue.poll());
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#element()}
+     */
+    public void test_element() throws Exception {
+        assertTrue(testQue.offerLast(testObjOne));
+        assertTrue(testQue.offerLast(testObjTwo));
+        assertTrue(testQue.offerLast(testObjThree));
+        assertEquals(3, testQue.size());
+        assertEquals(testObjOne, testQue.element());
+        assertEquals(3, testQue.size());
+        assertEquals(testObjOne, testQue.pollFirst());
+        assertEquals(testObjTwo, testQue.element());
+        assertEquals(testObjTwo, testQue.pollFirst());
+        assertEquals(testObjThree, testQue.element());
+        assertEquals(testObjThree, testQue.pollFirst());
+        assertEquals(0, testQue.size());
+        try {
+            testQue.element();
+            fail("should throw NoSuchElementException ");
+        } catch (NoSuchElementException e) {
+            // expected
+        }
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#peek()}
+     */
+    public void test_peek() throws Exception {
+        assertTrue(testQue.offerLast(testObjOne));
+        assertTrue(testQue.offerLast(testObjTwo));
+        assertTrue(testQue.offerLast(testObjThree));
+        assertEquals(3, testQue.size());
+        assertEquals(testObjOne, testQue.peek());
+        assertEquals(3, testQue.size());
+        assertEquals(testObjOne, testQue.pollFirst());
+        assertEquals(testObjTwo, testQue.peek());
+        assertEquals(testObjTwo, testQue.pollFirst());
+        assertEquals(testObjThree, testQue.pollFirst());
+        assertEquals(0, testQue.size());
+        assertEquals(null, testQue.peek());
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#push(Object)}
+     */
+    public void test_push() throws Exception {
+        testQue.push(testObjOne);
+        assertEquals(1, testQue.size());
+        assertEquals(testObjOne, testQue.peek());
+        testQue.push(testObjOne);
+        assertEquals(2, testQue.size());
+        assertEquals(testObjOne, testQue.peek());
+        testQue.push(testObjTwo);
+        assertEquals(3, testQue.size());
+        assertEquals(testObjTwo, testQue.peek());
+        assertEquals(testObjOne, testQue.getLast());
+        try {
+            testQue.push(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#pop()}
+     */
+    public void test_pop() throws Exception {
+        assertTrue(testQue.offerLast(testObjOne));
+        assertTrue(testQue.offerLast(testObjTwo));
+        assertTrue(testQue.offerLast(testObjThree));
+        assertEquals(3, testQue.size());
+        assertEquals(testObjOne, testQue.pop());
+        assertEquals(2, testQue.size());
+        assertEquals(testObjTwo, testQue.pop());
+        assertEquals(testObjThree, testQue.pop());
+        assertEquals(0, testQue.size());
+        try {
+            testQue.pop();
+            fail("should throw NoSuchElementException ");
+        } catch (NoSuchElementException e) {
+            // expected
+        }
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#addFirst(Object)}
+     */
+    public void test_size() throws Exception {
+        assertEquals(0, testQue.size());
+        assertTrue(testQue.add(testObjOne));
+        assertTrue(testQue.add(testObjTwo));
+        assertEquals(2, testQue.size());
+        assertTrue(testQue.add(testObjOne));
+        assertTrue(testQue.add(testObjThree));
+        assertEquals(4, testQue.size());
+        testQue.remove();
+        testQue.remove();
+        assertEquals(2, testQue.size());
+        testQue.clear();
+        assertEquals(0, testQue.size());
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#isEmpty()}
+     */
+    public void test_isEmpty() throws Exception {
+        assertTrue(testQue.isEmpty());
+        assertTrue(testQue.add(testObjOne));
+        assertFalse(testQue.isEmpty());
+        assertTrue(testQue.add(testObjTwo));
+        assertFalse(testQue.isEmpty());
+        assertTrue(testQue.add(testObjOne));
+        assertTrue(testQue.add(testObjThree));
+        assertFalse(testQue.isEmpty());
+        testQue.remove();
+        testQue.remove();
+        assertFalse(testQue.isEmpty());
+        testQue.clear();
+        assertTrue(testQue.isEmpty());
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#iterator()}
+     */
+    public void test_iterator() throws Exception {
+        assertFalse(testQue.iterator().hasNext());
+        assertTrue(testQue.add(testObjOne));
+        assertTrue(testQue.add(testObjTwo));
+        assertTrue(testQue.add(testObjOne));
+        assertTrue(testQue.add(testObjThree));
+        assertTrue(testQue.add(testObjLast));
+        Iterator result = testQue.iterator();
+        assertEquals(5, testQue.size());
+        try {
+            result.remove();
+            fail("should throw IllegalStateException");
+        } catch (IllegalStateException e) {
+            // expected
+        }
+        assertTrue(testQue.add(testObjThree));
+        try {
+            result.next();
+            fail("should throw ConcurrentModificationException");
+        } catch (ConcurrentModificationException e) {
+            // expected
+        }
+        result = testQue.iterator();
+        assertEquals(testObjOne, result.next());
+        assertEquals(testObjTwo, result.next());
+        assertEquals(testObjOne, result.next());
+        assertEquals(testObjThree, result.next());
+        assertEquals(testObjLast, result.next());
+        assertTrue(result.hasNext());
+        result.remove();
+        assertEquals(testObjThree, result.next());
+        assertFalse(result.hasNext());
+        try {
+            result.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // expected
+        }
+        // test a full array
+        ArrayDeque<Object> ad = new ArrayDeque<Object>();
+        // fill the array
+        for (int i = 0; i < 16; ++i) {
+            ad.addLast(new Object());
+        }
+        assertTrue(ad.iterator().hasNext());
+        Iterator<Object> iter = ad.iterator();
+        for (int i = 0; i < 16; ++i) {
+            assertTrue(iter.hasNext());
+            iter.next();
+        }
+        iter.remove();
+        // test un-full array
+        ad = new ArrayDeque<Object>();
+        // fill the array
+        for (int i = 0; i < 5; ++i) {
+            ad.addLast(new Object());
+        }
+        iter = ad.iterator();
+        for (int i = 0; i < 5; ++i) {
+            assertTrue(iter.hasNext());
+            iter.next();
+        }
+        iter.remove();
+
+        ad = new ArrayDeque<Object>();
+        // fill the array
+        for (int i = 0; i < 16; ++i) {
+            ad.addLast(new Object());
+        }
+        iter = ad.iterator();
+        assertTrue(iter.hasNext());
+        for (int i = 0; i < ad.size(); ++i) {
+            iter.next();
+        }
+        assertFalse(iter.hasNext());
+        iter.remove();
+        ad.add(new Object());
+        assertFalse(iter.hasNext());
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#descendingIterator()}
+     */
+    public void test_descendingIterator() throws Exception {
+        assertFalse(testQue.descendingIterator().hasNext());
+        assertTrue(testQue.add(testObjOne));
+        assertTrue(testQue.add(testObjTwo));
+        assertTrue(testQue.add(testObjOne));
+        assertTrue(testQue.add(testObjThree));
+        assertTrue(testQue.add(testObjLast));
+        Iterator result = testQue.descendingIterator();
+        assertEquals(5, testQue.size());
+        try {
+            result.remove();
+            fail("should throw IllegalStateException");
+        } catch (IllegalStateException e) {
+            // expected
+        }
+        assertTrue(testQue.add(testObjFour));
+
+        // a strange behavior here, RI's descendingIterator() and iterator() is
+        // properly different. Notice spec: "The iterators returned by this
+        // class's iterator method are fail-fast". RI shows descendingIterator()
+        // is not an iterator method.
+        assertEquals(testObjLast, result.next());
+
+        result = testQue.descendingIterator();
+        assertEquals(testObjFour, result.next());
+        assertEquals(testObjLast, result.next());
+        assertEquals(testObjThree, result.next());
+        assertEquals(testObjOne, result.next());
+        assertEquals(testObjTwo, result.next());
+        assertTrue(result.hasNext());
+        result.remove();
+        assertEquals(testObjOne, result.next());
+        assertFalse(result.hasNext());
+        try {
+            result.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // expected
+        }
+        // test a full array
+        ArrayDeque<Object> ad = new ArrayDeque<Object>();
+        // fill the array
+        for (int i = 0; i < 16; ++i) {
+            ad.addLast(new Object());
+        }
+        assertTrue(ad.descendingIterator().hasNext());
+        Iterator<Object> iter = ad.descendingIterator();
+        for (int i = 0; i < 16; ++i) {
+            assertTrue(iter.hasNext());
+            iter.next();
+        }
+        iter.remove();
+        // test un-full array
+        ad = new ArrayDeque<Object>();
+        // fill the array
+        for (int i = 0; i < 5; ++i) {
+            ad.addLast(new Object());
+        }
+        iter = ad.descendingIterator();
+        for (int i = 0; i < 5; ++i) {
+            assertTrue(iter.hasNext());
+            iter.next();
+        }
+        iter.remove();
+
+        ad = new ArrayDeque<Object>();
+        // fill the array
+        for (int i = 0; i < 16; ++i) {
+            ad.addLast(new Object());
+        }
+        iter = ad.descendingIterator();
+        assertTrue(iter.hasNext());
+        for (int i = 0; i < ad.size(); ++i) {
+            iter.next();
+        }
+        assertFalse(iter.hasNext());
+        iter.remove();
+        ad.add(new Object());
+        assertFalse(iter.hasNext());
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#contains(Object)}
+     */
+    public void test_contains() throws Exception {
+        assertFalse(testQue.contains(testObjFour));
+        assertFalse(testQue.contains(null));
+        assertTrue(testQue.add(testObjOne));
+        assertTrue(testQue.add(testObjTwo));
+        assertTrue(testQue.add(testObjOne));
+        assertTrue(testQue.add(testObjThree));
+        assertTrue(testQue.add(testObjLast));
+
+        assertTrue(testQue.contains(testObjOne));
+        assertTrue(testQue.contains(testObjTwo));
+        assertTrue(testQue.contains(testObjThree));
+        assertTrue(testQue.contains(testObjLast));
+        assertFalse(testQue.contains(null));
+        testQue.clear();
+        assertFalse(testQue.contains(testObjOne));
+        assertFalse(testQue.contains(testObjTwo));
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#remove(Object)}
+     */
+    public void test_remove_LObject() throws Exception {
+        assertTrue(testQue.offerLast(testObjOne));
+        assertTrue(testQue.offerLast(testObjTwo));
+        assertTrue(testQue.offerLast(testObjOne));
+        assertTrue(testQue.offerLast(testObjThree));
+        assertTrue(testQue.offerLast(testObjOne));
+        assertEquals(5, testQue.size());
+        assertTrue(testQue.remove(testObjOne));
+        assertFalse(testQue.remove(testObjFour));
+        assertEquals(testObjTwo, testQue.peekFirst());
+        assertEquals(testObjOne, testQue.peekLast());
+        assertEquals(4, testQue.size());
+        assertTrue(testQue.remove(testObjOne));
+        assertEquals(3, testQue.size());
+        assertEquals(testObjOne, testQue.peekLast());
+        assertTrue(testQue.remove(testObjOne));
+        assertEquals(2, testQue.size());
+        assertEquals(testObjThree, testQue.peekLast());
+        assertFalse(testQue.remove(testObjOne));
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#clear()}
+     */
+    public void test_clear() throws Exception {
+        assertTrue(testQue.isEmpty());
+        testQue.clear();
+        assertTrue(testQue.isEmpty());
+        assertTrue(testQue.add(testObjOne));
+        assertTrue(testQue.add(testObjTwo));
+        assertTrue(testQue.add(testObjOne));
+        assertTrue(testQue.add(testObjThree));
+        testQue.clear();
+        assertTrue(testQue.isEmpty());
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#toArray()}
+     */
+    public void test_toArray() throws Exception {
+        assertEquals(0, testQue.toArray().length);
+        assertTrue(testQue.add(testObjOne));
+        assertTrue(testQue.add(testObjTwo));
+        assertTrue(testQue.add(testObjOne));
+        assertTrue(testQue.add(testObjThree));
+        assertTrue(testQue.add(testObjLast));
+        Object[] result = testQue.toArray();
+        assertEquals(5, testQue.size());
+        assertEquals(testObjOne, result[0]);
+        assertEquals(testObjTwo, result[1]);
+        assertEquals(testObjOne, result[2]);
+        assertEquals(testObjThree, result[3]);
+        assertEquals(testObjLast, result[4]);
+        // change in array do not affect ArrayDeque
+        result[0] = null;
+        assertEquals(5, testQue.size());
+        assertEquals(testObjOne, testQue.peek());
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#toArray(Object[])}
+     */
+    public void test_toArray_$LObject() throws Exception {
+        Object[] array = new Object[0];
+        Object[] result = testQue.toArray(array);
+        assertEquals(0, result.length);
+        assertEquals(array, result);
+        assertTrue(testQue.add(testObjOne));
+        assertTrue(testQue.add(testObjTwo));
+        assertTrue(testQue.add(testObjOne));
+        assertTrue(testQue.add(testObjThree));
+        assertTrue(testQue.add(testObjLast));
+        result = testQue.toArray(array);
+        assertEquals(5, testQue.size());
+        assertEquals(5, result.length);
+        assertEquals(0, array.length);
+        assertFalse(array == result);
+        assertEquals(testObjOne, result[0]);
+        assertEquals(testObjTwo, result[1]);
+        assertEquals(testObjOne, result[2]);
+        assertEquals(testObjThree, result[3]);
+        assertEquals(testObjLast, result[4]);
+        // change in array do not affect ArrayDeque
+        result[0] = null;
+        assertEquals(5, testQue.size());
+        assertEquals(testObjOne, testQue.peek());
+        try {
+            testQue.toArray(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+    }
+
+    /**
+     * {@link java.util.ArrayDeque#clone()}
+     */
+    public void test_clone() throws Exception {
+        ArrayDeque<Object> cloned = testQue.clone();
+        assertEquals(0, cloned.size());
+        assertFalse(cloned == testQue);
+        assertTrue(testQue.add(testObjOne));
+        assertTrue(testQue.add(testObjTwo));
+        assertTrue(testQue.add(testObjOne));
+        assertTrue(testQue.add(testObjThree));
+        assertTrue(testQue.add(testObjLast));
+        assertTrue(testQue.add(testQue));
+        cloned = testQue.clone();
+        assertEquals(6, cloned.size());
+        while (0 != testQue.size()) {
+            assertEquals(testQue.remove(), cloned.remove());
+        }
+    }
+
+    /**
+     * java.util.ArrayDeque#Serialization()
+     */
+    public void test_serialization() throws Exception {
+        assertTrue(testQue.add(new Integer(1)));
+        assertTrue(testQue.add(new Integer(2)));
+        assertTrue(testQue.add(new Integer(3)));
+        assertTrue(testQue.add(new Integer(4)));
+        assertTrue(testQue.add(new Integer(5)));
+        SerializationTest.verifySelf(testQue, new SerializableAssert() {
+            public void assertDeserialized(Serializable initial,
+                    Serializable deserialized) {
+                ArrayDeque<Object> formerQue = (ArrayDeque) initial;
+                ArrayDeque<Object> deserializedQue = (ArrayDeque) deserialized;
+                assertEquals(formerQue.remove(), deserializedQue.remove());
+            }
+        });
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    @SuppressWarnings({ "unchecked", "boxing" })
+    public void testSerializationCompatibility() throws Exception {
+        assertTrue(testQue.add(new Integer(1)));
+        assertTrue(testQue.add(new Integer(2)));
+        assertTrue(testQue.add(new Integer(3)));
+        assertTrue(testQue.add(new Integer(4)));
+        assertTrue(testQue.add(new Integer(5)));
+        SerializationTest.verifyGolden(this, testQue, new SerializableAssert() {
+            public void assertDeserialized(Serializable initial,
+                    Serializable deserialized) {
+                ArrayDeque<Object> formerQue = (ArrayDeque) initial;
+                ArrayDeque<Object> deserializedQue = (ArrayDeque) deserialized;
+                assertEquals(formerQue.remove(), deserializedQue.remove());
+            }
+        });
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/Arrays2Test.java b/luni/src/test/java/tests/api/java/util/Arrays2Test.java
new file mode 100644
index 0000000..bac98aa
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/Arrays2Test.java
@@ -0,0 +1,472 @@
+/*
+ * 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.util;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.RandomAccess;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class Arrays2Test extends TestCase {
+
+    /**
+     * java.util.Arrays#binarySearch(double[], double)
+     */
+    public void test_binarySearch$DD() {
+        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);
+        }
+        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));
+    }
+
+    /**
+     * java.util.Arrays#binarySearch(float[], float)
+     */
+    public void test_binarySearch$FF() {
+        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);
+        }
+        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));
+    }
+
+    /**
+     * java.util.Arrays#equals(double[], double[])
+     */
+    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 }));
+    }
+
+    /**
+     * java.util.Arrays#equals(float[], float[])
+     */
+    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 }));
+    }
+
+    /**
+     * java.util.Arrays#sort(double[])
+     */
+    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));
+    }
+
+    /**
+     * java.util.Arrays#sort(float[])
+     */
+    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));
+    }
+
+    /**
+     * java.util.Arrays#toString(boolean[])
+     */
+    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 }));
+    }
+
+    /**
+     * java.util.Arrays#toString(byte[])
+     */
+    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 }));
+    }
+
+    /**
+     * java.util.Arrays#toString(char[])
+     */
+    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' }));
+    }
+
+    /**
+     * java.util.Arrays#toString(double[])
+     */
+    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 }));
+    }
+
+    /**
+     * java.util.Arrays#toString(float[])
+     */
+    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 }));
+    }
+
+    /**
+     * java.util.Arrays#toString(int[])
+     */
+    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 }));
+    }
+
+    /**
+     * java.util.Arrays#toString(long[])
+     */
+    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 }));
+    }
+
+    /**
+     * java.util.Arrays#toString(short[])
+     */
+    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 }));
+    }
+
+    /**
+     * java.util.Arrays#toString(Object[])
+     */
+    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" }));
+    }
+
+    /**
+     * java.util.Arrays#deepToString(Object[])
+     */
+    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));
+    }
+
+    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));
+
+        try {
+            Arrays.asList((Object[]) null);
+            fail("No NPE");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    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);
+
+        try {
+            Arrays.binarySearch((String[]) null, "A", String.CASE_INSENSITIVE_ORDER);
+            fail("No NPE");
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            Arrays.binarySearch(strings, (String) null, String.CASE_INSENSITIVE_ORDER);
+            fail("No NPE");
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            Arrays.binarySearch(strings, (String) null, (Comparator<String>) null);
+            fail("No NPE");
+        } catch (NullPointerException e) {
+        }
+
+    }
+
+    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]);
+
+        try {
+            Arrays.sort((String[]) null, String.CASE_INSENSITIVE_ORDER);
+            fail("No NPE");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    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]);
+
+        try {
+            Arrays.sort((String[]) null, String.CASE_INSENSITIVE_ORDER);
+            fail("No NPE");
+        } catch (NullPointerException e) {
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/Collections2Test.java b/luni/src/test/java/tests/api/java/util/Collections2Test.java
new file mode 100644
index 0000000..9946404
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/Collections2Test.java
@@ -0,0 +1,497 @@
+/*
+ * 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.util;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.RandomAccess;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.Vector;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+import junit.framework.TestCase;
+import tests.util.SerializationTester;
+
+public class Collections2Test extends TestCase {
+
+    private static final SerializableAssert comparator = new SerializableAssert() {
+        public void assertDeserialized(Serializable reference, Serializable test) {
+            assertSame(reference, test);
+        }
+    };
+
+    /**
+     * java.util.Collections#binarySearch(java.util.List,
+     *java.lang.Object, java.util.Comparator)
+     */
+    public void test_binarySearchLjava_util_ListLjava_lang_ObjectLjava_util_Comparator() {
+        // Regression for HARMONY-94
+        LinkedList<Integer> lst = new LinkedList<Integer>();
+        lst.add(new Integer(30));
+        Collections.sort(lst, null);
+        int index = Collections.binarySearch(lst, new Integer(2), null);
+        assertEquals(-1, index);
+    }
+
+    /**
+     * java.util.Collections#binarySearch(java.util.List,
+     *java.lang.Object)
+     */
+    @SuppressWarnings("unchecked")
+    public void test_binarySearchLjava_util_ListLjava_lang_Object() {
+        // regression for Harmony-1367
+        List localList = new LinkedList();
+        assertEquals(-1, Collections.binarySearch(localList, new Object()));
+        localList.add(new Object());
+        try {
+            Collections.binarySearch(localList, new Integer(1));
+            fail("Should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.Collections#rotate(java.util.List, int)
+     */
+    public void test_rotateLjava_util_ListI() {
+        // Regression for HARMONY-19 Rotate an *empty* list
+        Collections.rotate(new ArrayList<Object>(), 25);
+
+        // Regression for HARMONY-20
+        List<String> list = new ArrayList<String>();
+        list.add(0, "zero");
+        list.add(1, "one");
+        list.add(2, "two");
+        list.add(3, "three");
+        list.add(4, "four");
+
+        Collections.rotate(list, Integer.MIN_VALUE);
+        assertEquals("Rotated incorrectly at position 0, ", "three",
+                list.get(0));
+        assertEquals("Rotated incorrectly at position 1, ", "four",
+                list.get(1));
+        assertEquals("Rotated incorrectly at position 2, ", "zero",
+                list.get(2));
+        assertEquals("Rotated incorrectly at position 3, ", "one",
+                list.get(3));
+        assertEquals("Rotated incorrectly at position 4, ", "two",
+                list.get(4));
+    }
+
+    /**
+     * java.util.Collections#synchronizedCollection(java.util.Collection)
+     */
+    public void test_synchronizedCollectionLjava_util_Collection() {
+        try {
+            // Regression for HARMONY-93
+            Collections.synchronizedCollection(null);
+            fail("Assert 0: synchronizedCollection(null) must throw NPE");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.Collections#synchronizedSortedMap(java.util.SortedMap)
+     */
+    public void test_synchronizedSortedMapLjava_util_SortedMap() {
+        try {
+            // Regression for HARMONY-93
+            Collections.synchronizedSortedMap(null);
+            fail("Assert 0: synchronizedSortedMap(null) must throw NPE");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.Collections#synchronizedMap(java.util.Map)
+     */
+    public void test_synchronizedMapLjava_util_Map() {
+        try {
+            // Regression for HARMONY-93
+            Collections.synchronizedMap(null);
+            fail("Assert 0: synchronizedMap(map) must throw NPE");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.Collections#synchronizedSet(java.util.Set)
+     */
+    public void test_synchronizedSetLjava_util_Set() {
+        try {
+            // Regression for HARMONY-93
+            Collections.synchronizedSet(null);
+            fail("Assert 0: synchronizedSet(set) must throw NPE");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.Collections#synchronizedSortedSet(java.util.SortedSet)
+     */
+    public void test_synchronizedSortedSetLjava_util_SortedSet() {
+        try {
+            // Regression for HARMONY-93
+            Collections.synchronizedSortedSet(null);
+            fail("Assert 0: synchronizedSortedSet(null) must throw NPE");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.Collections#unmodifiableCollection(java.util.Collection)
+     */
+    public void test_unmodifiableCollectionLjava_util_Collection() {
+        try {
+            // Regression for HARMONY-93
+            Collections.unmodifiableCollection(null);
+            fail("Assert 0: unmodifiableCollection(null) must throw NPE");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.Collections#unmodifiableMap(java.util.Map)
+     */
+    public void test_unmodifiableMapLjava_util_Map() {
+        try {
+            // Regression for HARMONY-93
+            Collections.unmodifiableMap(null);
+            fail("Assert 0: unmodifiableMap(null) must throw NPE");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.Collections#unmodifiableSet(java.util.Set)
+     */
+    public void test_unmodifiableSetLjava_util_Set() {
+        try {
+            // Regression for HARMONY-93
+            Collections.unmodifiableSet(null);
+            fail("Assert 0: unmodifiableSet(null) must throw NPE");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.Collections#unmodifiableSortedMap(java.util.SortedMap)
+     */
+    public void test_unmodifiableSortedMapLjava_util_SortedMap() {
+        try {
+            // Regression for HARMONY-93
+            Collections.unmodifiableSortedMap(null);
+            fail("Assert 0: unmodifiableSortedMap(null) must throw NPE");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.Collections#unmodifiableSortedSet(java.util.SortedSet)
+     */
+    public void test_unmodifiableSortedSetLjava_util_SortedSet() {
+        try {
+            // Regression for HARMONY-93
+            Collections.unmodifiableSortedSet(null);
+            fail("Assert 0: unmodifiableSortedSet(null) must throw NPE");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.Collections#frequency(java.util.Collection, Object)
+     */
+    public void test_frequencyLjava_util_CollectionLint() {
+        try {
+            Collections.frequency(null, null);
+            fail("Assert 0: frequency(null,<any>) must throw NPE");
+        } catch (NullPointerException e) {
+        }
+
+        List<String> strings = Arrays.asList(new String[] { "1", "2", "3", "1", "1" });
+
+        assertEquals("Assert 1: did not find three \"1\" strings", 3,
+                Collections.frequency(strings, "1"));
+
+        assertEquals("Assert 2: did not find one \"2\" strings", 1, Collections
+                .frequency(strings, "2"));
+
+        assertEquals("Assert 3: did not find three \"3\" strings", 1,
+                Collections.frequency(strings, "3"));
+
+        assertEquals("Assert 4: matched on null when there are none", 0,
+                Collections.frequency(strings, null));
+
+        List<Object> objects = Arrays.asList(new Object[] { new Integer(1), null, null,
+                new Long(1) });
+
+        assertEquals("Assert 5: did not find one Integer(1)", 1, Collections
+                .frequency(objects, new Integer(1)));
+
+        assertEquals("Assert 6: did not find one Long(1)", 1, Collections
+                .frequency(objects, new Long(1)));
+
+        assertEquals("Assert 7: did not find two null references", 2,
+                Collections.frequency(objects, null));
+    }
+
+    /**
+     * java.util.Collections#reverseOrder()
+     */
+    public void test_reverseOrder() {
+        Comparator<String> roc = Collections.reverseOrder();
+        assertNotNull("Assert 0: comparator must not be null", roc);
+
+        assertTrue("Assert 1: comparator must implement Serializable",
+                roc instanceof Serializable);
+
+        String[] fixtureDesc = new String[] { "2", "1", "0" };
+        String[] numbers = new String[] { "0", "1", "2" };
+        Arrays.sort(numbers, roc);
+        assertTrue("Assert 2: the arrays are not equal, the sort failed",
+                Arrays.equals(fixtureDesc, numbers));
+    }
+
+    /**
+     * java.util.Collections#reverseOrder(java.util.Comparator)
+     */
+    public void test_reverseOrderLjava_util_Comparator() {
+        Comparator<String> roc = Collections
+                .reverseOrder(String.CASE_INSENSITIVE_ORDER);
+        assertNotNull("Assert 0: comparator must not be null", roc);
+
+        assertTrue("Assert 1: comparator must implement Serializable",
+                roc instanceof Serializable);
+
+        String[] fixtureDesc = new String[] { "2", "1", "0" };
+        String[] numbers = new String[] { "0", "1", "2" };
+        Arrays.sort(numbers, roc);
+        assertTrue("Assert 2: the arrays are not equal, the sort failed",
+                Arrays.equals(fixtureDesc, numbers));
+
+        roc = Collections.reverseOrder(null);
+        assertNotNull("Assert 3: comparator must not be null", roc);
+
+        assertTrue("Assert 4: comparator must implement Serializable",
+                roc instanceof Serializable);
+
+        numbers = new String[] { "0", "1", "2" };
+        Arrays.sort(numbers, roc);
+        assertTrue("Assert 5: the arrays are not equal, the sort failed",
+                Arrays.equals(fixtureDesc, numbers));
+    }
+
+    public void test_AddAll() {
+        List<Object> l = new ArrayList<Object>();
+        assertFalse(Collections.addAll(l, new Object[] { }));
+        assertTrue(l.isEmpty());
+        assertTrue(Collections.addAll(l, new Object[] { new Integer(1),
+                new Integer(2), new Integer(3) }));
+        assertFalse(l.isEmpty());
+        assertTrue(l.equals(Arrays.asList(new Object[] { new Integer(1),
+                new Integer(2), new Integer(3) })));
+    }
+
+    public void test_Disjoint() {
+        Object[] arr1 = new Object[10];
+        for (int i = 0; i < arr1.length; i++) {
+            arr1[i] = new Integer(i);
+        }
+        Object[] arr2 = new Object[20];
+        for (int i = 0; i < arr2.length; i++) {
+            arr2[i] = new Integer(100 + i);
+        }
+        Collection<Object> c1 = new ArrayList<Object>();
+        Collection<Object> c2 = new ArrayList<Object>();
+        Collections.addAll(c1, arr1);
+        Collections.addAll(c2, arr2);
+        assertTrue(Collections.disjoint(c1, c2));
+        c1.add(arr2[10]);
+        assertFalse(Collections.disjoint(c1, c2));
+
+        c1 = new LinkedList<Object>();
+        c2 = new LinkedList<Object>();
+        Collections.addAll(c1, arr1);
+        Collections.addAll(c2, arr2);
+        assertTrue(Collections.disjoint(c1, c2));
+        c1.add(arr2[10]);
+        assertFalse(Collections.disjoint(c1, c2));
+
+        c1 = new TreeSet<Object>();
+        c2 = new TreeSet<Object>();
+        Collections.addAll(c1, arr1);
+        Collections.addAll(c2, arr2);
+        assertTrue(Collections.disjoint(c1, c2));
+        c1.add(arr2[10]);
+        assertFalse(Collections.disjoint(c1, c2));
+
+        c1 = new HashSet<Object>();
+        c2 = new HashSet<Object>();
+        Collections.addAll(c1, arr1);
+        Collections.addAll(c2, arr2);
+        assertTrue(Collections.disjoint(c1, c2));
+        c1.add(arr2[10]);
+        assertFalse(Collections.disjoint(c1, c2));
+
+        c1 = new LinkedList<Object>();
+        c2 = new TreeSet<Object>();
+        Collections.addAll(c1, arr1);
+        Collections.addAll(c2, arr2);
+        assertTrue(Collections.disjoint(c1, c2));
+        c1.add(arr2[10]);
+        assertFalse(Collections.disjoint(c1, c2));
+
+        c1 = new Vector<Object>();
+        c2 = new HashSet<Object>();
+        Collections.addAll(c1, arr1);
+        Collections.addAll(c2, arr2);
+        assertTrue(Collections.disjoint(c1, c2));
+        c1.add(arr2[10]);
+        assertFalse(Collections.disjoint(c1, c2));
+
+    }
+
+    /**
+     * java.util.Collections.EmptyList#readResolve()
+     */
+    public void test_EmptyList_readResolve() throws Exception {
+        SerializationTest.verifySelf(Collections.EMPTY_LIST, comparator);
+    }
+
+    /**
+     * java.util.Collections.EmptyMap#readResolve()
+     */
+    public void test_EmptyMap_readResolve() throws Exception {
+        SerializationTest.verifySelf(Collections.EMPTY_MAP, comparator);
+    }
+
+    /**
+     * java.util.Collections.EmptySet#readResolve()
+     */
+    public void test_EmptySet_readResolve() throws Exception {
+        SerializationTest.verifySelf(Collections.EMPTY_SET, comparator);
+    }
+
+    public void test_checkedCollectionSerializationCompatability() throws Exception {
+        Collection<String> c = Collections.emptySet();
+        c = Collections.checkedCollection(c, String.class);
+        SerializationTester.assertCompabilityEquals(c, "serialization/java/util/Collections_CheckedCollection.golden.ser");
+    }
+
+    public void test_checkedListRandomAccessSerializationCompatability() throws Exception {
+        List<String> c = new ArrayList<String>();
+        assertTrue(c instanceof RandomAccess);
+        c = Collections.checkedList(c, String.class);
+        SerializationTester.assertCompabilityEquals(c, "serialization/java/util/Collections_CheckedListRandomAccess.golden.ser");
+    }
+
+    public void test_checkedListSerializationCompatability() throws Exception {
+        List<String> c = new LinkedList<String>();
+        assertFalse(c instanceof RandomAccess);
+        c = Collections.checkedList(c, String.class);
+        SerializationTester.assertCompabilityEquals(c, "serialization/java/util/Collections_CheckedList.golden.ser");
+    }
+
+    public void test_checkedSetSerializationCompatability() throws Exception {
+        Set<String> c = new HashSet<String>();
+        assertFalse(c instanceof SortedSet);
+        c = Collections.checkedSet(c, String.class);
+        SerializationTester.assertCompabilityEquals(c, "serialization/java/util/Collections_CheckedSet.golden.ser");
+    }
+
+    public void test_checkedMapSerializationCompatability() throws Exception {
+        Map<String, String> c = new HashMap<String, String>();
+        assertFalse(c instanceof SortedMap);
+        c = Collections.checkedMap(c, String.class, String.class);
+        SerializationTester.assertCompabilityEquals(c, "serialization/java/util/Collections_CheckedMap.golden.ser");
+    }
+
+    public void test_checkedSortedSetSerializationCompatability() throws Exception {
+        SortedSet<String> c = new TreeSet<String>();
+        c = Collections.checkedSortedSet(c, String.class);
+        SerializationTester.assertCompabilityEquals(c, "serialization/java/util/Collections_CheckedSortedSet.golden.ser");
+    }
+
+    public void test_checkedSortedMapSerializationCompatability() throws Exception {
+        SortedMap<String, String> c = new TreeMap<String, String>();
+        c = Collections.checkedSortedMap(c, String.class, String.class);
+        SerializationTester.assertCompabilityEquals(c, "serialization/java/util/Collections_CheckedSortedMap.golden.ser");
+    }
+
+    public void test_emptyList() {
+        List<Object> emptyList = Collections.emptyList();
+        assertEquals(0, emptyList.size());
+        assertTrue(emptyList instanceof RandomAccess);
+    }
+
+    // Regression test for http://issues.apache.org/jira/browse/HARMONY-6122
+    public void test_Collections_swap_IndexOutOfBoundsException() {
+        try {
+            Collections.swap(new ArrayList<Object>(), -1, 3);
+            fail("IOOBE expected");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        List<Object> list = new ArrayList<Object>();
+        list.add("0");
+        try {
+            Collections.swap(list, 0, -1);
+            fail("IOOBE expected");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Collections.swap(list, 0, 3);
+            fail("IOOBE expected");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            Collections.swap(new ArrayList<Object>(), 3, 3);
+            fail("IOOBE expected");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/util/ControlTest.java b/luni/src/test/java/tests/api/java/util/ControlTest.java
new file mode 100644
index 0000000..759fc5b
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/ControlTest.java
@@ -0,0 +1,848 @@
+/*
+ *  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.util;
+
+import junit.framework.TestCase;
+import tests.support.resource.Support_Resources;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.PropertyResourceBundle;
+import java.util.ResourceBundle;
+import java.util.ResourceBundle.Control;
+import java.util.Scanner;
+import static java.util.ResourceBundle.Control.*;
+
+/**
+ * Test cases for java.util.ResourceBundle.Control
+ *
+ * @since 1.6
+ */
+public class ControlTest extends TestCase {
+
+    /**
+     * Control with format:FORMAT_PROPERTIES
+     */
+    private Control controlP;
+
+    /**
+     * Control with format:FORMAT_CLASS
+     */
+    private Control controlC;
+
+    /**
+     * Control with format:FORMAT_DEFAULT
+     */
+    private Control control;
+
+    /**
+     * {@link java.util.ResourceBundle.Control#Control()}.
+     */
+    @SuppressWarnings("nls")
+    public void test_Constructor() {
+
+        class SubControl extends Control {
+            SubControl() {
+                super();
+            }
+        }
+        Control subControl = new SubControl();
+        assertEquals(FORMAT_DEFAULT, subControl.getFormats(""));
+        assertFalse(control.equals(subControl));
+    }
+
+    /**
+     * Test for all the public constants.
+     *
+     * {@link java.util.ResourceBundle.Control#FORMAT_CLASS}
+     * {@link java.util.ResourceBundle.Control#FORMAT_DEFAULT}
+     * {@link java.util.ResourceBundle.Control#FORMAT_PROPERTIES}
+     * {@link java.util.ResourceBundle.Control#TTL_DONT_CACHE}
+     * {@link java.util.ResourceBundle.Control#TTL_NO_EXPIRATION_CONTROL}
+     */
+    @SuppressWarnings("nls")
+    public void test_Constants() {
+        List<String> list = FORMAT_CLASS;
+        assertEquals(1, list.size());
+        assertEquals("java.class", list.get(0));
+        list = FORMAT_PROPERTIES;
+        assertEquals(1, list.size());
+        assertEquals("java.properties", list.get(0));
+        list = FORMAT_DEFAULT;
+        assertEquals(2, list.size());
+        assertEquals("java.class", list.get(0));
+        assertEquals("java.properties", list.get(1));
+        try {
+            FORMAT_CLASS.add("");
+            fail("Should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+        try {
+            FORMAT_DEFAULT.add("");
+            fail("Should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+        try {
+            FORMAT_PROPERTIES.add("");
+            fail("Should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+        Class<?> unmodifiableListClass = Collections.unmodifiableList(
+                new ArrayList<String>()).getClass();
+        assertEquals(FORMAT_CLASS.getClass(), unmodifiableListClass);
+        assertEquals(FORMAT_DEFAULT.getClass(), unmodifiableListClass);
+        assertEquals(FORMAT_PROPERTIES.getClass(), unmodifiableListClass);
+        assertEquals(-1L, TTL_DONT_CACHE);
+        assertEquals(-2L, TTL_NO_EXPIRATION_CONTROL);
+    }
+
+    /**
+     * {@link java.util.ResourceBundle.Control#getControl(java.util.List)}.
+     */
+    @SuppressWarnings("nls")
+    public void test_getControl_LList() {
+        // singleton
+        assertSame(control, Control.getControl(FORMAT_DEFAULT));
+        assertSame(controlC, Control.getControl(FORMAT_CLASS));
+        assertSame(controlP, Control.getControl(FORMAT_PROPERTIES));
+
+        // class
+        assertTrue(control.getClass() == Control.class);
+        assertTrue(controlC.getClass() != Control.class);
+        assertTrue(controlP.getClass() != Control.class);
+
+        // formats: need not same, just need equal
+        List<String> list = new ArrayList<String>(FORMAT_CLASS);
+        assertSame(controlC, Control.getControl(list));
+        // can add
+        list.add(FORMAT_PROPERTIES.get(0));
+        assertSame(control, Control.getControl(list));
+
+        // exceptions
+        try {
+            Control.getControl(null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        list = new ArrayList<String>();
+        try {
+            Control.getControl(list);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        list = new ArrayList<String>(FORMAT_CLASS);
+        // java.class -> JAVA.CLASS
+        list.set(0, list.get(0).toUpperCase());
+        try {
+            Control.getControl(list);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        list = new ArrayList<String>(FORMAT_CLASS);
+        list.add("");
+        try {
+            Control.getControl(list);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    /**
+     * {@link java.util.ResourceBundle.Control#getNoFallbackControl(java.util.List)}.
+     */
+    @SuppressWarnings("nls")
+    public void test_getNoFallbackControl_LList() {
+        assertNotSame(control, Control.getNoFallbackControl(FORMAT_DEFAULT));
+        assertNotSame(controlC, Control.getNoFallbackControl(FORMAT_CLASS));
+        assertNotSame(controlP, Control.getNoFallbackControl(FORMAT_PROPERTIES));
+        controlP = Control.getNoFallbackControl(FORMAT_PROPERTIES);
+        controlC = Control.getNoFallbackControl(FORMAT_CLASS);
+        control = Control.getNoFallbackControl(FORMAT_DEFAULT);
+        // singleton
+        assertSame(control, Control.getNoFallbackControl(FORMAT_DEFAULT));
+        assertSame(controlC, Control.getNoFallbackControl(FORMAT_CLASS));
+        assertSame(controlP, Control.getNoFallbackControl(FORMAT_PROPERTIES));
+
+        // class
+        assertTrue(control.getClass() != Control.class);
+        assertTrue(controlC.getClass() != Control.class);
+        assertTrue(controlP.getClass() != Control.class);
+
+        // format
+        assertEquals(FORMAT_CLASS, controlC.getFormats(""));
+        assertEquals(FORMAT_DEFAULT, control.getFormats(""));
+        assertEquals(FORMAT_PROPERTIES, controlP.getFormats(""));
+
+        // no fall back locale
+        Locale defaultLocale = Locale.getDefault();
+        Locale.setDefault(new Locale("TestLanguage", "TestCountry", "Var"));
+        assertNull(control.getFallbackLocale("message", Locale.US));
+        try {
+            control.getFallbackLocale("message", null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            control.getFallbackLocale(null, Locale.US);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        Locale.setDefault(defaultLocale);
+
+        // formats: need not same, just need equal
+        List<String> list = new ArrayList<String>(FORMAT_CLASS);
+        assertSame(controlC, Control.getNoFallbackControl(list));
+        // can add
+        list.add(FORMAT_PROPERTIES.get(0));
+        assertSame(control, Control.getNoFallbackControl(list));
+
+        // exceptions
+        try {
+            Control.getNoFallbackControl(null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        list = new ArrayList<String>();
+        try {
+            Control.getNoFallbackControl(list);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        list = new ArrayList<String>(FORMAT_CLASS);
+        // java.class -> JAVA.CLASS
+        list.set(0, list.get(0).toUpperCase());
+        try {
+            Control.getNoFallbackControl(list);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        list = new ArrayList<String>(FORMAT_CLASS);
+        list.add("");
+        try {
+            Control.getNoFallbackControl(list);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    /**
+     * {@link java.util.ResourceBundle.Control#getFormats(java.lang.String)}.
+     */
+    @SuppressWarnings("nls")
+    public void test_getFormats_LString() {
+        assertEquals(FORMAT_DEFAULT, control.getFormats(""));
+        assertEquals(FORMAT_PROPERTIES, controlP.getFormats(""));
+        assertEquals(FORMAT_CLASS, controlC.getFormats(""));
+        try {
+            controlC.getFormats(null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * {@link java.util.ResourceBundle.Control#getCandidateLocales(java.lang.String, java.util.Locale)}.
+     */
+    @SuppressWarnings("nls")
+    public void test_getCandidateLocales_LStringLLocale() {
+        // the ResourceBundle for this baseName and Locale does not exists
+        List<Locale> result = control.getCandidateLocales("baseName",
+                new Locale("one", "two", "three"));
+        assertEquals(4, result.size());
+        Locale locale = result.get(0);
+        assertEquals("one", locale.getLanguage());
+        assertEquals("TWO", locale.getCountry());
+        assertEquals("three", locale.getVariant());
+        assertEquals(new Locale("one", "TWO"), result.get(1));
+        assertEquals(new Locale("one"), result.get(2));
+        assertSame(Locale.ROOT, result.get(3));
+        // ArrayList is not immutable
+        assertTrue(ArrayList.class == result.getClass());
+
+        result = control.getCandidateLocales("baseName", new Locale("one",
+                "two", ""));
+        assertEquals(new Locale("one", "TWO"), result.get(0));
+        assertEquals(new Locale("one"), result.get(1));
+        assertSame(Locale.ROOT, result.get(2));
+
+        result = control.getCandidateLocales("baseName", new Locale("one", "",
+                "three"));
+        assertEquals(new Locale("one", "", "three"), result.get(0));
+        assertEquals(new Locale("one"), result.get(1));
+        assertSame(Locale.ROOT, result.get(2));
+
+        result = control.getCandidateLocales("baseName", new Locale("", "two",
+                "three"));
+        assertEquals(new Locale("", "TWO", "three"), result.get(0));
+        assertEquals(new Locale("", "TWO"), result.get(1));
+        assertSame(Locale.ROOT, result.get(2));
+
+        result = control.getCandidateLocales("baseName", new Locale("", "",
+                "three"));
+        assertEquals(new Locale("", "", "three"), result.get(0));
+        assertSame(Locale.ROOT, result.get(1));
+
+        result = control.getCandidateLocales("baseName", new Locale("", "two",
+                ""));
+        assertEquals(new Locale("", "TWO"), result.get(0));
+        assertSame(Locale.ROOT, result.get(1));
+
+        result = control.getCandidateLocales("baseName", Locale.ROOT);
+        assertSame(Locale.ROOT, result.get(0));
+
+        try {
+            control.getCandidateLocales(null, Locale.US);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            control.getCandidateLocales("baseName", null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * {@link java.util.ResourceBundle.Control#getFallbackLocale(java.lang.String, java.util.Locale)}.
+     */
+    @SuppressWarnings("nls")
+    public void test_getFallbackLocale_LStringLLocale() {
+        Locale defaultLocale = Locale.getDefault();
+        Locale testLocale = new Locale("TestLanguage", "TestCountry", "Var");
+        Locale.setDefault(testLocale);
+        assertSame(testLocale, control.getFallbackLocale("baseName",
+                Locale.ROOT));
+        assertSame(testLocale, control.getFallbackLocale("baseName", Locale.US));
+        assertSame(null, control.getFallbackLocale("baseName", testLocale));
+        try {
+            control.getFallbackLocale(null, Locale.US);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            control.getFallbackLocale("baseName", null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        // restore
+        Locale.setDefault(defaultLocale);
+    }
+
+    @SuppressWarnings("nls")
+    private void newBundleTester() throws IllegalAccessException,
+            InstantiationException, IOException, FileNotFoundException {
+        String className = "tests.support.Support_TestResource";
+        String propertiesName = Support_Resources.RESOURCE_PACKAGE_NAME
+                + ".hyts_resource";
+        String propertiesNameCopy = "hyts_resource_copy";
+        String CLASS = "java.class";
+        String PROPERTIES = "java.properties";
+        Locale frFR = new Locale("fr", "FR");
+        // the locale does not exist, but its parent does
+        Locale enUSVAR = new Locale("en", "US", "VAR");
+        ClassLoader systemLoader = ClassLoader.getSystemClassLoader();
+        ClassLoader URLLoader = systemLoader;
+        ResourceBundle bundle = null;
+        final URL srcFile = URLLoader.getResource(control
+                .toResourceName(control.toBundleName(propertiesName,
+                        Locale.ROOT), "properties"));
+        final File copyFile = copyFile(srcFile);
+
+        // 1. with format of "java.class"
+        bundle = control.newBundle(className, frFR, CLASS, systemLoader, false);
+        assertEquals("frFRChildValue1", bundle.getString("child1"));
+
+        bundle = control.newBundle(className, frFR, CLASS, systemLoader, true);
+        assertEquals("frFRChildValue1", bundle.getString("child1"));
+
+        bundle = control.newBundle(className, Locale.ROOT, CLASS, systemLoader,
+                false);
+        assertEquals("parentValue1", bundle.getString("parent1"));
+
+        assertNull(control.newBundle(className, frFR, CLASS, URLLoader, false));
+        assertNull(control.newBundle(className, enUSVAR, CLASS, systemLoader,
+                false));
+        assertNull(control.newBundle("wrongName", frFR, CLASS, systemLoader,
+                false));
+        assertNull(control.newBundle(className, Locale.ROOT, PROPERTIES,
+                systemLoader, false));
+
+        // 2. with format of "java.properties"
+        // if copy file exists, run the "changing" test
+        if (null != URLLoader
+                .getResourceAsStream("hyts_resource_copy.properties")) {
+            ResourceBundle.clearCache(URLLoader);
+            bundle = control.newBundle(propertiesNameCopy, Locale.ROOT,
+                    PROPERTIES, URLLoader, false);
+            assertTrue(bundle.getClass() == PropertyResourceBundle.class);
+            assertEquals("resource", bundle.getString("property"));
+            // change the file
+            changeProperties(copyFile);
+            assertEquals("resource", bundle.getString("property"));
+            bundle = control.newBundle(propertiesNameCopy, Locale.ROOT,
+                    PROPERTIES, URLLoader, false);
+            assertEquals("changedValue", bundle.getString("property"));
+            bundle = control.newBundle(propertiesNameCopy, Locale.ROOT,
+                    PROPERTIES, URLLoader, true);
+            assertEquals("changedValue", bundle.getString("property"));
+        } else {
+            System.err
+                    .println("Can not find the test file, some code of this test 'newBundleTester' did not run.");
+        }
+
+        // class loader
+        bundle = control.newBundle(propertiesName, Locale.ROOT, PROPERTIES,
+                URLLoader, true);
+        assertEquals("resource", bundle.getString("property"));
+        bundle = control.newBundle(propertiesName, Locale.ROOT, PROPERTIES,
+                systemLoader, true);
+        assertEquals("parent", bundle.getString("property"));
+
+        // locale
+        bundle = control.newBundle(propertiesName, frFR, PROPERTIES, URLLoader,
+                false);
+        assertEquals("fr_FR_resource", bundle.getString("property"));
+        assertNull(control.newBundle(propertiesName, frFR, PROPERTIES,
+                systemLoader, false));
+        assertNull(control.newBundle(propertiesName, enUSVAR, PROPERTIES,
+                systemLoader, true));
+        assertNull(control.newBundle(propertiesName, enUSVAR, PROPERTIES,
+                URLLoader, true));
+        assertNull(control.newBundle("wrongName", frFR, PROPERTIES, URLLoader,
+                false));
+
+        // exceptions
+        try {
+            control.newBundle(null, frFR, PROPERTIES, URLLoader, false);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            control.newBundle(propertiesName, null, PROPERTIES, URLLoader,
+                    false);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            control.newBundle(propertiesName, frFR, null, URLLoader, false);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            control.newBundle(propertiesName, frFR, PROPERTIES, null, false);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        // null is returned by toBundleName method
+        try {
+            new Control() {
+                @Override
+                public String toBundleName(@SuppressWarnings("unused")
+                String baseName, @SuppressWarnings("unused")
+                Locale locale) {
+                    return null;
+                }
+            }.newBundle(propertiesName, frFR, PROPERTIES, URLLoader, false);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            control.newBundle(propertiesName, frFR, "JAVA.CLASS", URLLoader,
+                    false);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            control.newBundle(this.getClass().getName(), Locale.ROOT, CLASS,
+                    systemLoader, false);
+            fail("Should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+        try {
+            control.newBundle(SubRBStaticPrivate.class.getName(), Locale.ROOT,
+                    CLASS, systemLoader, false);
+            fail("Should throw IllegalAccessException");
+        } catch (IllegalAccessException e) {
+            // expected
+        }
+        class SubRBNonStaticPrivate extends ListResourceBundle {
+            private SubRBNonStaticPrivate() {
+                super();
+            }
+
+            @Override
+            protected Object[][] getContents() {
+                return null;
+            }
+        }
+        class SubRBNonStaticPublic extends ListResourceBundle {
+            public SubRBNonStaticPublic() {
+                super();
+            }
+
+            @Override
+            protected Object[][] getContents() {
+                return null;
+            }
+        }
+    }
+
+    @SuppressWarnings("nls")
+    static File copyFile(final URL src) throws IOException {
+        String tail = src.getFile().split("hyts_resource")[1];
+        String tmpdir = System.getProperty("java.io.tmpdir");
+        if (null == tmpdir) {
+            return null;
+        }
+        String copyName = tmpdir + File.separator + "hyts_resource_copy" + tail;
+        File copy = new File(copyName);
+        if (copy.exists()) {
+            copy.delete();
+        }
+        copy.createNewFile();
+        copy.deleteOnExit();
+
+        Reader in = new InputStreamReader(src.openStream());
+        Writer out = new FileWriter(copy);
+        int c;
+        while ((c = in.read()) != -1) {
+            out.write(c);
+        }
+        in.close();
+        out.close();
+        return copy;
+    }
+
+    static class SubRBStaticPrivate extends ListResourceBundle {
+        private SubRBStaticPrivate() {
+            super();
+        }
+
+        @Override
+        protected Object[][] getContents() {
+            return null;
+        }
+    }
+
+    /*
+     * change the value in the .properties file
+     */
+    @SuppressWarnings("nls")
+    static void changeProperties(File file) throws FileNotFoundException {
+        String newValue = "property=changedValue";
+        PrintWriter writer = new PrintWriter(file);
+        writer.write(newValue);
+        writer.flush();
+        writer.close();
+        Scanner scanner = new Scanner(file);
+        assertEquals(newValue, scanner.nextLine());
+        scanner.close();
+    }
+
+    /**
+     * {@link java.util.ResourceBundle.Control#getTimeToLive(java.lang.String, java.util.Locale)}.
+     */
+    @SuppressWarnings("nls")
+    public void test_getTimeToLive_LStringLLocale() {
+        assertEquals(TTL_NO_EXPIRATION_CONTROL, control.getTimeToLive(
+                "baseName", Locale.US));
+        try {
+            control.getTimeToLive(null, Locale.US);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            control.getTimeToLive("baseName", null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @throws Exception
+     * {@link java.util.ResourceBundle.Control#needsReload(java.lang.String, java.util.Locale, java.lang.String, java.lang.ClassLoader, java.util.ResourceBundle, long)}.
+     */
+    @SuppressWarnings("nls")
+    public void test_needsReload_LStringLLocaleLStringLClassLoaderResourceBundleJ()
+            throws Exception {
+        String className = "tests.support.Support_TestResource";
+        String propertiesName = Support_Resources.RESOURCE_PACKAGE_NAME
+                + ".hyts_resource";
+        String propertiesNameCopy = "hyts_resource_copy";
+        String CLASS = "java.class";
+        String PROPERTIES = "java.properties";
+        Locale frFR = new Locale("fr", "FR");
+        ClassLoader systemLoader = ClassLoader.getSystemClassLoader();
+        ClassLoader URLLoader = systemLoader;
+        ResourceBundle bundle = null;
+        long time = 0L;
+        final URL srcFile = URLLoader.getResource(control.toResourceName(
+                control.toBundleName(propertiesName, frFR), "properties"));
+        final File copyFile = copyFile(srcFile);
+
+        // 1. format = "java.properties"
+        if (null != URLLoader
+                .getResourceAsStream("hyts_resource_copy_fr_FR.properties")) {
+            Thread.sleep(1000);
+            bundle = control.newBundle(propertiesNameCopy, frFR, PROPERTIES,
+                    URLLoader, false);
+            time = System.currentTimeMillis();
+            assertTrue(bundle.getClass() == PropertyResourceBundle.class);
+            assertEquals("fr_FR_resource", bundle.getString("property"));
+            assertFalse(control.needsReload(propertiesNameCopy, frFR,
+                    PROPERTIES, URLLoader, bundle, time));
+            // change the file
+            Thread.sleep(2000);
+            changeProperties(copyFile);
+            assertTrue(control.needsReload(propertiesNameCopy, frFR,
+                    PROPERTIES, URLLoader, bundle, time));
+            // detect again
+            assertTrue(control.needsReload(propertiesNameCopy, frFR,
+                    PROPERTIES, URLLoader, bundle, time));
+            // long long ago
+            assertTrue(control.needsReload(propertiesNameCopy, frFR,
+                    PROPERTIES, URLLoader, bundle, 2006L));
+            // other loader
+            assertFalse(control.needsReload(propertiesNameCopy, frFR,
+                    PROPERTIES, systemLoader, bundle, time));
+            // other bundle
+            ResourceBundle otherBundle = control.newBundle(propertiesName,
+                    Locale.ROOT, PROPERTIES, systemLoader, false);
+            assertEquals("parent", otherBundle.getString("property"));
+            assertTrue(control.needsReload(propertiesNameCopy, frFR,
+                    PROPERTIES, URLLoader, otherBundle, time));
+            otherBundle = control.newBundle(propertiesName, Locale.ROOT,
+                    PROPERTIES, URLLoader, false);
+            assertEquals("resource", otherBundle.getString("property"));
+            assertTrue(control.needsReload(propertiesNameCopy, frFR,
+                    PROPERTIES, URLLoader, otherBundle, time));
+            // other time
+            assertFalse(control.needsReload(propertiesNameCopy, frFR,
+                    PROPERTIES, URLLoader, bundle, System.currentTimeMillis()));
+        } else {
+            System.err
+                    .println("Can not find the test file, some code of this test 'test_needsReload_LStringLLocaleLStringLClassLoaderResourceBundleJ' did not run.");
+
+        }
+
+        // 2. format = "java.class"
+        bundle = control.newBundle(className, frFR, CLASS, systemLoader, false);
+        time = System.currentTimeMillis();
+        assertEquals("frFRValue3", bundle.getString("parent3"));
+        assertFalse(control.needsReload(className, frFR, CLASS, systemLoader,
+                bundle, time));
+        // exceptions
+        control.needsReload(propertiesName, frFR, PROPERTIES, URLLoader,
+                bundle, time);
+        try {
+            control
+                    .needsReload(null, frFR, PROPERTIES, URLLoader, bundle,
+                            time);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            control.needsReload(propertiesName, null, PROPERTIES, URLLoader,
+                    bundle, time);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            control.needsReload(propertiesName, frFR, null, URLLoader, bundle,
+                    time);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            control.needsReload(propertiesName, frFR, PROPERTIES, null, bundle,
+                    time);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            control.needsReload(propertiesName, frFR, PROPERTIES, URLLoader,
+                    null, time);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * {@link java.util.ResourceBundle.Control#toBundleName(java.lang.String, java.util.Locale)}.
+     */
+    @SuppressWarnings("nls")
+    public void test_toBundleName_LStringLLocale() {
+        assertEquals("baseName_one_TWO_three", control.toBundleName("baseName",
+                new Locale("one", "two", "three")));
+        assertEquals("baseName_one_TWO", control.toBundleName("baseName",
+                new Locale("one", "two")));
+        assertEquals("baseName_one__three", control.toBundleName("baseName",
+                new Locale("one", "", "three")));
+        assertEquals("baseName__TWO_three", control.toBundleName("baseName",
+                new Locale("", "two", "three")));
+        assertEquals("baseName_one", control.toBundleName("baseName",
+                new Locale("one", "", "")));
+        assertEquals("baseName___three", control.toBundleName("baseName",
+                new Locale("", "", "three")));
+        assertEquals("baseName__TWO", control.toBundleName("baseName",
+                new Locale("", "two", "")));
+        assertEquals("baseName", control.toBundleName("baseName", new Locale(
+                "", "", "")));
+        assertEquals("baseName", control.toBundleName("baseName", Locale.ROOT));
+        assertEquals("_one_TWO_three", control.toBundleName("", new Locale(
+                "one", "two", "three")));
+        assertEquals("", control.toBundleName("", Locale.ROOT));
+
+        assertEquals("does.not.exists_one_TWO_three", control.toBundleName(
+                "does.not.exists", new Locale("one", "two", "three")));
+        assertEquals("does/not/exists_one_TWO_three", control.toBundleName(
+                "does/not/exists", new Locale("one", "two", "three")));
+        assertEquals("does_not_exists__one_TWO_three", control.toBundleName(
+                "does_not_exists_", new Locale("one", "two", "three")));
+
+        assertEquals("...", control.toBundleName("...", Locale.ROOT));
+        assertEquals("s/./\\//g", control
+                .toBundleName("s/./\\//g", Locale.ROOT));
+        assertEquals("123_one", control.toBundleName("123", new Locale("one")));
+
+        try {
+            control.toBundleName(null, Locale.US);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            control.toBundleName("baseName", null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * {@link java.util.ResourceBundle.Control#toResourceName(java.lang.String, java.lang.String)}.
+     */
+    @SuppressWarnings("nls")
+    public void test_toResourceNameLStringLString() {
+        assertEquals("does/not/exists_language_country.someSuffix", control
+                .toResourceName("does.not.exists_language_country",
+                        "someSuffix"));
+        assertEquals("does/not/exists_language_country.someSuffix", control
+                .toResourceName("does/not/exists_language_country",
+                        "someSuffix"));
+        assertEquals("does///not//exists_language/country.someSuffix", control
+                .toResourceName("does...not..exists_language.country",
+                        "someSuffix"));
+        assertEquals("does\\not\\exists_language_country.someSuffix", control
+                .toResourceName("does\\not\\exists_language_country",
+                        "someSuffix"));
+        assertEquals("does/not/exists_language_country/.someSuffix", control
+                .toResourceName("does.not.exists_language_country.",
+                        "someSuffix"));
+        assertEquals("does/not/exists_language_country../someSuffix", control
+                .toResourceName("does.not.exists_language_country",
+                        "./someSuffix"));
+
+        assertEquals("///.//", control.toResourceName("...", "//"));
+        assertEquals("///...", control.toResourceName("///", ".."));
+        assertEquals("123...", control.toResourceName("123", ".."));
+        assertEquals("base.", control.toResourceName("base", ""));
+        assertEquals(".suffix", control.toResourceName("", "suffix"));
+        assertEquals(".", control.toResourceName("", ""));
+
+        try {
+            control.toResourceName(null, "suffix");
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            control.toResourceName("bundleName", null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+    }
+
+    /**
+     * @throws java.lang.Exception
+     */
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * @throws java.lang.Exception
+     */
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        controlP = Control.getControl(FORMAT_PROPERTIES);
+        controlC = Control.getControl(FORMAT_CLASS);
+        control = Control.getControl(FORMAT_DEFAULT);
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/util/DuplicateFormatFlagsExceptionTest.java b/luni/src/test/java/tests/api/java/util/DuplicateFormatFlagsExceptionTest.java
new file mode 100644
index 0000000..0fd0005
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/DuplicateFormatFlagsExceptionTest.java
@@ -0,0 +1,94 @@
+/* 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.util;
+
+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;
+
+public class DuplicateFormatFlagsExceptionTest extends TestCase {
+
+    /**
+     * java.util.DuplicateFormatFlagsException#DuplicateFormatFlagsException(String)
+     */
+    public void test_duplicateFormatFlagsException() {
+        try {
+            new DuplicateFormatFlagsException(null);
+            fail("should throw NullPointerException.");
+        } catch (NullPointerException e) {
+            // desired
+        }
+    }
+
+    /**
+     * java.util.DuplicateFormatFlagsException#getFlags()
+     */
+    public void test_getFlags() {
+        String strFlags = "MYTESTFLAGS";
+        DuplicateFormatFlagsException duplicateFormatException = new DuplicateFormatFlagsException(
+                strFlags);
+        assertEquals(strFlags, duplicateFormatException.getFlags());
+    }
+
+    /**
+     * java.util.DuplicateFormatFlagsException#getMessage()
+     */
+    public void test_getMessage() {
+        String strFlags = "MYTESTFLAGS";
+        DuplicateFormatFlagsException duplicateFormatException = new DuplicateFormatFlagsException(
+                strFlags);
+        assertTrue(null != duplicateFormatException.getFlags());
+
+    }
+
+    // comparator for DuplicateFormatFlagsException objects
+    private static final SerializableAssert exComparator = new SerializableAssert() {
+        public void assertDeserialized(Serializable initial,
+                Serializable deserialized) {
+
+            SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+                    deserialized);
+
+            DuplicateFormatFlagsException initEx = (DuplicateFormatFlagsException) initial;
+            DuplicateFormatFlagsException desrEx = (DuplicateFormatFlagsException) deserialized;
+
+            assertEquals("Flags", initEx.getFlags(), desrEx.getFlags());
+        }
+    };
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        SerializationTest.verifySelf(new DuplicateFormatFlagsException(
+                "TESTDESC"), exComparator);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        SerializationTest.verifyGolden(this, new DuplicateFormatFlagsException(
+                "TESTDESC"), exComparator);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/EventObjectTest.java b/luni/src/test/java/tests/api/java/util/EventObjectTest.java
new file mode 100644
index 0000000..0f00a81
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/EventObjectTest.java
@@ -0,0 +1,70 @@
+/*
+ *  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.util;
+
+import java.util.EventObject;
+
+public class EventObjectTest extends junit.framework.TestCase {
+
+    Object myObject;
+
+    EventObject myEventObject;
+
+    /**
+     * java.util.EventObject#EventObject(java.lang.Object)
+     */
+    public void test_ConstructorLjava_lang_Object() {
+        // Test for method java.util.EventObject(java.lang.Object)
+        assertTrue("Used to test", true);
+    }
+
+    /**
+     * java.util.EventObject#getSource()
+     */
+    public void test_getSource() {
+        // Test for method java.lang.Object java.util.EventObject.getSource()
+        assertTrue("Wrong source returned",
+                myEventObject.getSource() == myObject);
+    }
+
+    /**
+     * java.util.EventObject#toString()
+     */
+    public void test_toString() {
+        // Test for method java.lang.String java.util.EventObject.toString()
+        assertTrue("Incorrect toString returned: " + myEventObject.toString(),
+                myEventObject.toString().indexOf(
+                        "java.util.EventObject[source=java.lang.Object@") == 0);
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() {
+        myObject = new Object();
+        myEventObject = new EventObject(myObject);
+    }
+
+    /**
+     * 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/tests/api/java/util/FormatFlagsConversionMismatchExceptionTest.java b/luni/src/test/java/tests/api/java/util/FormatFlagsConversionMismatchExceptionTest.java
new file mode 100644
index 0000000..decf452
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/FormatFlagsConversionMismatchExceptionTest.java
@@ -0,0 +1,115 @@
+/* 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.util;
+
+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;
+
+public class FormatFlagsConversionMismatchExceptionTest extends TestCase {
+
+    /**
+     * java.util.FormatFlagsConversionMismatchException#FormatFlagsConversionMismatchException(String,
+     *char)
+     */
+    public void test_formatFlagsConversionMismatchException() {
+        try {
+            new FormatFlagsConversionMismatchException(null, ' ');
+            fail("should throw NullPointerException.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+    }
+
+    /**
+     * java.util.FormatFlagsConversionMismatchException#getFlags()
+     */
+    public void test_getFlags() {
+        String flags = "MYTESTFLAGS";
+        char conversion = 'T';
+        FormatFlagsConversionMismatchException formatFlagsConversionMismatchException = new FormatFlagsConversionMismatchException(
+                flags, conversion);
+        assertEquals(flags, formatFlagsConversionMismatchException.getFlags());
+    }
+
+    /**
+     * java.util.FormatFlagsConversionMismatchException#getConversion()
+     */
+    public void test_getConversion() {
+        String flags = "MYTESTFLAGS";
+        char conversion = 'T';
+        FormatFlagsConversionMismatchException formatFlagsConversionMismatchException = new FormatFlagsConversionMismatchException(
+                flags, conversion);
+        assertEquals(conversion, formatFlagsConversionMismatchException
+                .getConversion());
+
+    }
+
+    /**
+     * java.util.FormatFlagsConversionMismatchException#getMessage()
+     */
+    public void test_getMessage() {
+        String flags = "MYTESTFLAGS";
+        char conversion = 'T';
+        FormatFlagsConversionMismatchException formatFlagsConversionMismatchException = new FormatFlagsConversionMismatchException(
+                flags, conversion);
+        assertTrue(null != formatFlagsConversionMismatchException.getMessage());
+
+    }
+
+    // comparator for FormatFlagsConversionMismatchException objects
+    private static final SerializableAssert exComparator = new SerializableAssert() {
+        public void assertDeserialized(Serializable initial,
+                Serializable deserialized) {
+
+            SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+                    deserialized);
+
+            FormatFlagsConversionMismatchException initEx = (FormatFlagsConversionMismatchException) initial;
+            FormatFlagsConversionMismatchException desrEx = (FormatFlagsConversionMismatchException) deserialized;
+
+            assertEquals("Flags", initEx.getFlags(), desrEx.getFlags());
+            assertEquals("Conversion", initEx.getConversion(), desrEx
+                    .getConversion());
+        }
+    };
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        SerializationTest.verifySelf(
+                new FormatFlagsConversionMismatchException("MYTESTFLAGS", 'T'),
+                exComparator);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        SerializationTest.verifyGolden(this,
+                new FormatFlagsConversionMismatchException("MYTESTFLAGS", 'T'),
+                exComparator);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/FormatterClosedExceptionTest.java b/luni/src/test/java/tests/api/java/util/FormatterClosedExceptionTest.java
new file mode 100644
index 0000000..9d11f70
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/FormatterClosedExceptionTest.java
@@ -0,0 +1,42 @@
+/* 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.util;
+
+import java.util.FormatterClosedException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class FormatterClosedExceptionTest extends TestCase {
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        SerializationTest.verifySelf(new FormatterClosedException());
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        SerializationTest.verifyGolden(this, new FormatterClosedException());
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/FormatterTest.java b/luni/src/test/java/tests/api/java/util/FormatterTest.java
new file mode 100644
index 0000000..c6f7577
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/FormatterTest.java
@@ -0,0 +1,4244 @@
+/* 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.util;
+
+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;
+
+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 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;
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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
+            }
+        }
+    }
+
+    /**
+     * 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
+            }
+        }
+    }
+
+    /**
+     * 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
+            }
+        }
+    }
+
+    /**
+     * 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
+            }
+        }
+    }
+
+    /**
+     * 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
+            }
+        }
+
+        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());
+            }
+        }
+    }
+
+    /**
+     * 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
+            }
+        }
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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
+        }
+    }
+
+    /**
+     * 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
+        }
+
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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
+        }
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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");
+        try {
+            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());
+        } finally {
+            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);
+    }
+
+    /**
+     * 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
+        }
+    }
+
+    /**
+     * 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
+            }
+        }
+    }
+
+    /**
+     * 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());
+        }
+    }
+
+    /**
+     * 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());
+        }
+    }
+
+    /**
+     * 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());
+        }
+    }
+
+    /**
+     * 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());
+            }
+        }
+    }
+
+    /**
+     * 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
+        }
+    }
+
+    /**
+     * 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());
+    }
+
+
+    /**
+     * 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());
+        }
+    }
+
+    /**
+     * 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());
+        }
+    }
+
+    /**
+     * 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());
+        }
+    }
+
+    /**
+     * 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$
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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
+        }
+    }
+
+    /**
+     * 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 {
+            f.format("%(o", false);
+            fail();
+        } catch (FormatFlagsConversionMismatchException expected) {
+        } catch (IllegalFormatConversionException expected) {
+        }
+
+        try {
+            f.format("%.4o", false);
+            fail();
+        } catch (IllegalFormatPrecisionException expected) {
+        } catch (IllegalFormatConversionException expected) {
+        }
+
+        try {
+            f.format("%+ .4o", big);
+            fail();
+        } catch (IllegalFormatPrecisionException expected) {
+        } catch (IllegalFormatFlagsException expected) {
+        }
+
+        try {
+            f.format("%+ -o", big);
+            fail();
+        } catch (MissingFormatWidthException expected) {
+        } catch (IllegalFormatFlagsException expected) {
+        }
+
+        try {
+            f.format("%-O", big);
+            fail();
+        } catch (MissingFormatWidthException expected) {
+        } catch (UnknownFormatConversionException expected) {
+        }
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+        }
+    }
+
+    /**
+     * 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());
+        }
+    }
+
+    /**
+     * 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());
+        }
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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
+        }
+    }
+
+    /**
+     * 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
+        }
+    }
+
+    /**
+     * 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
+        }
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * java.util.Formatter.BigDecimalLayoutForm#values()
+     */
+    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]);
+    }
+
+    /**
+     * java.util.Formatter.BigDecimalLayoutForm#valueOf(String)
+     */
+    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);
+
+        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/tests/api/java/util/GregorianCalendarTest.java b/luni/src/test/java/tests/api/java/util/GregorianCalendarTest.java
new file mode 100644
index 0000000..8b943ed
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/GregorianCalendarTest.java
@@ -0,0 +1,775 @@
+/*
+ *  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.util;
+
+import java.util.BitSet;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.SimpleTimeZone;
+import java.util.TimeZone;
+import java.util.Vector;
+
+public class GregorianCalendarTest extends junit.framework.TestCase {
+
+    private static final TimeZone AMERICA_CHICAGO = TimeZone.getTimeZone("America/Chicago");
+    private static final TimeZone AMERICA_NEW_YORK = TimeZone.getTimeZone("America/New_York");
+
+    /**
+     * java.util.GregorianCalendar#GregorianCalendar()
+     */
+    public void test_Constructor() {
+        // Test for method java.util.GregorianCalendar()
+        assertTrue("Constructed incorrect calendar", (new GregorianCalendar()
+                .isLenient()));
+    }
+
+    /**
+     * java.util.GregorianCalendar#GregorianCalendar(int, int, int)
+     */
+    public void test_ConstructorIII() {
+        // Test for method java.util.GregorianCalendar(int, int, int)
+        GregorianCalendar gc = new GregorianCalendar(1972, Calendar.OCTOBER, 13);
+        assertEquals("Incorrect calendar constructed 1",
+                1972, gc.get(Calendar.YEAR));
+        assertTrue("Incorrect calendar constructed 2",
+                gc.get(Calendar.MONTH) == Calendar.OCTOBER);
+        assertEquals("Incorrect calendar constructed 3", 13, gc
+                .get(Calendar.DAY_OF_MONTH));
+        assertTrue("Incorrect calendar constructed 4", gc.getTimeZone().equals(
+                TimeZone.getDefault()));
+    }
+
+    /**
+     * java.util.GregorianCalendar#GregorianCalendar(int, int, int, int,
+     *int)
+     */
+    public void test_ConstructorIIIII() {
+        // Test for method java.util.GregorianCalendar(int, int, int, int, int)
+        GregorianCalendar gc = new GregorianCalendar(1972, Calendar.OCTOBER,
+                13, 19, 9);
+        assertEquals("Incorrect calendar constructed",
+                1972, gc.get(Calendar.YEAR));
+        assertTrue("Incorrect calendar constructed",
+                gc.get(Calendar.MONTH) == Calendar.OCTOBER);
+        assertEquals("Incorrect calendar constructed", 13, gc
+                .get(Calendar.DAY_OF_MONTH));
+        assertEquals("Incorrect calendar constructed", 7, gc.get(Calendar.HOUR));
+        assertEquals("Incorrect calendar constructed",
+                1, gc.get(Calendar.AM_PM));
+        assertEquals("Incorrect calendar constructed",
+                9, gc.get(Calendar.MINUTE));
+        assertTrue("Incorrect calendar constructed", gc.getTimeZone().equals(
+                TimeZone.getDefault()));
+
+        //Regression for HARMONY-998
+        gc = new GregorianCalendar(1900, 0, 0, 0, Integer.MAX_VALUE);
+        assertEquals("Incorrect calendar constructed",
+                5983, gc.get(Calendar.YEAR));
+    }
+
+    /**
+     * java.util.GregorianCalendar#GregorianCalendar(int, int, int, int,
+     *int, int)
+     */
+    public void test_ConstructorIIIIII() {
+        // Test for method java.util.GregorianCalendar(int, int, int, int, int,
+        // int)
+        GregorianCalendar gc = new GregorianCalendar(1972, Calendar.OCTOBER,
+                13, 19, 9, 59);
+        assertEquals("Incorrect calendar constructed",
+                1972, gc.get(Calendar.YEAR));
+        assertTrue("Incorrect calendar constructed",
+                gc.get(Calendar.MONTH) == Calendar.OCTOBER);
+        assertEquals("Incorrect calendar constructed", 13, gc
+                .get(Calendar.DAY_OF_MONTH));
+        assertEquals("Incorrect calendar constructed", 7, gc.get(Calendar.HOUR));
+        assertEquals("Incorrect calendar constructed",
+                1, gc.get(Calendar.AM_PM));
+        assertEquals("Incorrect calendar constructed",
+                9, gc.get(Calendar.MINUTE));
+        assertEquals("Incorrect calendar constructed",
+                59, gc.get(Calendar.SECOND));
+        assertTrue("Incorrect calendar constructed", gc.getTimeZone().equals(
+                TimeZone.getDefault()));
+    }
+
+    /**
+     * java.util.GregorianCalendar#GregorianCalendar(java.util.Locale)
+     */
+    public void test_ConstructorLjava_util_Locale() {
+        // Test for method java.util.GregorianCalendar(java.util.Locale)
+        Date date = new Date();
+        GregorianCalendar gcJapan = new GregorianCalendar(Locale.JAPAN);
+        gcJapan.setTime(date);
+        GregorianCalendar gcJapan2 = new GregorianCalendar(Locale.JAPAN);
+        gcJapan2.setTime(date);
+        GregorianCalendar gcItaly = new GregorianCalendar(Locale.ITALY);
+        gcItaly.setTime(date);
+        assertTrue("Locales not created correctly", gcJapan.equals(gcJapan2)
+                && !gcJapan.equals(gcItaly));
+    }
+
+    /**
+     * java.util.GregorianCalendar#GregorianCalendar(java.util.TimeZone)
+     */
+    public void test_ConstructorLjava_util_TimeZone() {
+        // Test for method java.util.GregorianCalendar(java.util.TimeZone)
+        Date date = new Date(2008, 1, 1);
+        TimeZone.getDefault();
+        GregorianCalendar gc1 = new GregorianCalendar(AMERICA_NEW_YORK);
+        gc1.setTime(date);
+        GregorianCalendar gc2 = new GregorianCalendar(AMERICA_CHICAGO);
+        gc2.setTime(date);
+        // Chicago is 1 hour before New York, add 1 to the Chicago time and convert to 0-12 value
+        assertEquals("Incorrect calendar returned",
+                gc1.get(Calendar.HOUR), ((gc2.get(Calendar.HOUR) + 1) % 12));
+
+        // Regression test for HARMONY-2961
+        SimpleTimeZone timezone = new SimpleTimeZone(-3600 * 24 * 1000 * 2,
+                "GMT");
+        GregorianCalendar gc = new GregorianCalendar(timezone);
+
+        // Regression test for HARMONY-5195
+        Calendar c1 = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
+        c1.set(Calendar.YEAR, 1999);
+        c1.set(Calendar.MONTH, Calendar.JUNE);
+        c1.set(Calendar.DAY_OF_MONTH, 2);
+        c1.set(Calendar.HOUR, 15);
+        c1.set(Calendar.MINUTE, 34);
+        c1.set(Calendar.SECOND, 16);
+        assertEquals(34, c1.get(Calendar.MINUTE));
+        c1.setTimeZone(new SimpleTimeZone(60000, "ONE MINUTE"));
+        assertEquals(35, c1.get(Calendar.MINUTE));
+
+    }
+
+    /**
+     * java.util.GregorianCalendar#GregorianCalendar(java.util.TimeZone,
+     *java.util.Locale)
+     */
+    public void test_ConstructorLjava_util_TimeZoneLjava_util_Locale() {
+        // Test for method java.util.GregorianCalendar(java.util.TimeZone,
+        // java.util.Locale)
+        Date date = new Date(2008, 1, 1);
+        TimeZone.getDefault();
+        GregorianCalendar gc1 = new GregorianCalendar(AMERICA_NEW_YORK, Locale.JAPAN);
+        gc1.setTime(date);
+        GregorianCalendar gc2 = new GregorianCalendar(AMERICA_NEW_YORK, Locale.JAPAN);
+        gc2.setTime(date);
+        GregorianCalendar gc3 = new GregorianCalendar(AMERICA_CHICAGO, Locale.ITALY);
+        gc3.setTime(date);
+        // Chicago is 1 hour before New York, add 1 to the Chicago time and convert to 0-12 value
+        assertEquals("Incorrect calendar returned",
+                gc1.get(Calendar.HOUR), ((gc3.get(Calendar.HOUR) + 1) % 12));
+        assertTrue("Locales not created correctly", gc1.equals(gc2)
+                && !gc1.equals(gc3));
+    }
+
+    /**
+     * java.util.GregorianCalendar#add(int, int)
+     */
+    public void test_addII() {
+        // Test for method void java.util.GregorianCalendar.add(int, int)
+        GregorianCalendar gc1 = new GregorianCalendar(1998, 11, 6);
+        gc1.add(GregorianCalendar.YEAR, 1);
+        assertEquals("Add failed to Increment",
+                1999, gc1.get(GregorianCalendar.YEAR));
+
+        gc1 = new GregorianCalendar(1999, Calendar.JULY, 31);
+        gc1.add(Calendar.MONTH, 7);
+        assertEquals("Wrong result year 1", 2000, gc1.get(Calendar.YEAR));
+        assertTrue("Wrong result month 1",
+                gc1.get(Calendar.MONTH) == Calendar.FEBRUARY);
+        assertEquals("Wrong result date 1", 29, gc1.get(Calendar.DATE));
+
+        gc1.add(Calendar.YEAR, -1);
+        assertEquals("Wrong result year 2", 1999, gc1.get(Calendar.YEAR));
+        assertTrue("Wrong result month 2",
+                gc1.get(Calendar.MONTH) == Calendar.FEBRUARY);
+        assertEquals("Wrong result date 2", 28, gc1.get(Calendar.DATE));
+
+        gc1 = new GregorianCalendar(AMERICA_NEW_YORK);
+        gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+        gc1.add(Calendar.MILLISECOND, 24 * 60 * 60 * 1000);
+        assertEquals("Wrong time after MILLISECOND change", 16, gc1
+                .get(Calendar.HOUR_OF_DAY));
+        gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+        gc1.add(Calendar.SECOND, 24 * 60 * 60);
+        assertEquals("Wrong time after SECOND change", 16, gc1
+                .get(Calendar.HOUR_OF_DAY));
+        gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+        gc1.add(Calendar.MINUTE, 24 * 60);
+        assertEquals("Wrong time after MINUTE change", 16, gc1
+                .get(Calendar.HOUR_OF_DAY));
+        gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+        gc1.add(Calendar.HOUR, 24);
+        assertEquals("Wrong time after HOUR change", 16, gc1
+                .get(Calendar.HOUR_OF_DAY));
+        gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+        gc1.add(Calendar.HOUR_OF_DAY, 24);
+        assertEquals("Wrong time after HOUR_OF_DAY change", 16, gc1
+                .get(Calendar.HOUR_OF_DAY));
+
+        gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+        gc1.add(Calendar.AM_PM, 2);
+        assertEquals("Wrong time after AM_PM change", 16, gc1
+                .get(Calendar.HOUR_OF_DAY));
+        gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+        gc1.add(Calendar.DATE, 1);
+        assertEquals("Wrong time after DATE change", 16, gc1
+                .get(Calendar.HOUR_OF_DAY));
+        gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+        gc1.add(Calendar.DAY_OF_YEAR, 1);
+        assertEquals("Wrong time after DAY_OF_YEAR change", 16, gc1
+                .get(Calendar.HOUR_OF_DAY));
+        gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+        gc1.add(Calendar.DAY_OF_WEEK, 1);
+        assertEquals("Wrong time after DAY_OF_WEEK change", 16, gc1
+                .get(Calendar.HOUR_OF_DAY));
+        gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+        gc1.add(Calendar.WEEK_OF_YEAR, 1);
+        assertEquals("Wrong time after WEEK_OF_YEAR change", 16, gc1
+                .get(Calendar.HOUR_OF_DAY));
+        gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+        gc1.add(Calendar.WEEK_OF_MONTH, 1);
+        assertEquals("Wrong time after WEEK_OF_MONTH change", 16, gc1
+                .get(Calendar.HOUR_OF_DAY));
+        gc1.set(1999, Calendar.APRIL, 3, 16, 0); // day before DST change
+        gc1.add(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
+        assertEquals("Wrong time after DAY_OF_WEEK_IN_MONTH change", 16, gc1
+                .get(Calendar.HOUR_OF_DAY));
+
+        gc1.clear();
+        gc1.set(2000, Calendar.APRIL, 1, 23, 0);
+        gc1.add(Calendar.DATE, 1);
+        assertTrue("Wrong time after DATE change near DST boundary", gc1
+                .get(Calendar.MONTH) == Calendar.APRIL
+                && gc1.get(Calendar.DATE) == 2
+                && gc1.get(Calendar.HOUR_OF_DAY) == 23);
+    }
+
+    /**
+     * java.util.GregorianCalendar#equals(java.lang.Object)
+     */
+    public void test_equalsLjava_lang_Object() {
+        // Test for method boolean
+        // java.util.GregorianCalendar.equals(java.lang.Object)
+        GregorianCalendar gc1 = new GregorianCalendar(1998, 11, 6);
+        GregorianCalendar gc2 = new GregorianCalendar(2000, 11, 6);
+        GregorianCalendar gc3 = new GregorianCalendar(1998, 11, 6);
+        assertTrue("Equality check failed", gc1.equals(gc3));
+        assertTrue("Equality check failed", !gc1.equals(gc2));
+        gc3.setGregorianChange(new Date());
+        assertTrue("Different gregorian change", !gc1.equals(gc3));
+    }
+
+    /**
+     * java.util.GregorianCalendar#getActualMaximum(int)
+     */
+    public void test_getActualMaximumI() {
+        // Test for method int java.util.GregorianCalendar.getActualMaximum(int)
+        GregorianCalendar gc1 = new GregorianCalendar(1900, 1, 1);
+        GregorianCalendar gc2 = new GregorianCalendar(1996, 1, 1);
+        GregorianCalendar gc3 = new GregorianCalendar(1997, 1, 1);
+        GregorianCalendar gc4 = new GregorianCalendar(2000, 1, 1);
+        GregorianCalendar gc5 = new GregorianCalendar(2000, 9, 9);
+        GregorianCalendar gc6 = new GregorianCalendar(2000, 3, 3);
+        assertEquals("Wrong actual maximum value for DAY_OF_MONTH for Feb 1900",
+                28, gc1.getActualMaximum(Calendar.DAY_OF_MONTH));
+        assertEquals("Wrong actual maximum value for DAY_OF_MONTH for Feb 1996",
+                29, gc2.getActualMaximum(Calendar.DAY_OF_MONTH));
+        assertEquals("Wrong actual maximum value for DAY_OF_MONTH for Feb 1998",
+                28, gc3.getActualMaximum(Calendar.DAY_OF_MONTH));
+        assertEquals("Wrong actual maximum value for DAY_OF_MONTH for Feb 2000",
+                29, gc4.getActualMaximum(Calendar.DAY_OF_MONTH));
+        assertEquals("Wrong actual maximum value for DAY_OF_MONTH for Oct 2000",
+                31, gc5.getActualMaximum(Calendar.DAY_OF_MONTH));
+        assertEquals("Wrong actual maximum value for DAY_OF_MONTH for Apr 2000",
+                30, gc6.getActualMaximum(Calendar.DAY_OF_MONTH));
+        assertTrue("Wrong actual maximum value for MONTH", gc1
+                .getActualMaximum(Calendar.MONTH) == Calendar.DECEMBER);
+        assertEquals("Wrong actual maximum value for HOUR_OF_DAY", 23, gc1
+                .getActualMaximum(Calendar.HOUR_OF_DAY));
+        assertEquals("Wrong actual maximum value for HOUR", 11, gc1
+                .getActualMaximum(Calendar.HOUR));
+        assertEquals("Wrong actual maximum value for DAY_OF_WEEK_IN_MONTH", 4, gc6
+                .getActualMaximum(Calendar.DAY_OF_WEEK_IN_MONTH));
+
+
+        // Regression test for harmony 2954
+        Date date = new Date(Date.parse("Jan 15 00:00:01 GMT 2000"));
+        GregorianCalendar gc = new GregorianCalendar();
+        gc.setTimeInMillis(Date.parse("Dec 15 00:00:01 GMT 1582"));
+        assertEquals(355, gc.getActualMaximum(Calendar.DAY_OF_YEAR));
+        gc.setGregorianChange(date);
+        gc.setTimeInMillis(Date.parse("Jan 16 00:00:01 GMT 2000"));
+        assertEquals(353, gc.getActualMaximum(Calendar.DAY_OF_YEAR));
+
+        //Regression test for HARMONY-3004
+        gc = new GregorianCalendar(1900, 7, 1);
+        String[] ids = TimeZone.getAvailableIDs();
+        for (int i = 0; i < ids.length; i++) {
+            TimeZone tz = TimeZone.getTimeZone(ids[i]);
+            gc.setTimeZone(tz);
+            for (int j = 1900; j < 2000; j++) {
+                gc.set(Calendar.YEAR, j);
+                assertEquals(7200000, gc.getActualMaximum(Calendar.DST_OFFSET));
+            }
+        }
+    }
+
+    /**
+     * java.util.GregorianCalendar#getActualMinimum(int)
+     */
+    public void test_getActualMinimumI() {
+        // Test for method int java.util.GregorianCalendar.getActualMinimum(int)
+        GregorianCalendar gc1 = new GregorianCalendar(1900, 1, 1);
+        new GregorianCalendar(1996, 1, 1);
+        new GregorianCalendar(1997, 1, 1);
+        new GregorianCalendar(2000, 1, 1);
+        new GregorianCalendar(2000, 9, 9);
+        GregorianCalendar gc6 = new GregorianCalendar(2000, 3, 3);
+        assertEquals("Wrong actual minimum value for DAY_OF_MONTH for Feb 1900",
+                1, gc1.getActualMinimum(Calendar.DAY_OF_MONTH));
+        assertTrue("Wrong actual minimum value for MONTH", gc1
+                .getActualMinimum(Calendar.MONTH) == Calendar.JANUARY);
+        assertEquals("Wrong actual minimum value for HOUR_OF_DAY", 0, gc1
+                .getActualMinimum(Calendar.HOUR_OF_DAY));
+        assertEquals("Wrong actual minimum value for HOUR", 0, gc1
+                .getActualMinimum(Calendar.HOUR));
+        assertEquals("Wrong actual minimum value for DAY_OF_WEEK_IN_MONTH", 1, gc6
+                .getActualMinimum(Calendar.DAY_OF_WEEK_IN_MONTH));
+    }
+
+    /**
+     * java.util.GregorianCalendar#getGreatestMinimum(int)
+     */
+    public void test_getGreatestMinimumI() {
+        // Test for method int
+        // java.util.GregorianCalendar.getGreatestMinimum(int)
+        GregorianCalendar gc = new GregorianCalendar();
+        assertEquals("Wrong greatest minimum value for DAY_OF_MONTH", 1, gc
+                .getGreatestMinimum(Calendar.DAY_OF_MONTH));
+        assertTrue("Wrong greatest minimum value for MONTH", gc
+                .getGreatestMinimum(Calendar.MONTH) == Calendar.JANUARY);
+        assertEquals("Wrong greatest minimum value for HOUR_OF_DAY", 0, gc
+                .getGreatestMinimum(Calendar.HOUR_OF_DAY));
+        assertEquals("Wrong greatest minimum value for HOUR", 0, gc
+                .getGreatestMinimum(Calendar.HOUR));
+
+        BitSet result = new BitSet();
+        int[] min = { 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, -46800000,
+                0 };
+        for (int i = 0; i < min.length; i++) {
+            if (gc.getGreatestMinimum(i) != min[i])
+                result.set(i);
+        }
+        assertTrue("Wrong greatest min for " + result, result.length() == 0);
+    }
+
+    /**
+     * java.util.GregorianCalendar#getGregorianChange()
+     */
+    public void test_getGregorianChange() {
+        // Test for method java.util.Date
+        // java.util.GregorianCalendar.getGregorianChange()
+        GregorianCalendar gc = new GregorianCalendar();
+        GregorianCalendar returnedChange = new GregorianCalendar(AMERICA_NEW_YORK);
+        returnedChange.setTime(gc.getGregorianChange());
+        assertEquals("Returned incorrect year",
+                1582, returnedChange.get(Calendar.YEAR));
+        assertTrue("Returned incorrect month", returnedChange
+                .get(Calendar.MONTH) == Calendar.OCTOBER);
+        assertEquals("Returned incorrect day of month", 4, returnedChange
+                .get(Calendar.DAY_OF_MONTH));
+    }
+
+    /**
+     * java.util.GregorianCalendar#getLeastMaximum(int)
+     */
+    public void test_getLeastMaximumI() {
+        // Test for method int java.util.GregorianCalendar.getLeastMaximum(int)
+        GregorianCalendar gc = new GregorianCalendar();
+        assertEquals("Wrong least maximum value for DAY_OF_MONTH", 28, gc
+                .getLeastMaximum(Calendar.DAY_OF_MONTH));
+        assertTrue("Wrong least maximum value for MONTH", gc
+                .getLeastMaximum(Calendar.MONTH) == Calendar.DECEMBER);
+        assertEquals("Wrong least maximum value for HOUR_OF_DAY", 23, gc
+                .getLeastMaximum(Calendar.HOUR_OF_DAY));
+        assertEquals("Wrong least maximum value for HOUR", 11, gc
+                .getLeastMaximum(Calendar.HOUR));
+
+        BitSet result = new BitSet();
+        Vector values = new Vector();
+        int[] max = { 1, 292269054, 11, 50, 3, 28, 355, 7, 3, 1, 11, 23, 59,
+                59, 999, 50400000, 1200000 };
+        for (int i = 0; i < max.length; i++) {
+            if (gc.getLeastMaximum(i) != max[i]) {
+                result.set(i);
+                values.add(new Integer(gc.getLeastMaximum(i)));
+            }
+        }
+        assertTrue("Wrong least max for " + result + " = " + values, result
+                .length() == 0);
+
+        // Regression test for harmony-2947
+        Date date = new Date(Date.parse("Jan 1 00:00:01 GMT 2000"));
+        gc = new GregorianCalendar();
+        gc.setGregorianChange(date);
+        gc.setTime(date);
+        assertEquals(gc.getActualMaximum(Calendar.WEEK_OF_YEAR), gc
+                .getLeastMaximum(Calendar.WEEK_OF_YEAR));
+    }
+
+    /**
+     * java.util.GregorianCalendar#getMaximum(int)
+     */
+    public void test_getMaximumI() {
+        // Test for method int java.util.GregorianCalendar.getMaximum(int)
+        GregorianCalendar gc = new GregorianCalendar();
+        assertEquals("Wrong maximum value for DAY_OF_MONTH", 31, gc
+                .getMaximum(Calendar.DAY_OF_MONTH));
+        assertTrue("Wrong maximum value for MONTH", gc
+                .getMaximum(Calendar.MONTH) == Calendar.DECEMBER);
+        assertEquals("Wrong maximum value for HOUR_OF_DAY", 23, gc
+                .getMaximum(Calendar.HOUR_OF_DAY));
+        assertEquals("Wrong maximum value for HOUR",
+                11, gc.getMaximum(Calendar.HOUR));
+
+        BitSet result = new BitSet();
+        Vector values = new Vector();
+        int[] max = { 1, 292278994, 11, 53, 6, 31, 366, 7, 6, 1, 11, 23, 59,
+                59, 999, 50400000, 7200000 };
+        for (int i = 0; i < max.length; i++) {
+            if (gc.getMaximum(i) != max[i]) {
+                result.set(i);
+                values.add(new Integer(gc.getMaximum(i)));
+            }
+        }
+        assertTrue("Wrong max for " + result + " = " + values,
+                result.length() == 0);
+    }
+
+    /**
+     * java.util.GregorianCalendar#getMinimum(int)
+     */
+    public void test_getMinimumI() {
+        // Test for method int java.util.GregorianCalendar.getMinimum(int)
+        GregorianCalendar gc = new GregorianCalendar();
+        assertEquals("Wrong minimum value for DAY_OF_MONTH", 1, gc
+                .getMinimum(Calendar.DAY_OF_MONTH));
+        assertTrue("Wrong minimum value for MONTH", gc
+                .getMinimum(Calendar.MONTH) == Calendar.JANUARY);
+        assertEquals("Wrong minimum value for HOUR_OF_DAY", 0, gc
+                .getMinimum(Calendar.HOUR_OF_DAY));
+        assertEquals("Wrong minimum value for HOUR",
+                0, gc.getMinimum(Calendar.HOUR));
+
+        BitSet result = new BitSet();
+        int[] min = { 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, -46800000,
+                0 };
+        for (int i = 0; i < min.length; i++) {
+            if (gc.getMinimum(i) != min[i])
+                result.set(i);
+        }
+        assertTrue("Wrong min for " + result, result.length() == 0);
+    }
+
+    /**
+     * java.util.GregorianCalendar#isLeapYear(int)
+     */
+    public void test_isLeapYearI() {
+        // Test for method boolean java.util.GregorianCalendar.isLeapYear(int)
+        GregorianCalendar gc = new GregorianCalendar(1998, 11, 6);
+        assertTrue("Returned incorrect value for leap year", !gc
+                .isLeapYear(1998));
+        assertTrue("Returned incorrect value for leap year", gc
+                .isLeapYear(2000));
+
+    }
+
+    /**
+     * java.util.GregorianCalendar#roll(int, int)
+     */
+    public void test_rollII() {
+        // Test for method void java.util.GregorianCalendar.roll(int, int)
+        GregorianCalendar gc = new GregorianCalendar(1972, Calendar.OCTOBER, 8,
+                2, 5, 0);
+        gc.roll(Calendar.DAY_OF_MONTH, -1);
+        assertTrue("Failed to roll DAY_OF_MONTH down by 1", gc
+                .equals(new GregorianCalendar(1972, Calendar.OCTOBER, 7, 2, 5,
+                        0)));
+        gc = new GregorianCalendar(1972, Calendar.OCTOBER, 8, 2, 5, 0);
+        gc.roll(Calendar.DAY_OF_MONTH, 25);
+        assertTrue("Failed to roll DAY_OF_MONTH up by 25", gc
+                .equals(new GregorianCalendar(1972, Calendar.OCTOBER, 2, 2, 5,
+                        0)));
+        gc = new GregorianCalendar(1972, Calendar.OCTOBER, 8, 2, 5, 0);
+        gc.roll(Calendar.DAY_OF_MONTH, -10);
+        assertTrue("Failed to roll DAY_OF_MONTH down by 10", gc
+                .equals(new GregorianCalendar(1972, Calendar.OCTOBER, 29, 2, 5,
+                        0)));
+    }
+
+    /**
+     * java.util.GregorianCalendar#roll(int, boolean)
+     */
+    public void test_rollIZ() {
+        // Test for method void java.util.GregorianCalendar.roll(int, boolean)
+        GregorianCalendar gc = new GregorianCalendar(1972, Calendar.OCTOBER,
+                13, 19, 9, 59);
+        gc.roll(Calendar.DAY_OF_MONTH, false);
+        assertTrue("Failed to roll day_of_month down", gc
+                .equals(new GregorianCalendar(1972, Calendar.OCTOBER, 12, 19,
+                        9, 59)));
+        gc = new GregorianCalendar(1972, Calendar.OCTOBER, 13, 19, 9, 59);
+        gc.roll(Calendar.DAY_OF_MONTH, true);
+        assertTrue("Failed to roll day_of_month up", gc
+                .equals(new GregorianCalendar(1972, Calendar.OCTOBER, 14, 19,
+                        9, 59)));
+        gc = new GregorianCalendar(1972, Calendar.OCTOBER, 31, 19, 9, 59);
+        gc.roll(Calendar.DAY_OF_MONTH, true);
+        assertTrue("Failed to roll day_of_month up", gc
+                .equals(new GregorianCalendar(1972, Calendar.OCTOBER, 1, 19, 9,
+                        59)));
+
+        GregorianCalendar cal = new GregorianCalendar();
+        int result;
+        try {
+            cal.roll(Calendar.ZONE_OFFSET, true);
+            result = 0;
+        } catch (IllegalArgumentException e) {
+            result = 1;
+        }
+        assertEquals("ZONE_OFFSET roll", 1, result);
+        try {
+            cal.roll(Calendar.DST_OFFSET, true);
+            result = 0;
+        } catch (IllegalArgumentException e) {
+            result = 1;
+        }
+        assertEquals("ZONE_OFFSET roll", 1, result);
+
+        cal.set(2004, Calendar.DECEMBER, 31, 5, 0, 0);
+        cal.roll(Calendar.WEEK_OF_YEAR, true);
+        assertEquals("Wrong year: " + cal.getTime(), 2004, cal
+                .get(Calendar.YEAR));
+        assertEquals("Wrong month: " + cal.getTime(), Calendar.JANUARY, cal
+                .get(Calendar.MONTH));
+        assertEquals("Wrong date: " + cal.getTime(), 9, cal.get(Calendar.DATE));
+
+        // Regression for HARMONY-4372
+        cal.set(1994, 11, 30, 5, 0, 0);
+        cal.setMinimalDaysInFirstWeek(4);
+        cal.roll(Calendar.WEEK_OF_YEAR, true);
+        assertEquals("Wrong year: " + cal.getTime(), 1994, cal
+                .get(Calendar.YEAR));
+        assertEquals("Wrong month: " + cal.getTime(), Calendar.JANUARY, cal
+                .get(Calendar.MONTH));
+        assertEquals("Wrong date: " + cal.getTime(), 7, cal.get(Calendar.DATE));
+
+        cal.roll(Calendar.WEEK_OF_YEAR, true);
+        assertEquals("Wrong year: " + cal.getTime(), 1994, cal
+                .get(Calendar.YEAR));
+        assertEquals("Wrong month: " + cal.getTime(), Calendar.JANUARY, cal
+                .get(Calendar.MONTH));
+        assertEquals("Wrong date: " + cal.getTime(), 14, cal.get(Calendar.DATE));
+
+        cal.roll(Calendar.WEEK_OF_YEAR, false);
+        assertEquals("Wrong year: " + cal.getTime(), 1994, cal
+                .get(Calendar.YEAR));
+        assertEquals("Wrong month: " + cal.getTime(), Calendar.JANUARY, cal
+                .get(Calendar.MONTH));
+        assertEquals("Wrong date: " + cal.getTime(), 7, cal.get(Calendar.DATE));
+
+        cal.roll(Calendar.WEEK_OF_YEAR, false);
+        assertEquals("Wrong year: " + cal.getTime(), 1994, cal
+                .get(Calendar.YEAR));
+        assertEquals("Wrong month: " + cal.getTime(), Calendar.DECEMBER, cal
+                .get(Calendar.MONTH));
+        assertEquals("Wrong date: " + cal.getTime(), 30, cal.get(Calendar.DATE));
+
+        cal.roll(Calendar.WEEK_OF_YEAR, false);
+        assertEquals("Wrong year: " + cal.getTime(), 1994, cal
+                .get(Calendar.YEAR));
+        assertEquals("Wrong month: " + cal.getTime(), Calendar.DECEMBER, cal
+                .get(Calendar.MONTH));
+        assertEquals("Wrong date: " + cal.getTime(), 23, cal.get(Calendar.DATE));
+
+        // Regression for HARMONY-4510
+        cal.set(1999, Calendar.DECEMBER, 31, 23, 59, 59);
+        cal.roll(GregorianCalendar.WEEK_OF_YEAR, true);
+        assertEquals("Wrong year: " + cal.getTime(), 1999, cal
+                .get(Calendar.YEAR));
+        assertEquals("Wrong month: " + cal.getTime(), Calendar.JANUARY, cal
+                .get(Calendar.MONTH));
+        assertEquals("Wrong date: " + cal.getTime(), 8, cal.get(Calendar.DATE));
+        cal.roll(GregorianCalendar.WEEK_OF_YEAR, false);
+        assertEquals("Wrong year: " + cal.getTime(), 1999, cal
+                .get(Calendar.YEAR));
+        assertEquals("Wrong month: " + cal.getTime(), Calendar.DECEMBER, cal
+                .get(Calendar.MONTH));
+        assertEquals("Wrong date: " + cal.getTime(), 31, cal.get(Calendar.DATE));
+    }
+
+    /**
+     * java.util.GregorianCalendar#setGregorianChange(java.util.Date)
+     */
+    public void test_setGregorianChangeLjava_util_Date() {
+        // Test for method void
+        // java.util.GregorianCalendar.setGregorianChange(java.util.Date)
+        GregorianCalendar gc1 = new GregorianCalendar(1582, Calendar.OCTOBER,
+                4, 0, 0);
+        GregorianCalendar gc2 = new GregorianCalendar(1972, Calendar.OCTOBER,
+                13, 0, 0);
+        gc1.setGregorianChange(gc2.getTime());
+        assertTrue("Returned incorrect value", gc2.getTime().equals(
+                gc1.getGregorianChange()));
+    }
+
+    /**
+     * java.util.GregorianCalendar#clone()
+     */
+    public void test_clone() {
+
+        // Regression for HARMONY-498
+        GregorianCalendar gCalend = new GregorianCalendar();
+
+        gCalend.set(Calendar.MILLISECOND, 0);
+        int dayOfMonth = gCalend.get(Calendar.DAY_OF_MONTH);
+
+        // create clone object and change date
+        GregorianCalendar gCalendClone = (GregorianCalendar) gCalend.clone();
+        gCalendClone.add(Calendar.DATE, 1);
+
+        assertEquals("Before", dayOfMonth, gCalend.get(Calendar.DAY_OF_MONTH));
+        gCalend.set(Calendar.MILLISECOND, 0);//changes nothing
+        assertEquals("After", dayOfMonth, gCalend.get(Calendar.DAY_OF_MONTH));
+    }
+
+    /**
+     * java.util.GregorianCalendar#getMinimalDaysInFirstWeek()
+     */
+    public void test_getMinimalDaysInFirstWeek() {
+        // Regression for Harmony-1037
+        // Some non-bug differences below because of different CLDR data of Harmony
+        GregorianCalendar g = new GregorianCalendar(TimeZone
+                .getTimeZone("Europe/London"), new Locale("en", "GB"));
+        int minimalDaysInFirstWeek = g.getMinimalDaysInFirstWeek();
+        assertEquals(4, minimalDaysInFirstWeek);
+
+        g = new GregorianCalendar(TimeZone.getTimeZone("Europe/London"),
+                new Locale("fr"));
+        minimalDaysInFirstWeek = g.getMinimalDaysInFirstWeek();
+        assertEquals(4, minimalDaysInFirstWeek);
+
+        g = new GregorianCalendar(TimeZone.getTimeZone("Europe/London"),
+                new Locale("fr", "CA"));
+        minimalDaysInFirstWeek = g.getMinimalDaysInFirstWeek();
+        assertEquals(4, minimalDaysInFirstWeek);
+
+    }
+
+    /**
+     * java.util.GregorianCalendar#computeTime()
+     */
+    public void test_computeTime() {
+        // Regression for Harmony-493
+        GregorianCalendar g = new GregorianCalendar(
+                TimeZone.getTimeZone("Europe/London"),
+                new Locale("en", "GB")
+        );
+        g.clear();
+        g.set(2006, 02, 26, 01, 50, 00);
+        assertEquals(1143337800000L, g.getTimeInMillis());
+
+        GregorianCalendar g1 = new GregorianCalendar(
+                TimeZone.getTimeZone("Europe/Moscow")
+        );
+        g1.clear();
+        g1.set(2006, 02, 26, 02, 20, 00); // in the DST transition interval
+        assertEquals(1143328800000L, g1.getTimeInMillis());
+        assertEquals(3, g1.get(Calendar.HOUR_OF_DAY));
+        g1.clear();
+        g1.set(2006, 9, 29, 02, 50, 00); // transition from DST
+        assertEquals(1162079400000L, g1.getTimeInMillis());
+        assertEquals(2, g1.get(Calendar.HOUR_OF_DAY));
+        // End of regression test
+    }
+
+    /**
+     * java.util.GregorianCalendar#get(int)
+     */
+    @SuppressWarnings("deprecation")
+    public void test_getI() {
+        // Regression test for HARMONY-2959
+        Date date = new Date(Date.parse("Jan 15 00:00:01 GMT 2000"));
+        GregorianCalendar gc = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
+        gc.setGregorianChange(date);
+        gc.setTimeInMillis(Date.parse("Dec 24 00:00:01 GMT 2000"));
+        assertEquals(346, gc.get(Calendar.DAY_OF_YEAR));
+
+        // Regression test for HARMONY-3003
+        date = new Date(Date.parse("Feb 28 00:00:01 GMT 2000"));
+        gc = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
+        gc.setGregorianChange(date);
+        gc.setTimeInMillis(Date.parse("Dec 1 00:00:01 GMT 2000"));
+        assertEquals(1, gc.get(Calendar.DAY_OF_MONTH));
+        assertEquals(11, gc.get(Calendar.MONTH));
+
+        // Regression test for HARMONY-4513
+        gc = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
+        gc.set(1582, Calendar.OCTOBER, 15, 0, 0, 0);
+        // reset millisecond to zero in order to be the same time as cutover
+        gc.set(Calendar.MILLISECOND, 0);
+        assertEquals(0, gc.get(Calendar.MILLISECOND));
+        assertEquals(1582, gc.get(Calendar.YEAR));
+        assertEquals(Calendar.OCTOBER, gc.get(Calendar.MONTH));
+        assertEquals(15, gc.get(Calendar.DAY_OF_MONTH));
+        assertEquals(0, gc.get(Calendar.HOUR_OF_DAY));
+        assertEquals(0, gc.get(Calendar.MINUTE));
+        assertEquals(0, gc.get(Calendar.SECOND));
+        gc.set(1582, Calendar.OCTOBER, 14, 0, 0, 0);
+        assertEquals(24, gc.get(Calendar.DAY_OF_MONTH));
+
+        // Regression test for HARMONY-2422
+        gc = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
+        gc.set(GregorianCalendar.ZONE_OFFSET, -1);
+        assertEquals(-1, gc.get(GregorianCalendar.ZONE_OFFSET));
+        gc.set(GregorianCalendar.ZONE_OFFSET, 1);
+        assertEquals(1, gc.get(GregorianCalendar.ZONE_OFFSET));
+        gc.set(GregorianCalendar.ZONE_OFFSET, 0);
+        assertEquals(0, gc.get(GregorianCalendar.ZONE_OFFSET));
+    }
+
+    /**
+     * 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() {
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/IdentityHashMap2Test.java b/luni/src/test/java/tests/api/java/util/IdentityHashMap2Test.java
new file mode 100644
index 0000000..bb68c2a
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/IdentityHashMap2Test.java
@@ -0,0 +1,467 @@
+/*
+ *  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.util;
+
+import java.io.Serializable;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import tests.support.Support_MapTest2;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class IdentityHashMap2Test extends junit.framework.TestCase {
+    private static final String ID = "hello";
+
+    class MockMap extends AbstractMap {
+        public Set entrySet() {
+            return null;
+        }
+
+        public int size() {
+            return 0;
+        }
+    }
+    /*
+      * TODO: change all the statements testing the keys and values with equals()
+      * method to check for reference equality instead
+      */
+
+    IdentityHashMap 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();
+        }
+    }
+
+    /**
+     * java.util.IdentityHashMap#IdentityHashMap()
+     */
+    public void test_Constructor() {
+        // Test for method java.util.IdentityHashMap()
+        new Support_MapTest2(new IdentityHashMap()).runTest();
+
+        IdentityHashMap hm2 = new IdentityHashMap();
+        assertEquals("Created incorrect IdentityHashMap", 0, hm2.size());
+    }
+
+    /**
+     * java.util.IdentityHashMap#IdentityHashMap(int)
+     */
+    public void test_ConstructorI() {
+        // Test for method java.util.IdentityHashMap(int)
+        IdentityHashMap hm2 = new IdentityHashMap(5);
+        assertEquals("Created incorrect IdentityHashMap", 0, hm2.size());
+        try {
+            new IdentityHashMap(-1);
+        } catch (IllegalArgumentException e) {
+            return;
+        }
+        fail(
+                "Failed to throw IllegalArgumentException for initial capacity < 0");
+
+        IdentityHashMap empty = new IdentityHashMap(0);
+        assertNull("Empty IdentityHashMap access", empty.get("nothing"));
+        empty.put("something", "here");
+        assertTrue("cannot get element", empty.get("something") == "here");
+    }
+
+    /**
+     * java.util.IdentityHashMap#IdentityHashMap(java.util.Map)
+     */
+    public void test_ConstructorLjava_util_Map() {
+        // Test for method java.util.IdentityHashMap(java.util.Map)
+        Map myMap = new TreeMap();
+        for (int counter = 0; counter < hmSize; counter++)
+            myMap.put(objArray2[counter], objArray[counter]);
+        IdentityHashMap hm2 = new IdentityHashMap(myMap);
+        for (int counter = 0; counter < hmSize; counter++)
+            assertTrue("Failed to construct correct IdentityHashMap", hm
+                    .get(objArray2[counter]) == hm2.get(objArray2[counter]));
+
+        Map mockMap = new MockMap();
+        hm2 = new IdentityHashMap(mockMap);
+        assertEquals("Size should be 0", 0, hm2.size());
+    }
+
+    public void test_IdentityHashMap_Constructor_BigSize() {
+        try {
+            new IdentityHashMap(Integer.MAX_VALUE);
+            fail("should throw OutOfMemoryError");
+        } catch (OutOfMemoryError e) {
+            // Expected
+        }
+    }
+
+    /**
+     * java.util.IdentityHashMap#clear()
+     */
+    public void test_clear() {
+        // Test for method void java.util.IdentityHashMap.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]));
+
+    }
+
+    /**
+     * java.util.IdentityHashMap#clone()
+     */
+    public void test_clone() {
+        // Test for method java.lang.Object java.util.IdentityHashMap.clone()
+        IdentityHashMap hm2 = (IdentityHashMap) hm.clone();
+        assertTrue("Clone answered equivalent IdentityHashMap", hm2 != hm);
+        for (int counter = 0; counter < hmSize; counter++)
+            assertTrue("Clone answered unequal IdentityHashMap", hm
+                    .get(objArray2[counter]) == hm2.get(objArray2[counter]));
+
+        IdentityHashMap map = new IdentityHashMap();
+        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());
+    }
+
+    /**
+     * java.util.IdentityHashMap#containsKey(java.lang.Object)
+     */
+    public void test_containsKeyLjava_lang_Object() {
+        // Test for method boolean
+        // java.util.IdentityHashMap.containsKey(java.lang.Object)
+        assertTrue("Returned false for valid key", hm
+                .containsKey(objArray2[23]));
+        assertTrue("Returned true for copy of valid key", !hm
+                .containsKey(new Integer(23).toString()));
+        assertTrue("Returned true for invalid key", !hm.containsKey("KKDKDKD"));
+
+        IdentityHashMap m = new IdentityHashMap();
+        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)));
+    }
+
+    /**
+     * java.util.IdentityHashMap#containsValue(java.lang.Object)
+     */
+    public void test_containsValueLjava_lang_Object() {
+        // Test for method boolean
+        // java.util.IdentityHashMap.containsValue(java.lang.Object)
+        assertTrue("Returned false for valid value", hm
+                .containsValue(objArray[19]));
+        assertTrue("Returned true for invalid valie", !hm
+                .containsValue(new Integer(-9)));
+    }
+
+    /**
+     * java.util.IdentityHashMap#entrySet()
+     */
+    public void test_entrySet() {
+        // Test for method java.util.Set java.util.IdentityHashMap.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()));
+        }
+    }
+
+    /**
+     * java.util.IdentityHashMap#get(java.lang.Object)
+     */
+    public void test_getLjava_lang_Object() {
+        // Test for method java.lang.Object
+        // java.util.IdentityHashMap.get(java.lang.Object)
+        assertNull("Get returned non-null for non existent key",
+                hm.get("T"));
+        hm.put("T", "HELLO");
+        assertEquals("Get returned incorecct value for existing key", "HELLO", hm.get("T")
+        );
+
+        IdentityHashMap m = new IdentityHashMap();
+        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)));
+    }
+
+    /**
+     * java.util.IdentityHashMap#isEmpty()
+     */
+    public void test_isEmpty() {
+        // Test for method boolean java.util.IdentityHashMap.isEmpty()
+        assertTrue("Returned false for new map", new IdentityHashMap()
+                .isEmpty());
+        assertTrue("Returned true for non-empty", !hm.isEmpty());
+    }
+
+    /**
+     * java.util.IdentityHashMap#keySet()
+     */
+    public void test_keySet() {
+        // Test for method java.util.Set java.util.IdentityHashMap.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(objArray2[i]));
+        }
+
+        IdentityHashMap m = new IdentityHashMap();
+        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 IdentityHashMap(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 IdentityHashMap(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));
+    }
+
+    /**
+     * java.util.IdentityHashMap#put(java.lang.Object, java.lang.Object)
+     */
+    public void test_putLjava_lang_ObjectLjava_lang_Object() {
+        // Test for method java.lang.Object
+        // java.util.IdentityHashMap.put(java.lang.Object, java.lang.Object)
+        hm.put("KEY", "VALUE");
+        assertEquals("Failed to install key/value pair",
+                "VALUE", hm.get("KEY"));
+
+        IdentityHashMap m = new IdentityHashMap();
+        Short s0 = new Short((short) 0);
+        m.put(s0, "short");
+        m.put(null, "test");
+        Integer i0 = new Integer(0);
+        m.put(i0, "int");
+        assertEquals("Failed adding to bucket containing null",
+                "short", m.get(s0));
+        assertEquals("Failed adding to bucket containing null2", "int", m.get(i0)
+        );
+    }
+
+    /**
+     * java.util.IdentityHashMap#putAll(java.util.Map)
+     */
+    public void test_putAllLjava_util_Map() {
+        // Test for method void java.util.IdentityHashMap.putAll(java.util.Map)
+        IdentityHashMap hm2 = new IdentityHashMap();
+        hm2.putAll(hm);
+        for (int i = 0; i < 1000; i++)
+            assertTrue("Failed to clear all elements", hm2.get(objArray2[i])
+                    .equals((new Integer(i))));
+
+        hm2 = new IdentityHashMap();
+        Map mockMap = new MockMap();
+        hm2.putAll(mockMap);
+        assertEquals("Size should be 0", 0, hm2.size());
+    }
+
+    /**
+     * java.util.IdentityHashMap#remove(java.lang.Object)
+     */
+    public void test_removeLjava_lang_Object() {
+        // Test for method java.lang.Object
+        // java.util.IdentityHashMap.remove(java.lang.Object)
+        int size = hm.size();
+        Integer x = ((Integer) hm.remove(objArray2[9]));
+        assertTrue("Remove returned incorrect value", x.equals(new Integer(9)));
+        assertNull("Failed to remove given key", hm.get(objArray2[9]));
+        assertTrue("Failed to decrement size", hm.size() == (size - 1));
+        assertNull("Remove of non-existent key returned non-null", hm
+                .remove("LCLCLC"));
+
+        IdentityHashMap m = new IdentityHashMap();
+        m.put(null, "test");
+        assertNull("Failed with same hash as null",
+                m.remove(objArray[0]));
+        assertEquals("Failed with null key", "test", m.remove(null));
+    }
+
+    /**
+     * java.util.IdentityHashMap#size()
+     */
+    public void test_size() {
+        // Test for method int java.util.IdentityHashMap.size()
+        assertEquals("Returned incorrect size, ", (objArray.length + 2), hm
+                .size());
+    }
+
+    /**
+     * java.util.IdentityHashMap#equals(java.lang.Object)
+     */
+    public void test_equalsLjava_lang_Object() {
+        IdentityHashMap mapOne = new IdentityHashMap();
+        IdentityHashMap mapTwo = new IdentityHashMap();
+        IdentityHashMap mapThree = new IdentityHashMap();
+        IdentityHashMap mapFour = new IdentityHashMap();
+
+        String one = "one";
+        String alsoOne = new String(one); // use the new operator to ensure a
+        // new reference is constructed
+        String two = "two";
+        String alsoTwo = new String(two); // use the new operator to ensure a
+        // new reference is constructed
+
+        mapOne.put(one, two);
+        mapFour.put(one, two);
+
+        // these two are not equal to the above two
+        mapTwo.put(alsoOne, two);
+        mapThree.put(one, alsoTwo);
+
+        assertEquals("failure of equality of IdentityHashMaps", mapOne, mapFour);
+        assertTrue("failure of non-equality of IdentityHashMaps one and two",
+                !mapOne.equals(mapTwo));
+        assertTrue("failure of non-equality of IdentityHashMaps one and three",
+                !mapOne.equals(mapThree));
+        assertTrue("failure of non-equality of IdentityHashMaps two and three",
+                !mapTwo.equals(mapThree));
+
+        HashMap hashMapTwo = new HashMap();
+        HashMap hashMapThree = new HashMap();
+        hashMapTwo.put(alsoOne, two);
+        hashMapThree.put(one, alsoTwo);
+
+        assertTrue(
+                "failure of non-equality of IdentityHashMaps one and Hashmap two",
+                !mapOne.equals(hashMapTwo));
+        assertTrue(
+                "failure of non-equality of IdentityHashMaps one and Hashmap three",
+                !mapOne.equals(hashMapThree));
+    }
+
+    /**
+     * java.util.IdentityHashMap#values()
+     */
+    public void test_values() {
+        // Test for method java.util.Collection
+        // java.util.IdentityHashMap.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]));
+
+        IdentityHashMap myIdentityHashMap = new IdentityHashMap();
+        for (int i = 0; i < 100; i++)
+            myIdentityHashMap.put(objArray2[i], objArray[i]);
+        Collection values = myIdentityHashMap.values();
+        values.remove(objArray[0]);
+        assertTrue(
+                "Removing from the values collection should remove from the original map",
+                !myIdentityHashMap.containsValue(objArray2[0]));
+
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() {
+        hm = new IdentityHashMap();
+        for (int i = 0; i < objArray.length; i++)
+            hm.put(objArray2[i], objArray[i]);
+        hm.put("test", null);
+        hm.put(null, "test");
+    }
+
+
+    private static final SerializationTest.SerializableAssert comparator = new
+            SerializationTest.SerializableAssert() {
+
+                public void assertDeserialized(Serializable initial, Serializable deserialized) {
+                    IdentityHashMap<String, String> initialMap = (IdentityHashMap<String, String>) initial;
+                    IdentityHashMap<String, String> deseriaMap = (IdentityHashMap<String, String>) deserialized;
+                    assertEquals("should be equal", initialMap.size(), deseriaMap.size());
+                }
+
+            };
+}
diff --git a/luni/src/test/java/tests/api/java/util/IllegalFormatCodePointExceptionTest.java b/luni/src/test/java/tests/api/java/util/IllegalFormatCodePointExceptionTest.java
new file mode 100644
index 0000000..d223c8c
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/IllegalFormatCodePointExceptionTest.java
@@ -0,0 +1,91 @@
+/* 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.util;
+
+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;
+
+public class IllegalFormatCodePointExceptionTest extends TestCase {
+
+    /**
+     * java.util.IllegalFormatCodePointException.IllegalFormatCodePointException(int)
+     */
+    public void test_illegalFormatCodePointException() {
+        IllegalFormatCodePointException illegalFormatCodePointException = new IllegalFormatCodePointException(
+                -1);
+        assertTrue(null != illegalFormatCodePointException);
+    }
+
+    /**
+     * java.util.IllegalFormatCodePointException.getCodePoint()
+     */
+    public void test_getCodePoint() {
+        int codePoint = 12345;
+        IllegalFormatCodePointException illegalFormatCodePointException = new IllegalFormatCodePointException(
+                codePoint);
+        assertEquals(codePoint, illegalFormatCodePointException.getCodePoint());
+    }
+
+    /**
+     * java.util.IllegalFormatCodePointException.getMessage()
+     */
+    public void test_getMessage() {
+        int codePoint = 12345;
+        IllegalFormatCodePointException illegalFormatCodePointException = new IllegalFormatCodePointException(
+                codePoint);
+        assertTrue(null != illegalFormatCodePointException.getMessage());
+    }
+
+    // comparator for IllegalFormatCodePointException objects
+    private static final SerializableAssert exComparator = new SerializableAssert() {
+        public void assertDeserialized(Serializable initial,
+                Serializable deserialized) {
+
+            SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+                    deserialized);
+
+            IllegalFormatCodePointException initEx = (IllegalFormatCodePointException) initial;
+            IllegalFormatCodePointException desrEx = (IllegalFormatCodePointException) deserialized;
+
+            assertEquals("CodePoint", initEx.getCodePoint(), desrEx
+                    .getCodePoint());
+        }
+    };
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        SerializationTest.verifySelf(
+                new IllegalFormatCodePointException(12345), exComparator);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        SerializationTest.verifyGolden(this,
+                new IllegalFormatCodePointException(12345), exComparator);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/IllegalFormatConversionExceptionTest.java b/luni/src/test/java/tests/api/java/util/IllegalFormatConversionExceptionTest.java
new file mode 100644
index 0000000..14475fe
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/IllegalFormatConversionExceptionTest.java
@@ -0,0 +1,115 @@
+/* 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.util;
+
+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;
+
+public class IllegalFormatConversionExceptionTest extends TestCase {
+
+    /**
+     * java.util.IllegalFormatConversionException#IllegalFormatConversionException(char,
+     *Class)
+     */
+    public void test_illegalFormatConversionException() {
+        try {
+            new IllegalFormatConversionException(' ', null);
+            fail("should throw NullPointerExcetpion.");
+        } catch (NullPointerException e) {
+            // desired
+        }
+    }
+
+    /**
+     * java.util.IllegalFormatConversionException#getArgumentClass()
+     */
+    public void test_getArgumentClass() {
+        char c = '*';
+        Class<String> argClass = String.class;
+        IllegalFormatConversionException illegalFormatConversionException = new IllegalFormatConversionException(
+                c, argClass);
+        assertEquals(argClass, illegalFormatConversionException
+                .getArgumentClass());
+
+    }
+
+    /**
+     * java.util.IllegalFormatConversionException#getConversion()
+     */
+    public void test_getConversion() {
+        char c = '*';
+        Class<String> argClass = String.class;
+        IllegalFormatConversionException illegalFormatConversionException = new IllegalFormatConversionException(
+                c, argClass);
+        assertEquals(c, illegalFormatConversionException.getConversion());
+
+    }
+
+    /**
+     * java.util.IllegalFormatConversionException#getMessage()
+     */
+    public void test_getMessage() {
+        char c = '*';
+        Class<String> argClass = String.class;
+        IllegalFormatConversionException illegalFormatConversionException = new IllegalFormatConversionException(
+                c, argClass);
+        assertTrue(null != illegalFormatConversionException.getMessage());
+
+    }
+
+    // comparator for IllegalFormatConversionException objects
+    private static final SerializableAssert exComparator = new SerializableAssert() {
+        public void assertDeserialized(Serializable initial,
+                Serializable deserialized) {
+
+            SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+                    deserialized);
+
+            IllegalFormatConversionException initEx = (IllegalFormatConversionException) initial;
+            IllegalFormatConversionException desrEx = (IllegalFormatConversionException) deserialized;
+
+            assertEquals("ArgumentClass", initEx.getArgumentClass(), desrEx
+                    .getArgumentClass());
+            assertEquals("Conversion", initEx.getConversion(), desrEx
+                    .getConversion());
+        }
+    };
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        SerializationTest.verifySelf(new IllegalFormatConversionException('*',
+                String.class), exComparator);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        SerializationTest.verifyGolden(this,
+                new IllegalFormatConversionException('*', String.class),
+                exComparator);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/IllegalFormatFlagsExceptionTest.java b/luni/src/test/java/tests/api/java/util/IllegalFormatFlagsExceptionTest.java
new file mode 100644
index 0000000..c0f6b31
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/IllegalFormatFlagsExceptionTest.java
@@ -0,0 +1,94 @@
+/* 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.util;
+
+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;
+
+public class IllegalFormatFlagsExceptionTest extends TestCase {
+
+    /**
+     * java.util.IllegalFormatFlagsException#IllegalFormatFlagsException(String)
+     */
+    public void test_illegalFormatFlagsException() {
+        try {
+            new IllegalFormatFlagsException(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.IllegalFormatFlagsException.getFlags()
+     */
+    public void test_getFlags() {
+        String flags = "TESTFLAGS";
+        IllegalFormatFlagsException illegalFormatFlagsException = new IllegalFormatFlagsException(
+                flags);
+        assertEquals(flags, illegalFormatFlagsException.getFlags());
+    }
+
+    /**
+     * java.util.IllegalFormatFlagsException.getMessage()
+     */
+    public void test_getMessage() {
+        String flags = "TESTFLAGS";
+        IllegalFormatFlagsException illegalFormatFlagsException = new IllegalFormatFlagsException(
+                flags);
+        assertTrue(null != illegalFormatFlagsException.getMessage());
+
+    }
+
+    // comparator for IllegalFormatFlagsException objects
+    private static final SerializableAssert exComparator = new SerializableAssert() {
+        public void assertDeserialized(Serializable initial,
+                Serializable deserialized) {
+
+            SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+                    deserialized);
+
+            IllegalFormatFlagsException initEx = (IllegalFormatFlagsException) initial;
+            IllegalFormatFlagsException desrEx = (IllegalFormatFlagsException) deserialized;
+
+            assertEquals("Flags", initEx.getFlags(), desrEx.getFlags());
+        }
+    };
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        SerializationTest.verifySelf(new IllegalFormatFlagsException(
+                "TESTFLAGS"), exComparator);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        SerializationTest.verifyGolden(this, new IllegalFormatFlagsException(
+                "TESTFLAGS"), exComparator);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/IllegalFormatPrecisionExceptionTest.java b/luni/src/test/java/tests/api/java/util/IllegalFormatPrecisionExceptionTest.java
new file mode 100644
index 0000000..06863fa
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/IllegalFormatPrecisionExceptionTest.java
@@ -0,0 +1,92 @@
+/* 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.util;
+
+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;
+
+public class IllegalFormatPrecisionExceptionTest extends TestCase {
+
+    /**
+     * java.util.IllegalFormatPrecisionException#IllegalFormatPrecisionException(int)
+     */
+    public void test_illegalFormatPrecisionException() {
+        IllegalFormatPrecisionException illegalFormatPrecisionException = new IllegalFormatPrecisionException(
+                Integer.MIN_VALUE);
+        assertEquals(Integer.MIN_VALUE, illegalFormatPrecisionException
+                .getPrecision());
+    }
+
+    /**
+     * java.util.IllegalFormatPrecisionException#getPrecision()
+     */
+    public void test_getPrecision() {
+        int precision = 12345;
+        IllegalFormatPrecisionException illegalFormatPrecisionException = new IllegalFormatPrecisionException(
+                precision);
+        assertEquals(precision, illegalFormatPrecisionException.getPrecision());
+    }
+
+    /**
+     * method for 'java.util.IllegalFormatPrecisionException#getMessage()
+     */
+    public void test_getMessage() {
+        int precision = 12345;
+        IllegalFormatPrecisionException illegalFormatPrecisionException = new IllegalFormatPrecisionException(
+                precision);
+        assertTrue(null != illegalFormatPrecisionException.getMessage());
+
+    }
+
+    // comparator for IllegalFormatPrecisionException objects
+    private static final SerializableAssert exComparator = new SerializableAssert() {
+        public void assertDeserialized(Serializable initial,
+                Serializable deserialized) {
+
+            SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+                    deserialized);
+
+            IllegalFormatPrecisionException initEx = (IllegalFormatPrecisionException) initial;
+            IllegalFormatPrecisionException desrEx = (IllegalFormatPrecisionException) deserialized;
+
+            assertEquals("Precision", initEx.getPrecision(), desrEx
+                    .getPrecision());
+        }
+    };
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        SerializationTest.verifySelf(
+                new IllegalFormatPrecisionException(12345), exComparator);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        SerializationTest.verifyGolden(this,
+                new IllegalFormatPrecisionException(12345), exComparator);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/IllegalFormatWidthExceptionTest.java b/luni/src/test/java/tests/api/java/util/IllegalFormatWidthExceptionTest.java
new file mode 100644
index 0000000..49cd632
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/IllegalFormatWidthExceptionTest.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 tests.api.java.util;
+
+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;
+
+public class IllegalFormatWidthExceptionTest extends TestCase {
+
+    /**
+     * java.util.IllegalFormatWidthException#IllegalFormatWidthException(int)
+     */
+    public void test_illegalFormatWidthException() {
+        int width = Integer.MAX_VALUE;
+        IllegalFormatWidthException illegalFormatWidthException = new IllegalFormatWidthException(
+                width);
+        assertEquals(width, illegalFormatWidthException.getWidth());
+
+    }
+
+    /**
+     * java.util.IllegalFormatWidthException#getWidth()
+     */
+    public void test_getWidth() {
+        int width = 12345;
+        IllegalFormatWidthException illegalFormatWidthException = new IllegalFormatWidthException(
+                width);
+        assertEquals(width, illegalFormatWidthException.getWidth());
+
+    }
+
+    /**
+     * java.util.IllegalFormatWidthException#getMessage()
+     */
+    public void test_getMessage() {
+        int width = 12345;
+        IllegalFormatWidthException illegalFormatWidthException = new IllegalFormatWidthException(
+                width);
+        assertTrue(null != illegalFormatWidthException.getMessage());
+
+    }
+
+    // comparator for IllegalFormatWidthException objects
+    private static final SerializableAssert exComparator = new SerializableAssert() {
+        public void assertDeserialized(Serializable initial,
+                Serializable deserialized) {
+
+            SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+                    deserialized);
+
+            IllegalFormatWidthException initEx = (IllegalFormatWidthException) initial;
+            IllegalFormatWidthException desrEx = (IllegalFormatWidthException) deserialized;
+
+            assertEquals("Width", initEx.getWidth(), desrEx.getWidth());
+        }
+    };
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        SerializationTest.verifySelf(new IllegalFormatWidthException(12345),
+                exComparator);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        SerializationTest.verifyGolden(this, new IllegalFormatWidthException(
+                12345), exComparator);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/InputMismatchExceptionTest.java b/luni/src/test/java/tests/api/java/util/InputMismatchExceptionTest.java
new file mode 100644
index 0000000..47232b9
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/InputMismatchExceptionTest.java
@@ -0,0 +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
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.util;
+
+import java.io.Serializable;
+import java.util.InputMismatchException;
+import java.util.NoSuchElementException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+public class InputMismatchExceptionTest extends TestCase {
+
+    private static final String ERROR_MESSAGE = "for serialization test"; //$NON-NLS-1$
+
+    /**
+     * java.util.InputMismatchException#InputMismatchException()
+     */
+    @SuppressWarnings("cast")
+    public void test_Constructor() {
+        InputMismatchException exception = new InputMismatchException();
+        assertNotNull(exception);
+        assertTrue(exception instanceof NoSuchElementException);
+        assertTrue(exception instanceof Serializable);
+    }
+
+    /**
+     * java.util.InputMismatchException#InputMismatchException(String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        InputMismatchException exception = new InputMismatchException(
+                ERROR_MESSAGE);
+        assertNotNull(exception);
+        assertEquals(ERROR_MESSAGE, exception.getMessage());
+    }
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        SerializationTest.verifySelf(new InputMismatchException(ERROR_MESSAGE));
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        SerializationTest.verifyGolden(this, new InputMismatchException(
+                ERROR_MESSAGE));
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/MissingFormatArgumentExceptionTest.java b/luni/src/test/java/tests/api/java/util/MissingFormatArgumentExceptionTest.java
new file mode 100644
index 0000000..f3887f5
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/MissingFormatArgumentExceptionTest.java
@@ -0,0 +1,97 @@
+/* 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.util;
+
+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;
+
+public class MissingFormatArgumentExceptionTest extends TestCase {
+
+    /**
+     * java.util.MissingFormatArgumentException#MissingFormatArgumentException(String)
+     */
+    public void test_missingFormatArgumentException() {
+
+        try {
+            new MissingFormatArgumentException(null);
+            fail("should throw NullPointerExcepiton.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.MissingFormatArgumentException#getFormatSpecifier()
+     */
+    public void test_getFormatSpecifier() {
+        String s = "MYTESTSTRING";
+        MissingFormatArgumentException missingFormatArgumentException = new MissingFormatArgumentException(
+                s);
+        assertEquals(s, missingFormatArgumentException.getFormatSpecifier());
+    }
+
+    /**
+     * java.util.MissingFormatArgumentException#getMessage()
+     */
+    public void test_getMessage() {
+        String s = "MYTESTSTRING";
+        MissingFormatArgumentException missingFormatArgumentException = new MissingFormatArgumentException(
+                s);
+        assertTrue(null != missingFormatArgumentException.getMessage());
+
+    }
+
+    // comparator for comparing MissingFormatArgumentException objects
+    private static final SerializableAssert exComparator = new SerializableAssert() {
+        public void assertDeserialized(Serializable initial,
+                Serializable deserialized) {
+
+            SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+                    deserialized);
+
+            MissingFormatArgumentException initEx = (MissingFormatArgumentException) initial;
+            MissingFormatArgumentException desrEx = (MissingFormatArgumentException) deserialized;
+
+            assertEquals("FormatSpecifier", initEx.getFormatSpecifier(), desrEx
+                    .getFormatSpecifier());
+        }
+    };
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        SerializationTest.verifySelf(new MissingFormatArgumentException(
+                "MYTESTSTRING"), exComparator);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        SerializationTest.verifyGolden(this,
+                new MissingFormatArgumentException("MYTESTSTRING"),
+                exComparator);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/MissingFormatWidthExceptionTest.java b/luni/src/test/java/tests/api/java/util/MissingFormatWidthExceptionTest.java
new file mode 100644
index 0000000..ffca1c9
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/MissingFormatWidthExceptionTest.java
@@ -0,0 +1,95 @@
+/* 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.util;
+
+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;
+
+public class MissingFormatWidthExceptionTest extends TestCase {
+
+    /**
+     * java.util.MissingFormatWidthException#MissingFormatWidthException(String)
+     */
+    public void test_missingFormatWidthException() {
+        try {
+            new MissingFormatWidthException(null);
+            fail("should throw NullPointerExcepiton");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.MissingFormatWidthException#getFormatSpecifier()
+     */
+    public void test_getFormatSpecifier() {
+        String s = "MYTESTSTRING";
+        MissingFormatWidthException missingFormatWidthException = new MissingFormatWidthException(
+                s);
+        assertEquals(s, missingFormatWidthException.getFormatSpecifier());
+
+    }
+
+    /**
+     * java.util.MissingFormatWidthException#getMessage()
+     */
+    public void test_getMessage() {
+        String s = "MYTESTSTRING";
+        MissingFormatWidthException missingFormatWidthException = new MissingFormatWidthException(
+                s);
+        assertTrue(null != missingFormatWidthException.getMessage());
+
+    }
+
+    // comparator for comparing MissingFormatWidthException objects
+    private static final SerializableAssert exComparator = new SerializableAssert() {
+        public void assertDeserialized(Serializable initial,
+                Serializable deserialized) {
+
+            SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+                    deserialized);
+
+            MissingFormatWidthException initEx = (MissingFormatWidthException) initial;
+            MissingFormatWidthException desrEx = (MissingFormatWidthException) deserialized;
+
+            assertEquals("FormatSpecifier", initEx.getFormatSpecifier(), desrEx
+                    .getFormatSpecifier());
+        }
+    };
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        SerializationTest.verifySelf(new MissingFormatWidthException(
+                "MYTESTSTRING"), exComparator);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        SerializationTest.verifyGolden(this, new MissingFormatWidthException(
+                "MYTESTSTRING"), exComparator);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/PriorityQueueTest.java b/luni/src/test/java/tests/api/java/util/PriorityQueueTest.java
new file mode 100644
index 0000000..05f9791
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/PriorityQueueTest.java
@@ -0,0 +1,823 @@
+/* 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.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.PriorityQueue;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import junit.framework.TestCase;
+import tests.util.SerializationTester;
+
+public class PriorityQueueTest extends TestCase {
+
+    private static final String SERIALIZATION_FILE_NAME = "serialization/java/util/PriorityQueue.golden.ser"; //$NON-NLS-1$    
+
+    /**
+     * java.util.PriorityQueue#iterator()
+     */
+    public void test_iterator() {
+        PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+        Integer[] array = { 2, 45, 7, -12, 9 };
+        for (int i = 0; i < array.length; i++) {
+            integerQueue.offer(array[i]);
+        }
+        Iterator<Integer> iter = integerQueue.iterator();
+        assertNotNull(iter);
+        ArrayList<Integer> iterResult = new ArrayList<Integer>();
+        while (iter.hasNext()) {
+            iterResult.add(iter.next());
+        }
+        Object[] resultArray = iterResult.toArray();
+        Arrays.sort(array);
+        Arrays.sort(resultArray);
+        assertTrue(Arrays.equals(array, resultArray));
+    }
+
+    /**
+     * java.util.PriorityQueue#iterator()
+     */
+    public void test_iterator_empty() {
+        PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+        Iterator<Integer> iter = integerQueue.iterator();
+        try {
+            iter.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // expected
+        }
+
+        iter = integerQueue.iterator();
+        try {
+            iter.remove();
+            fail("should throw IllegalStateException");
+        } catch (IllegalStateException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.PriorityQueue#iterator()
+     */
+    public void test_iterator_outofbound() {
+        PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+        integerQueue.offer(0);
+        Iterator<Integer> iter = integerQueue.iterator();
+        iter.next();
+        try {
+            iter.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // expected
+        }
+
+        iter = integerQueue.iterator();
+        iter.next();
+        iter.remove();
+        try {
+            iter.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.PriorityQueue#iterator()
+     */
+    public void test_iterator_remove() {
+        PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+        Integer[] array = { 2, 45, 7, -12, 9 };
+        for (int i = 0; i < array.length; i++) {
+            integerQueue.offer(array[i]);
+        }
+        Iterator<Integer> iter = integerQueue.iterator();
+        assertNotNull(iter);
+        for (int i = 0; i < array.length; i++) {
+            iter.next();
+            if (2 == i) {
+                iter.remove();
+            }
+        }
+        assertEquals(array.length - 1, integerQueue.size());
+
+        iter = integerQueue.iterator();
+        Integer[] newArray = new Integer[array.length - 1];
+        for (int i = 0; i < newArray.length; i++) {
+            newArray[i] = iter.next();
+        }
+
+        Arrays.sort(newArray);
+        for (int i = 0; i < integerQueue.size(); i++) {
+            assertEquals(newArray[i], integerQueue.poll());
+        }
+    }
+
+    public void test_iterator_removeEquals() {
+        PriorityQueue<String> integerQueue = new PriorityQueue<String>(10, new MockComparatorStringByLength());
+        String[] array = { "ONE", "TWO", "THREE", "FOUR", "FIVE" };
+        for (int i = 0; i < array.length; i++) {
+            integerQueue.offer(array[i]);
+        }
+        // Try removing an entry that the comparator says is equal
+        assertFalse(integerQueue.remove("123"));
+        assertFalse(integerQueue.remove("one"));
+        assertTrue(integerQueue.remove("THREE"));
+    }
+
+    /**
+     * java.util.PriorityQueue#iterator()
+     */
+    public void test_iterator_remove_illegalState() {
+        PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+        Integer[] array = { 2, 45, 7, -12, 9 };
+        for (int i = 0; i < array.length; i++) {
+            integerQueue.offer(array[i]);
+        }
+        Iterator<Integer> iter = integerQueue.iterator();
+        assertNotNull(iter);
+        try {
+            iter.remove();
+            fail("should throw IllegalStateException");
+        } catch (IllegalStateException e) {
+            // expected
+        }
+        iter.next();
+        iter.remove();
+        try {
+            iter.remove();
+            fail("should throw IllegalStateException");
+        } catch (IllegalStateException e) {
+            // expected
+        }
+
+    }
+
+    /**
+     * java.util.PriorityQueue.size()
+     */
+    public void test_size() {
+        PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+        assertEquals(0, integerQueue.size());
+        int[] array = { 2, 45, 7, -12, 9 };
+        for (int i = 0; i < array.length; i++) {
+            integerQueue.offer(array[i]);
+        }
+        assertEquals(array.length, integerQueue.size());
+    }
+
+    /**
+     * java.util.PriorityQueue#PriorityQueue()
+     */
+    public void test_Constructor() {
+        PriorityQueue<Object> queue = new PriorityQueue<Object>();
+        assertNotNull(queue);
+        assertEquals(0, queue.size());
+        assertNull(queue.comparator());
+    }
+
+    /**
+     * java.util.PriorityQueue#PriorityQueue(int)
+     */
+    public void test_ConstructorI() {
+        PriorityQueue<Object> queue = new PriorityQueue<Object>(100);
+        assertNotNull(queue);
+        assertEquals(0, queue.size());
+        assertNull(queue.comparator());
+    }
+
+    /**
+     * java.util.PriorityQueue#PriorityQueue(int, Comparator<? super E>)
+     */
+    public void test_ConstructorILjava_util_Comparator() {
+        PriorityQueue<Object> queue = new PriorityQueue<Object>(100,
+                (Comparator<Object>) null);
+        assertNotNull(queue);
+        assertEquals(0, queue.size());
+        assertNull(queue.comparator());
+
+        MockComparator<Object> comparator = new MockComparator<Object>();
+        queue = new PriorityQueue<Object>(100, comparator);
+        assertNotNull(queue);
+        assertEquals(0, queue.size());
+        assertEquals(comparator, queue.comparator());
+    }
+
+    /**
+     * java.util.PriorityQueue#PriorityQueue(int, Comparator<? super E>)
+     */
+    public void test_ConstructorILjava_util_Comparator_illegalCapacity() {
+        try {
+            new PriorityQueue<Object>(0, new MockComparator<Object>());
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            new PriorityQueue<Object>(-1, new MockComparator<Object>());
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.PriorityQueue#PriorityQueue(int, Comparator<? super E>)
+     */
+    public void test_ConstructorILjava_util_Comparator_cast() {
+        MockComparatorCast<Object> objectComparator = new MockComparatorCast<Object>();
+        PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>(100,
+                objectComparator);
+        assertNotNull(integerQueue);
+        assertEquals(0, integerQueue.size());
+        assertEquals(objectComparator, integerQueue.comparator());
+        Integer[] array = { 2, 45, 7, -12, 9 };
+        List<Integer> list = Arrays.asList(array);
+        integerQueue.addAll(list);
+        assertEquals(list.size(), integerQueue.size());
+        // just test here no cast exception raises.
+    }
+
+    /**
+     * java.util.PriorityQueue#PriorityQueue(Collection)
+     */
+    public void test_ConstructorLjava_util_Colleciton() {
+        Integer[] array = { 2, 45, 7, -12, 9 };
+        List<Integer> list = Arrays.asList(array);
+        PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>(list);
+        assertEquals(array.length, integerQueue.size());
+        assertNull(integerQueue.comparator());
+        Arrays.sort(array);
+        for (int i = 0; i < array.length; i++) {
+            assertEquals(array[i], integerQueue.poll());
+        }
+    }
+
+    /**
+     * java.util.PriorityQueue#PriorityQueue(Collection)
+     */
+    public void test_ConstructorLjava_util_Colleciton_null() {
+        ArrayList<Object> list = new ArrayList<Object>();
+        list.add(new Float(11));
+        list.add(null);
+        list.add(new Integer(10));
+        try {
+            new PriorityQueue<Object>(list);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.PriorityQueue#PriorityQueue(Collection)
+     */
+    public void test_ConstructorLjava_util_Colleciton_non_comparable() {
+        ArrayList<Object> list = new ArrayList<Object>();
+        list.add(new Float(11));
+        list.add(new Integer(10));
+        try {
+            new PriorityQueue<Object>(list);
+            fail("should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.PriorityQueue#PriorityQueue(Collection)
+     */
+    public void test_ConstructorLjava_util_Colleciton_from_priorityqueue() {
+        String[] array = { "AAAAA", "AA", "AAAA", "AAAAAAAA" };
+        PriorityQueue<String> queue = new PriorityQueue<String>(4,
+                new MockComparatorStringByLength());
+        for (int i = 0; i < array.length; i++) {
+            queue.offer(array[i]);
+        }
+        Collection<String> c = queue;
+        PriorityQueue<String> constructedQueue = new PriorityQueue<String>(c);
+        assertEquals(queue.comparator(), constructedQueue.comparator());
+        while (queue.size() > 0) {
+            assertEquals(queue.poll(), constructedQueue.poll());
+        }
+        assertEquals(0, constructedQueue.size());
+    }
+
+    /**
+     * java.util.PriorityQueue#PriorityQueue(Collection)
+     */
+    public void test_ConstructorLjava_util_Colleciton_from_sortedset() {
+        int[] array = { 3, 5, 79, -17, 5 };
+        TreeSet<Integer> treeSet = new TreeSet<Integer>(new MockComparator<Integer>());
+        for (int i = 0; i < array.length; i++) {
+            treeSet.add(array[i]);
+        }
+        Collection<? extends Integer> c = treeSet;
+        PriorityQueue<Integer> queue = new PriorityQueue<Integer>(c);
+        assertEquals(treeSet.comparator(), queue.comparator());
+        Iterator<Integer> iter = treeSet.iterator();
+        while (iter.hasNext()) {
+            assertEquals(iter.next(), queue.poll());
+        }
+        assertEquals(0, queue.size());
+    }
+
+    /**
+     * java.util.PriorityQueue#PriorityQueue(PriorityQueue<? * extends
+     *E>)
+     */
+    public void test_ConstructorLjava_util_PriorityQueue() {
+        PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+        int[] array = { 2, 45, 7, -12, 9 };
+        for (int i = 0; i < array.length; i++) {
+            integerQueue.offer(array[i]);
+        }
+        PriorityQueue<Object> objectQueue = new PriorityQueue<Object>(
+                integerQueue);
+        assertEquals(integerQueue.size(), objectQueue.size());
+        assertEquals(integerQueue.comparator(), objectQueue.comparator());
+        Arrays.sort(array);
+        for (int i = 0; i < array.length; i++) {
+            assertEquals(array[i], objectQueue.poll());
+        }
+    }
+
+    /**
+     * java.util.PriorityQueue#PriorityQueue(PriorityQueue<? * extends
+     *E>)
+     */
+    public void test_ConstructorLjava_util_PriorityQueue_null() {
+        try {
+            new PriorityQueue<Object>((PriorityQueue<Integer>) null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.PriorityQueue#PriorityQueue(SortedSet<? extends E>)
+     */
+    public void test_ConstructorLjava_util_SortedSet() {
+        int[] array = { 3, 5, 79, -17, 5 };
+        TreeSet<Integer> treeSet = new TreeSet<Integer>();
+        for (int i = 0; i < array.length; i++) {
+            treeSet.add(array[i]);
+        }
+        PriorityQueue<Integer> queue = new PriorityQueue<Integer>(treeSet);
+        Iterator<Integer> iter = treeSet.iterator();
+        while (iter.hasNext()) {
+            assertEquals(iter.next(), queue.poll());
+        }
+    }
+
+    /**
+     * java.util.PriorityQueue#PriorityQueue(SortedSet<? extends E>)
+     */
+    public void test_ConstructorLjava_util_SortedSet_null() {
+        try {
+            new PriorityQueue<Integer>((SortedSet<? extends Integer>) null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.PriorityQueue#offer(Object)
+     */
+    public void test_offerLjava_lang_Object() {
+        PriorityQueue<String> queue = new PriorityQueue<String>(10,
+                new MockComparatorStringByLength());
+        String[] array = { "AAAAA", "AA", "AAAA", "AAAAAAAA" };
+        for (int i = 0; i < array.length; i++) {
+            queue.offer(array[i]);
+        }
+        String[] sortedArray = { "AA", "AAAA", "AAAAA", "AAAAAAAA" };
+        for (int i = 0; i < sortedArray.length; i++) {
+            assertEquals(sortedArray[i], queue.poll());
+        }
+        assertEquals(0, queue.size());
+        assertNull(queue.poll());
+    }
+
+    /**
+     * java.util.PriorityQueue#offer(Object)
+     */
+    public void test_offerLjava_lang_Object_null() {
+        PriorityQueue<Object> queue = new PriorityQueue<Object>();
+        try {
+            queue.offer(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.PriorityQueue#offer(Object)
+     */
+    public void test_offer_Ljava_lang_Object_non_Comparable() {
+        PriorityQueue<Object> queue = new PriorityQueue<Object>();
+        queue.offer(new Integer(10));
+        try {
+            queue.offer(new Float(1.3));
+            fail("should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+
+        queue = new PriorityQueue<Object>();
+        queue.offer(new Integer(10));
+        try {
+            queue.offer(new Object());
+            fail("should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.PriorityQueue#poll()
+     */
+    public void test_poll() {
+        PriorityQueue<String> stringQueue = new PriorityQueue<String>();
+        String[] array = { "MYTESTSTRING", "AAAAA", "BCDEF", "ksTRD", "AAAAA" };
+        for (int i = 0; i < array.length; i++) {
+            stringQueue.offer(array[i]);
+        }
+        Arrays.sort(array);
+        for (int i = 0; i < array.length; i++) {
+            assertEquals(array[i], stringQueue.poll());
+        }
+        assertEquals(0, stringQueue.size());
+        assertNull(stringQueue.poll());
+    }
+
+    /**
+     * java.util.PriorityQueue#poll()
+     */
+    public void test_poll_empty() {
+        PriorityQueue<Object> queue = new PriorityQueue<Object>();
+        assertEquals(0, queue.size());
+        assertNull(queue.poll());
+    }
+
+    /**
+     * java.util.PriorityQueue#peek()
+     */
+    public void test_peek() {
+        PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+        int[] array = { 2, 45, 7, -12, 9 };
+        for (int i = 0; i < array.length; i++) {
+            integerQueue.add(array[i]);
+        }
+        Arrays.sort(array);
+        assertEquals(new Integer(array[0]), integerQueue.peek());
+        assertEquals(new Integer(array[0]), integerQueue.peek());
+    }
+
+    /**
+     * java.util.PriorityQueue#peek()
+     */
+    public void test_peek_empty() {
+        PriorityQueue<Object> queue = new PriorityQueue<Object>();
+        assertEquals(0, queue.size());
+        assertNull(queue.peek());
+        assertNull(queue.peek());
+    }
+
+    /**
+     * java.util.PriorityQueue#Clear()
+     */
+    public void test_clear() {
+        PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+        int[] array = { 2, 45, 7, -12, 9 };
+        for (int i = 0; i < array.length; i++) {
+            integerQueue.offer(array[i]);
+        }
+        integerQueue.clear();
+        assertTrue(integerQueue.isEmpty());
+    }
+
+    /**
+     * java.util.PriorityQueue#add(Object)
+     */
+    public void test_add_Ljava_lang_Object() {
+        PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+        Integer[] array = { 2, 45, 7, -12, 9 };
+        for (int i = 0; i < array.length; i++) {
+            integerQueue.add(array[i]);
+        }
+        Arrays.sort(array);
+        assertEquals(array.length, integerQueue.size());
+        for (int i = 0; i < array.length; i++) {
+            assertEquals(array[i], integerQueue.poll());
+        }
+        assertEquals(0, integerQueue.size());
+    }
+
+    /**
+     * java.util.PriorityQueue#add(Object)
+     */
+    public void test_add_Ljava_lang_Object_null() {
+        PriorityQueue<Object> queue = new PriorityQueue<Object>();
+        try {
+            queue.add(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.PriorityQueue#add(Object)
+     */
+    public void test_add_Ljava_lang_Object_non_Comparable() {
+        PriorityQueue<Object> queue = new PriorityQueue<Object>();
+        queue.add(new Integer(10));
+        try {
+            queue.add(new Float(1.3));
+            fail("should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+
+        queue = new PriorityQueue<Object>();
+        queue.add(new Integer(10));
+        try {
+            queue.add(new Object());
+            fail("should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.PriorityQueue#remove(Object)
+     */
+    public void test_remove_Ljava_lang_Object() {
+        Integer[] array = { 2, 45, 7, -12, 9, 23, 17, 1118, 10, 16, 39 };
+        List<Integer> list = Arrays.asList(array);
+        PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>(list);
+        assertTrue(integerQueue.remove(16));
+        Integer[] newArray = { 2, 45, 7, -12, 9, 23, 17, 1118, 10, 39 };
+        Arrays.sort(newArray);
+        for (int i = 0; i < newArray.length; i++) {
+            assertEquals(newArray[i], integerQueue.poll());
+        }
+        assertEquals(0, integerQueue.size());
+    }
+
+    /**
+     * java.util.PriorityQueue#remove(Object)
+     */
+    public void test_remove_Ljava_lang_Object_using_comparator() {
+        PriorityQueue<String> queue = new PriorityQueue<String>(10,
+                new MockComparatorStringByLength());
+        String[] array = { "AAAAA", "AA", "AAAA", "AAAAAAAA" };
+        for (int i = 0; i < array.length; i++) {
+            queue.offer(array[i]);
+        }
+        assertFalse(queue.contains("BB"));
+        assertTrue(queue.remove("AA"));
+    }
+
+    /**
+     * java.util.PriorityQueue#remove(Object)
+     */
+    public void test_remove_Ljava_lang_Object_not_exists() {
+        Integer[] array = { 2, 45, 7, -12, 9, 23, 17, 1118, 10, 16, 39 };
+        List<Integer> list = Arrays.asList(array);
+        PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>(list);
+        assertFalse(integerQueue.remove(111));
+        assertFalse(integerQueue.remove(null));
+        assertFalse(integerQueue.remove(""));
+    }
+
+    /**
+     * java.util.PriorityQueue#remove(Object)
+     */
+    public void test_remove_Ljava_lang_Object_null() {
+        Integer[] array = { 2, 45, 7, -12, 9, 23, 17, 1118, 10, 16, 39 };
+        List<Integer> list = Arrays.asList(array);
+        PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>(list);
+        assertFalse(integerQueue.remove(null));
+    }
+
+    /**
+     * java.util.PriorityQueue#remove(Object)
+     */
+    public void test_remove_Ljava_lang_Object_not_Compatible() {
+        Integer[] array = { 2, 45, 7, -12, 9, 23, 17, 1118, 10, 16, 39 };
+        List<Integer> list = Arrays.asList(array);
+        PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>(list);
+        assertFalse(integerQueue.remove(new Float(1.3F)));
+
+        // although argument element type is not compatible with those in queue,
+        // but comparator supports it.
+        MockComparator<Object> comparator = new MockComparator<Object>();
+        PriorityQueue<Integer> integerQueue1 = new PriorityQueue<Integer>(100,
+                comparator);
+        integerQueue1.offer(1);
+        assertFalse(integerQueue1.remove(new Float(1.3F)));
+
+        PriorityQueue<Object> queue = new PriorityQueue<Object>();
+        Object o = new Object();
+        queue.offer(o);
+        assertTrue(queue.remove(o));
+    }
+
+    /**
+     * java.util.PriorityQueue#comparator()
+     */
+    public void test_comparator() {
+        PriorityQueue<Object> queue = new PriorityQueue<Object>();
+        assertNull(queue.comparator());
+
+        MockComparator<Object> comparator = new MockComparator<Object>();
+        queue = new PriorityQueue<Object>(100, comparator);
+        assertEquals(comparator, queue.comparator());
+    }
+
+    /**
+     * serialization/deserialization.
+     */
+    public void test_Serialization() throws Exception {
+        Integer[] array = { 2, 45, 7, -12, 9, 23, 17, 1118, 10, 16, 39 };
+        List<Integer> list = Arrays.asList(array);
+        PriorityQueue<Integer> srcIntegerQueue = new PriorityQueue<Integer>(
+                list);
+        PriorityQueue<Integer> destIntegerQueue = (PriorityQueue<Integer>) SerializationTester
+                .getDeserilizedObject(srcIntegerQueue);
+        Arrays.sort(array);
+        for (int i = 0; i < array.length; i++) {
+            assertEquals(array[i], destIntegerQueue.poll());
+        }
+        assertEquals(0, destIntegerQueue.size());
+    }
+
+    /**
+     * serialization/deserialization.
+     */
+    public void test_Serialization_casting() throws Exception {
+        Integer[] array = { 2, 45, 7, -12, 9, 23, 17, 1118, 10, 16, 39 };
+        List<Integer> list = Arrays.asList(array);
+        PriorityQueue<Integer> srcIntegerQueue = new PriorityQueue<Integer>(
+                list);
+        PriorityQueue<String> destStringQueue = (PriorityQueue<String>) SerializationTester
+                .getDeserilizedObject(srcIntegerQueue);
+        // will not incur class cast exception.
+        Object o = destStringQueue.peek();
+        Arrays.sort(array);
+        Integer I = (Integer) o;
+        assertEquals(array[0], I);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void test_SerializationCompatibility_cast() throws Exception {
+        Integer[] array = { 2, 45, 7, -12, 9, 23, 17, 1118, 10, 16, 39 };
+        List<Integer> list = Arrays.asList(array);
+        PriorityQueue<Integer> srcIntegerQueue = new PriorityQueue<Integer>(
+                list);
+        PriorityQueue<String> destStringQueue = (PriorityQueue<String>) SerializationTester
+                .readObject(srcIntegerQueue, SERIALIZATION_FILE_NAME);
+
+        // will not incur class cast exception.
+        Object o = destStringQueue.peek();
+        Arrays.sort(array);
+        Integer I = (Integer) o;
+        assertEquals(array[0], I);
+    }
+
+    /**
+     * {@link PriorityQueue#contains(Object)}
+     */
+    public void test_contains() throws Exception {
+        PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+        Integer[] array = { 2, 45, 7, -12, 9 };
+        for (int i = 0; i < array.length; i++) {
+            integerQueue.add(array[i]);
+        }
+        for (int i = 0; i < array.length; i++) {
+            assertTrue(integerQueue.contains(array[i]));
+        }
+        assertFalse(integerQueue.contains(null));
+    }
+
+    /**
+     * {@link PriorityQueue#toArray()}
+     */
+    public void test_toArray() throws Exception {
+        PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+        Integer[] array = { 2, 45, 7, -12, 9 };
+        for (int i = 0; i < array.length; i++) {
+            integerQueue.add(array[i]);
+        }
+        Object[] returnArray = integerQueue.toArray();
+        assertEquals(returnArray.length, integerQueue.size());
+        for (int i = 0; i < returnArray.length; i++) {
+            assertTrue(integerQueue.contains(returnArray[i]));
+        }
+    }
+
+    /**
+     * {@link PriorityQueue#toArray(T[])}
+     */
+    public void test_toArray_$T() throws Exception {
+        PriorityQueue<Integer> integerQueue = new PriorityQueue<Integer>();
+        Integer[] array = { 2, 45, 7, -12, 9 };
+        for (int i = 0; i < array.length; i++) {
+            integerQueue.add(array[i]);
+        }
+        Object[] returnArray = integerQueue.toArray(new Integer[0]);
+        assertEquals(returnArray.length, integerQueue.size());
+        for (int i = 0; i < returnArray.length; i++) {
+            assertTrue(integerQueue.contains(returnArray[i]));
+        }
+        returnArray = integerQueue.toArray(new Integer[10]);
+        assertEquals(10, returnArray.length);
+        for (int i = 0; i < array.length; i++) {
+            assertTrue(integerQueue.contains(returnArray[i]));
+        }
+        for (int i = array.length; i < 10; i++) {
+            assertNull(returnArray[i]);
+        }
+        try {
+            integerQueue.toArray(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            integerQueue.toArray(new String[1]);
+            fail("should throw ArrayStoreException");
+        } catch (ArrayStoreException e) {
+            // expected
+        }
+    }
+
+    private static class MockComparator<E> implements Comparator<E> {
+
+        public int compare(E object1, E object2) {
+            int hashcode1 = object1.hashCode();
+            int hashcode2 = object2.hashCode();
+            if (hashcode1 > hashcode2) {
+                return 1;
+            } else if (hashcode1 == hashcode2) {
+                return 0;
+            } else {
+                return -1;
+            }
+        }
+    }
+
+    private static class MockComparatorStringByLength implements
+            Comparator<String> {
+
+        public int compare(String object1, String object2) {
+            int length1 = object1.length();
+            int length2 = object2.length();
+            if (length1 > length2) {
+                return 1;
+            } else if (length1 == length2) {
+                return 0;
+            } else {
+                return -1;
+            }
+        }
+
+    }
+
+    private static class MockComparatorCast<E> implements Comparator<E> {
+
+        public int compare(E object1, E object2) {
+            return 0;
+        }
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/util/PropertiesTest.java b/luni/src/test/java/tests/api/java/util/PropertiesTest.java
new file mode 100644
index 0000000..22a919c
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/PropertiesTest.java
@@ -0,0 +1,1267 @@
+/*
+ *  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.util;
+
+import java.io.BufferedReader;
+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.Reader;
+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;
+
+public class PropertiesTest extends junit.framework.TestCase {
+
+    Properties tProps;
+
+    byte[] propsFile;
+
+    /**
+     * java.util.Properties#Properties()
+     */
+    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
+        }
+    }
+
+    /**
+     * java.util.Properties#Properties(java.util.Properties)
+     */
+    public void test_ConstructorLjava_util_Properties() {
+        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));
+        }
+    }
+
+    /**
+     * java.util.Properties#getProperty(java.lang.String)
+     */
+    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",
+                ((String) tProps.getProperty("test.prop")));
+    }
+
+    /**
+     * java.util.Properties#getProperty(java.lang.String,
+     *java.lang.String)
+     */
+    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",
+                ((String) tProps.getProperty("test.prop", "Blarg")));
+        assertEquals("Did not return default value", "Gabba", ((String) tProps
+                .getProperty("notInThere.prop", "Gabba")));
+    }
+
+    /**
+     * java.util.Properties#getProperty(java.lang.String)
+     */
+    public void test_getPropertyLjava_lang_String2() {
+        // regression test for HARMONY-3518
+        MyProperties props = new MyProperties();
+        assertNull(props.getProperty("key"));
+    }
+
+    /**
+     * java.util.Properties#getProperty(java.lang.String,
+     *java.lang.String)
+     */
+    public void test_getPropertyLjava_lang_StringLjava_lang_String2() {
+        // regression test for HARMONY-3518
+        MyProperties props = new MyProperties();
+        assertEquals("defaultValue", props.getProperty("key", "defaultValue"));
+    }
+
+    // regression testing for HARMONY-3518
+    static class MyProperties extends Properties {
+        public synchronized Object get(Object key) {
+            return getProperty((String) key); // assume String
+        }
+    }
+
+    /**
+     * java.util.Properties#list(java.io.PrintStream)
+     */
+    public void test_listLjava_io_PrintStream() {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        PrintStream ps = new PrintStream(baos);
+        Properties myProps = new Properties();
+        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();
+        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
+        }
+    }
+
+    /**
+     * java.util.Properties#list(java.io.PrintWriter)
+     */
+    public void test_listLjava_io_PrintWriter() {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        PrintWriter pw = new PrintWriter(baos);
+        Properties myProps = new Properties();
+        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();
+        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
+        }
+    }
+
+    /**
+     * 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"));
+    }
+
+    /**
+     * 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
+     * java.util.Properties#load(java.io.Reader)
+     * @since 1.6
+     */
+    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
+                .getProperty("commented.entry"));
+
+        prop = new Properties();
+        prop.load(new ByteArrayInputStream("=".getBytes()));
+        assertEquals("Failed to add empty key", "", prop.get(""));
+
+        prop = new Properties();
+        prop.load(new ByteArrayInputStream(" = ".getBytes()));
+        assertEquals("Failed to add empty key2", "", prop.get(""));
+
+        prop = new Properties();
+        prop.load(new ByteArrayInputStream(" a= b".getBytes()));
+        assertEquals("Failed to ignore whitespace", "b", prop.get("a"));
+
+        prop = new Properties();
+        prop.load(new ByteArrayInputStream(" a b".getBytes()));
+        assertEquals("Failed to interpret whitespace as =", "b", prop.get("a"));
+
+        prop = new Properties();
+        prop.load(new ByteArrayInputStream("#comment\na=value"
+                .getBytes("UTF-8")));
+        assertEquals("value", prop.getProperty("a"));
+
+        prop = new Properties();
+        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"));
+
+        // Regression tests for HARMONY-5414
+        prop = new Properties();
+        prop.load(new ByteArrayInputStream("a=\\u1234z".getBytes()));
+
+        prop = new Properties();
+        try {
+            prop.load(new ByteArrayInputStream("a=\\u123".getBytes()));
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // 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);
+    }
+
+    /**
+     * 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
+     * java.util.Properties#load(java.io.Reader)
+     * @since 1.6
+     */
+    public void test_loadLjava_io_Reader_subtest0() throws IOException {
+        InputStream is = Support_Resources
+                .getStream("hyts_PropertiesTest.properties");
+        Properties props = new Properties();
+        props.load(new InputStreamReader(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"));
+    }
+
+    /**
+     * 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"));
+        }
+
+        // cast Enumeration to Iterator
+        Iterator iterator = (Iterator) names;
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+    }
+
+    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());
+    }
+
+    /**
+     * {@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
+        }
+    }
+
+    /**
+     * {@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);
+    }
+
+    /**
+     * {@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);
+    }
+
+    /**
+     * java.util.Properties#save(java.io.OutputStream, java.lang.String)
+     */
+    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");
+
+        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()) {
+            nextKey = (String) e.nextElement();
+            assertEquals("Stored property list not equal to original", myProps
+                    .getProperty(nextKey), myProps2.getProperty(nextKey));
+        }
+    }
+
+    /**
+     * java.util.Properties#setProperty(java.lang.String,
+     *java.lang.String)
+     */
+    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
+                .getProperty("Yoink"));
+        myProps.setProperty("Yoink", "Gab");
+        assertEquals("Failed to reset property", "Gab", myProps
+                .getProperty("Yoink"));
+    }
+
+    /**
+     * java.util.Properties#store(java.io.OutputStream, java.lang.String)
+     */
+    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");
+
+        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
+     * 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()) {
+            nextKey = (String) e.nextElement();
+            assertTrue("Stored property list not equal to original", myProps2
+                    .getProperty(nextKey).equals(myProps.getProperty(nextKey)));
+        }
+
+        try {
+            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
+        }
+    }
+
+    /**
+     * java.util.Properties#loadFromXML(java.io.InputStream)
+     */
+    public void test_loadFromXMLLjava_io_InputStream() throws Exception {
+        // Test for method void
+        // java.util.Properties.loadFromXML(java.io.InputStream)
+        Properties prop = null;
+        try {
+            InputStream is;
+            prop = new Properties();
+            prop.loadFromXML(is = new ByteArrayInputStream(
+                    writePropertiesXMLUTF_8()));
+            is.close();
+        } catch (Exception e) {
+            fail("Exception during load test : " + e.getMessage());
+        }
+        assertEquals("Failed to load correct properties", "value3", prop
+                .getProperty("key3"));
+        assertEquals("Failed to load correct properties", "value1", prop
+                .getProperty("key1"));
+
+        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
+                .getProperty("key1"));
+
+        try {
+            prop.loadFromXML(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.Properties#storeToXML(java.io.OutputStream,
+     *java.lang.String, java.lang.String)
+     */
+    public void test_storeToXMLLjava_io_OutputStreamLjava_lang_StringLjava_lang_String()
+            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");
+        myProps.setProperty("<a>key4</a>", "\"value4");
+        myProps.setProperty("key5   ", "<h>value5</h>");
+        myProps.setProperty("<a>key6</a>", "   <h>value6</h>   ");
+        myProps.setProperty("<comment>key7</comment>", "value7");
+        myProps.setProperty("  key8   ", "<comment>value8</comment>");
+        myProps.setProperty("&lt;key9&gt;", "\u0027value9");
+        myProps.setProperty("key10\"", "&lt;value10&gt;");
+        myProps.setProperty("&amp;key11&amp;", "value11");
+        myProps.setProperty("key12", "&amp;value12&amp;");
+        myProps.setProperty("<a>&amp;key13&lt;</a>",
+                "&amp;&value13<b>&amp;</b>");
+
+        try {
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+            // 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());
+        }
+
+        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)));
+        }
+
+        try {
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+            // 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()) {
+            nextKey = (String) e.nextElement();
+            assertTrue("Stored property list not equal to original", myProps2
+                    .getProperty(nextKey).equals(myProps.getProperty(nextKey)));
+        }
+
+        try {
+            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());
+    }
+
+    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());
+    }
+
+    public static class MockProperties extends Properties {
+
+        private static final long serialVersionUID = 1L;
+
+        public MockProperties() throws IOException {
+            mockLoad();
+        }
+
+        private void mockLoad() throws IOException {
+            super.load(new ByteArrayInputStream("key=value".getBytes()));
+        }
+
+        public void load(Reader reader) {
+            fail("should invoke Properties.load(Reader)");
+        }
+    }
+
+    public void test_loadLjava_io_InputStream_onLjava_io_Reader()
+            throws IOException {
+        MockProperties mockProperties = new MockProperties();
+        assertEquals(1, mockProperties.size());
+        assertEquals("value", mockProperties.get("key"));
+    }
+
+    private String comment1 = "comment1";
+
+    private String comment2 = "comment2";
+
+    private void validateOutput(String[] expectStrings, byte[] output)
+            throws IOException {
+        ByteArrayInputStream bais = new ByteArrayInputStream(output);
+        BufferedReader br = new BufferedReader(new InputStreamReader(bais,
+                "ISO8859_1"));
+        for (String expectString : expectStrings) {
+            assertEquals(expectString, br.readLine());
+        }
+        br.readLine();
+        assertNull(br.readLine());
+        br.close();
+    }
+
+    public void testStore_scenario0() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\r' + comment2);
+        validateOutput(new String[] { "#comment1", "#comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario1() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\n' + comment2);
+        validateOutput(new String[] { "#comment1", "#comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario2() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\r' + '\n' + comment2);
+        validateOutput(new String[] { "#comment1", "#comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario3() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\n' + '\r' + comment2);
+        validateOutput(new String[] { "#comment1", "#", "#comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario4() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\r' + '#' + comment2);
+        validateOutput(new String[] { "#comment1", "#comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario5() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\r' + '!' + comment2);
+        validateOutput(new String[] { "#comment1", "!comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario6() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\n' + '#' + comment2);
+        validateOutput(new String[] { "#comment1", "#comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario7() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\n' + '!' + comment2);
+        validateOutput(new String[] { "#comment1", "!comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario8() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\r' + '\n' + '#' + comment2);
+        validateOutput(new String[] { "#comment1", "#comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario9() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\n' + '\r' + '#' + comment2);
+        validateOutput(new String[] { "#comment1", "#", "#comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario10() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\r' + '\n' + '!' + comment2);
+        validateOutput(new String[] { "#comment1", "!comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario11() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\n' + '\r' + '!' + comment2);
+        validateOutput(new String[] { "#comment1", "#", "!comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testLoadReader() throws IOException {
+        InputStream inputStream = new ByteArrayInputStream(
+                "\u3000key=value".getBytes("UTF-8"));
+        Properties props = new Properties();
+        props.load(inputStream);
+        Enumeration<Object> keyEnum = props.keys();
+        assertFalse("\u3000key".equals(keyEnum.nextElement()));
+        assertFalse(keyEnum.hasMoreElements());
+        inputStream.close();
+
+        inputStream = new ByteArrayInputStream(
+                "\u3000key=value".getBytes("UTF-8"));
+        props = new Properties();
+        props.load(new InputStreamReader(inputStream, "UTF-8"));
+        keyEnum = props.keys();
+        assertEquals("\u3000key", keyEnum.nextElement());
+        assertFalse(keyEnum.hasMoreElements());
+        inputStream.close();
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() {
+
+        tProps = new Properties();
+        tProps.put("test.prop", "this is a test property");
+        tProps.put("bogus.prop", "bogus");
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
+    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();
+        ps = new PrintStream(bout);
+        ps.println("#commented.entry=Bogus");
+        ps.println("test.pkg=harmony.tests");
+        ps.println("test.proj=Automated Tests");
+        ps.close();
+        return bout.toByteArray();
+    }
+
+    protected byte[] writePropertiesXMLUTF_8() throws IOException {
+        PrintStream ps = null;
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        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>");
+        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();
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/RefSortedMap.java b/luni/src/test/java/tests/api/java/util/RefSortedMap.java
new file mode 100644
index 0000000..aa4eaa8
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/RefSortedMap.java
@@ -0,0 +1,402 @@
+/*
+ *  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.util;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.AbstractSet;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.SortedMap;
+
+public class RefSortedMap<K, V> extends java.util.AbstractMap<K, V>
+        implements SortedMap<K, V>, Cloneable, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final class MapEntry<K, V> implements Map.Entry<K, V> {
+
+        final K key;
+        V value;
+
+        MapEntry(K key, V value) {
+            this.key = key;
+            this.value = value;
+        }
+
+        public K getKey() {
+            return key;
+        }
+
+        public V getValue() {
+            return value;
+        }
+
+        public V setValue(V v) {
+            V res = value;
+            value = v;
+            return res;
+        }
+
+        public int hashCode() {
+            return (getKey() == null ? 0 : getKey().hashCode())
+                    ^ (getValue() == null ? 0 : getValue().hashCode());
+        }
+
+        public boolean equals(Object object) {
+            if (this == object) {
+                return true;
+            }
+            if (object instanceof Map.Entry) {
+                Map.Entry<?, ?> entry = (Map.Entry<?, ?>) object;
+                return (getKey() == null ? entry.getKey() == null : getKey().equals(entry
+                        .getKey()))
+                        && (getValue() == null ? entry.getValue() == null : getValue()
+                        .equals(entry.getValue()));
+            }
+            return false;
+        }
+    }
+
+    transient ArrayList<MapEntry<K, V>> entries = new ArrayList<MapEntry<K, V>>();
+    transient int modCnt;
+
+    private final Comparator<? super K> comparator;
+
+    class SubMap extends java.util.AbstractMap<K, V>
+            implements SortedMap<K, V>, Cloneable {
+
+        final boolean hasStart, hasEnd;
+        final K start, end;
+
+        SubMap(boolean hasFirst, K first, boolean hasLast, K last) {
+            this.hasStart = hasFirst;
+            this.start = first;
+            this.hasEnd = hasLast;
+            this.end = last;
+            if (hasStart && hasEnd && compare(start, end) >= 0) {
+                throw new IllegalArgumentException();
+            }
+        }
+
+        @Override
+        public Set<java.util.Map.Entry<K, V>> entrySet() {
+            return new AbstractSet<Entry<K, V>>() {
+
+                @Override
+                public Iterator<java.util.Map.Entry<K, V>> iterator() {
+                    return new Iterator<Entry<K, V>>() {
+                        int modCnt = RefSortedMap.this.modCnt;
+                        int offset = SubMap.this.size() > 0 ?
+                                bsearch(SubMap.this.firstKey()) - 1 :
+                                entries.size();
+
+                        public boolean hasNext() {
+                            if (modCnt != RefSortedMap.this.modCnt) {
+                                throw new ConcurrentModificationException();
+                            }
+                            return offset + 1 < entries.size()
+                                    && isInRange(entries.get(offset + 1).getKey());
+                        }
+
+                        public Map.Entry<K, V> next() {
+                            if (modCnt != RefSortedMap.this.modCnt) {
+                                throw new ConcurrentModificationException();
+                            }
+                            if (!hasNext()) {
+                                throw new NoSuchElementException();
+                            }
+                            offset++;
+                            return entries.get(offset);
+                        }
+
+                        public void remove() {
+                            if (modCnt != RefSortedMap.this.modCnt) {
+                                throw new ConcurrentModificationException();
+                            }
+                            modCnt++;
+                            RefSortedMap.this.modCnt++;
+                            RefSortedMap.this.entries.remove(offset);
+                            offset--;
+                        }
+
+                    };
+                }
+
+                @Override
+                public int size() {
+                    try {
+                        int lastIdx = bsearch(SubMap.this.lastKey());
+                        int firstIdx = bsearch(SubMap.this.firstKey());
+                        return lastIdx - firstIdx + 1;
+                    } catch (NoSuchElementException e) {
+                        return 0;
+                    } catch (ArrayIndexOutOfBoundsException e) {
+                        return 0;
+                    }
+                }
+
+            };
+        }
+
+        public Comparator<? super K> comparator() {
+            return RefSortedMap.this.comparator();
+        }
+
+        public K firstKey() {
+            if (!hasStart) {
+                K res = RefSortedMap.this.firstKey();
+                if (!isInRange(res)) {
+                    throw new NoSuchElementException();
+                }
+                return res;
+            }
+            int idx = bsearch(start);
+            if (idx >= 0) {
+                return start;
+            }
+            if (-idx - 1 >= entries.size() || !isInRange(entries.get(-idx - 1).getKey())) {
+                throw new NoSuchElementException();
+            }
+            return entries.get(-idx - 1).getKey();
+        }
+
+        public SortedMap<K, V> headMap(K key) {
+            if (!isInRange(key)) {
+                throw new IllegalArgumentException();
+            }
+            return new SubMap(hasStart, start, true, key);
+        }
+
+        public K lastKey() {
+            if (!hasEnd) {
+                K res = RefSortedMap.this.lastKey();
+                if (!isInRange(res)) {
+                    throw new NoSuchElementException();
+                }
+                return res;
+            }
+            int idx = bsearch(end);
+            idx = idx >= 0 ? idx - 1 : -idx - 2;
+            if (idx < 0 || !isInRange(entries.get(idx).getKey())) {
+                throw new NoSuchElementException();
+            }
+            return entries.get(idx).getKey();
+        }
+
+        public SortedMap<K, V> subMap(K startKey, K endKey) {
+            if (!isInRange(startKey)) {
+                throw new IllegalArgumentException();
+            }
+            if (!isInRange(endKey)) {
+                throw new IllegalArgumentException();
+            }
+            return new SubMap(true, startKey, true, endKey);
+        }
+
+        public SortedMap<K, V> tailMap(K key) {
+            if (!isInRange(key)) {
+                throw new IllegalArgumentException();
+            }
+            return new SubMap(true, key, hasEnd, end);
+        }
+
+        private boolean isInRange(K key) {
+            if (hasStart && compare(key, start) < 0) {
+                return false;
+            }
+            if (hasEnd && compare(key, end) >= 0) {
+                return false;
+            }
+            return true;
+        }
+
+    }
+
+    public RefSortedMap() {
+        this((Comparator<? super K>) null);
+    }
+
+    @SuppressWarnings("unchecked")
+    public int compare(K start, K end) {
+        return comparator != null ? comparator.compare(start, end)
+                : ((Comparable<K>) start).compareTo(end);
+    }
+
+    @SuppressWarnings("unchecked")
+    public RefSortedMap(Comparator<? super K> comparator) {
+        this.comparator = comparator;
+        cmp = createCmp();
+    }
+
+    public RefSortedMap(Map<? extends K, ? extends V> map) {
+        this();
+        putAll(map);
+    }
+
+    public RefSortedMap(SortedMap<K, ? extends V> map) {
+        this(map.comparator());
+        putAll(map);
+    }
+
+    public Comparator<? super K> comparator() {
+        return comparator;
+    }
+
+    public Set<Map.Entry<K, V>> entrySet() {
+        return tailMap(firstKey()).entrySet();
+    }
+
+    public K firstKey() {
+        return entries.get(0).getKey();
+    }
+
+    public SortedMap<K, V> headMap(K key) {
+        return new SubMap(false, null, true, key);
+    }
+
+    public Set<K> keySet() {
+        return tailMap(firstKey()).keySet();
+    }
+
+    public K lastKey() {
+        return entries.get(entries.size() - 1).getKey();
+    }
+
+    public SortedMap<K, V> subMap(K startKey, K endKey) {
+        return new SubMap(true, startKey, true, endKey);
+    }
+
+    public SortedMap<K, V> tailMap(K key) {
+        return new SubMap(true, key, false, null);
+    }
+
+    public Collection<V> values() {
+        return tailMap(firstKey()).values();
+    }
+
+    public void clear() {
+        entries.clear();
+    }
+
+    public boolean containsKey(Object arg0) {
+        return bsearch(arg0) >= 0;
+    }
+
+    public boolean containsValue(Object arg0) {
+        for (V v : values()) {
+            if (arg0.equals(v)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @SuppressWarnings("unchecked")
+    public V get(Object arg0) {
+        int idx = bsearch(arg0);
+        return idx >= 0 ? entries.get(idx).getValue() : null;
+    }
+
+    public boolean isEmpty() {
+        return entries.isEmpty();
+    }
+
+    public V put(K arg0, V arg1) {
+        modCnt++;
+        int idx = bsearch(arg0);
+        if (idx >= 0) {
+            return entries.get(idx).setValue(arg1);
+        }
+        entries.add(-idx - 1, new MapEntry<K, V>(arg0, arg1));
+        return null;
+    }
+
+    public void putAll(Map<? extends K, ? extends V> arg0) {
+        for (Map.Entry<? extends K, ? extends V> e : arg0.entrySet()) {
+            put(e.getKey(), e.getValue());
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public V remove(Object arg0) {
+        modCnt++;
+        int idx = bsearch(arg0);
+        if (idx < 0) {
+            return null;
+        }
+        return entries.remove(idx).getValue();
+    }
+
+    transient private Comparator<MapEntry<K, V>> cmp = createCmp();
+
+    Comparator<MapEntry<K, V>> createCmp() {
+        return new Comparator<MapEntry<K, V>>() {
+
+            public int compare(MapEntry<K, V> arg0, MapEntry<K, V> arg1) {
+                return RefSortedMap.this.compare(arg0.getKey(), arg1.getKey());
+            }
+
+        };
+    }
+
+    @SuppressWarnings("unchecked")
+    private int bsearch(Object arg0) {
+        return Collections.binarySearch(entries, new MapEntry<K, V>((K) arg0, null), cmp);
+    }
+
+    public int size() {
+        return entries.size();
+    }
+
+    public RefSortedMap<K, V> clone() {
+        return new RefSortedMap<K, V>(this);
+    }
+
+    private void writeObject(ObjectOutputStream stream) throws IOException {
+        stream.defaultWriteObject();
+        stream.writeInt(size());
+        for (Map.Entry<K, V> e : entrySet()) {
+            stream.writeObject(e.getKey());
+            stream.writeObject(e.getValue());
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private void readObject(ObjectInputStream stream) throws IOException,
+            ClassNotFoundException {
+
+        cmp = createCmp();
+        stream.defaultReadObject();
+        int size = stream.readInt();
+        entries = new ArrayList<MapEntry<K, V>>(size);
+        for (int i = 0; i < size; i++) {
+            put((K) stream.readObject(), (V) stream.readObject());
+        }
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/util/ServiceConfigurationErrorTest.java b/luni/src/test/java/tests/api/java/util/ServiceConfigurationErrorTest.java
new file mode 100644
index 0000000..51a0527
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/ServiceConfigurationErrorTest.java
@@ -0,0 +1,78 @@
+/*
+ *  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.util;
+
+import java.util.ServiceConfigurationError;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+/**
+ * Tests for java.util.ServiceConfigurationError
+ *
+ * @since 1.6
+ */
+public class ServiceConfigurationErrorTest extends TestCase {
+
+    /**
+     * {@link java.util.ServiceConfigurationError#ServiceConfigurationError(String)}
+     */
+    @SuppressWarnings("nls")
+    public void test_ConstructorLjava_lang_String() {
+        ServiceConfigurationError e = new ServiceConfigurationError("fixture");
+        assertEquals("fixture", e.getMessage());
+        assertNull(e.getCause());
+    }
+
+    /**
+     * {@link java.util.ServiceConfigurationError#ServiceConfigurationError(String, Throwable)}
+     */
+    @SuppressWarnings("nls")
+    public void test_ConstructorLjava_lang_StringLjava_lang_Throwable() {
+        IllegalArgumentException iae = new IllegalArgumentException(
+                "info in the IAE");
+        ServiceConfigurationError e = new ServiceConfigurationError("fixture",
+                iae);
+        assertEquals("fixture", e.getMessage());
+        assertEquals(iae, e.getCause());
+        assertEquals("info in the IAE", e.getCause().getMessage());
+    }
+
+    /**
+     * @throws Exception
+     * serialization/deserialization.
+     */
+    @SuppressWarnings("nls")
+    public void testSerializationSelf() throws Exception {
+        SerializationTest.verifySelf(new ServiceConfigurationError("fixture"));
+        SerializationTest.verifySelf(new ServiceConfigurationError("fixture",
+                new IllegalArgumentException("info in the IAE")));
+    }
+
+    /**
+     * @throws Exception
+     * serialization/deserialization compatibility with RI.
+     */
+    @SuppressWarnings("nls")
+    public void testSerializationCompatibility() throws Exception {
+        ServiceConfigurationError e = new ServiceConfigurationError("fixture",
+                new IllegalArgumentException("info in the IAE"));
+        SerializationTest.verifyGolden(this, e);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/ServiceLoaderTest.java b/luni/src/test/java/tests/api/java/util/ServiceLoaderTest.java
new file mode 100644
index 0000000..154077f
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/ServiceLoaderTest.java
@@ -0,0 +1,490 @@
+/*
+ *  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.util;
+
+import junit.framework.TestCase;
+import tests.resources.ServiceLoader.AbstractService;
+import tests.resources.ServiceLoader.Service;
+import tests.resources.ServiceLoader.ServiceDuplicateIn2File;
+import tests.resources.ServiceLoader.ServiceFinalClass;
+import tests.resources.ServiceLoader.ServiceForAllCommentTest;
+import tests.resources.ServiceLoader.ServiceForEmptyTest;
+import tests.resources.ServiceLoader.ServiceForIllegalNameTest;
+import tests.resources.ServiceLoader.ServiceForWrongNameTest;
+import tests.resources.ServiceLoader.ServiceIn2File;
+import tests.resources.ServiceLoader.ServiceIn2FileWithEmptyConfig;
+import tests.resources.ServiceLoader.ServiceMoreThanOne;
+import tests.resources.ServiceLoader.ServiceWithDuplicateSons;
+import tests.support.resource.Support_Resources;
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.ServiceConfigurationError;
+import java.util.ServiceLoader;
+
+/**
+ * Test cases for java.util.ServiceLoader
+ */
+public class ServiceLoaderTest extends TestCase {
+
+    private static URL jarFile = null;
+
+    /**
+     * @throws MalformedURLException
+     * {@link java.util.ServiceLoader#reload()}.
+     */
+    @SuppressWarnings("nls")
+    public void test_reload() throws MalformedURLException {
+        class SubURLClassLoader extends URLClassLoader {
+            /**
+             * @param urls
+             */
+            public SubURLClassLoader(URL[] urls) {
+                super(urls);
+            }
+
+            @Override
+            public void addURL(URL url) {
+                super.addURL(url);
+            }
+        }
+        SubURLClassLoader ucl = new SubURLClassLoader(new URL[] { new URL(
+                "file:/no/such/file") });
+        ServiceLoader<Service> serviceLoader = ServiceLoader.load(
+                Service.class, ucl);
+        Iterator<Service> itr = serviceLoader.iterator();
+        assertFalse(itr.hasNext());
+        // change the ucl to install a jar file
+        ucl.addURL(jarFile);
+        // before reload, the Iterator is unchanged
+        itr = serviceLoader.iterator();
+        assertNotSame(itr, serviceLoader.iterator());
+        assertFalse(itr.hasNext());
+        // after reload, the Iterator update
+        serviceLoader.reload();
+        itr = serviceLoader.iterator();
+        assertTrue(itr.hasNext());
+        assertEquals("ImplementationOfService", itr.next().myNameIs());
+        assertFalse(itr.hasNext());
+    }
+
+    /**
+     * {@link java.util.ServiceLoader#iterator()}.
+     */
+    @SuppressWarnings({ "nls", "unchecked" })
+    public void test_iterator() {
+        URLClassLoader ucl = new URLClassLoader(new URL[] { jarFile });
+        Iterator itr = ServiceLoader.load(Service.class, ucl).iterator();
+        assertTrue(itr.hasNext());
+        assertEquals("ImplementationOfService", ((Service) itr.next())
+                .myNameIs());
+        assertFalse(itr.hasNext());
+        try {
+            itr.remove();
+            fail("Should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+
+        itr = ServiceLoader.load(ServiceForWrongNameTest.class, ucl).iterator();
+        assertTrue(itr.hasNext());
+        try {
+            itr.next();
+            fail("Should throw ServiceConfigurationError");
+        } catch (ServiceConfigurationError e) {
+            // expected
+        }
+        try {
+            itr.remove();
+            fail("Should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+
+        // null test
+        itr = ServiceLoader.load(null).iterator();
+        nullIteratorTester(itr);
+
+        itr = ServiceLoader.load(null, null).iterator();
+        nullIteratorTester(itr);
+
+        itr = ServiceLoader.load(null, ClassLoader.getSystemClassLoader())
+                .iterator();
+        nullIteratorTester(itr);
+
+        itr = ServiceLoader.load(Service.class, null).iterator();
+        assertFalse(itr.hasNext());
+        try {
+            itr.next();
+            fail("Should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // expected
+        }
+        try {
+            itr.remove();
+            fail("Should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+    }
+
+    @SuppressWarnings({ "nls", "unchecked" })
+    private void nullIteratorTester(Iterator itr) {
+        assertNotNull(itr);
+        try {
+            itr.hasNext();
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            itr.next();
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            itr.remove();
+            fail("Should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @throws MalformedURLException
+     * {@link java.util.ServiceLoader#load(java.lang.Class, java.lang.ClassLoader)}.
+     */
+    @SuppressWarnings({ "nls", "unchecked" })
+    public void test_loadLjava_lang_ClassLjava_lang_ClassLoader()
+            throws MalformedURLException {
+        URLClassLoader ucl = new URLClassLoader(new URL[] { jarFile });
+        // normal config file
+        ServiceLoader serviceLoader = ServiceLoader.load(Service.class, ucl);
+        Iterator itr = serviceLoader.iterator();
+        assertTrue(itr.hasNext());
+        assertEquals("ImplementationOfService", ((Service) itr.next())
+                .myNameIs());
+        assertFalse(itr.hasNext());
+
+        // class that can not cast correctly
+        serviceLoader = ServiceLoader.load(ServiceFinalClass.class, ucl);
+        itr = serviceLoader.iterator();
+        assertTrue(itr.hasNext());
+        try {
+            itr.next();
+            fail("Should throw ServiceConfigurationError");
+        } catch (ServiceConfigurationError e) {
+            // expected
+        }
+
+        // abstract class with comment in config file
+        serviceLoader = ServiceLoader.load(AbstractService.class, ucl);
+        itr = serviceLoader.iterator();
+        assertTrue(itr.hasNext());
+        assertEquals("ImplementationOfAbstractService", ((AbstractService) itr
+                .next()).myNameIs());
+        assertFalse(itr.hasNext());
+
+        // one service with two implementation class
+        serviceLoader = ServiceLoader.load(ServiceMoreThanOne.class, ucl);
+        itr = serviceLoader.iterator();
+        assertTrue(itr.hasNext());
+        String name = ((ServiceMoreThanOne) itr.next()).myNameIs();
+        if ("ImplementationOfServiceMoreThanOne1".equals(name)) {
+            assertEquals("ImplementationOfServiceMoreThanOne2",
+                    ((ServiceMoreThanOne) itr.next()).myNameIs());
+        } else if ("ImplementationOfServiceMoreThanOne2".equals(name)) {
+            assertEquals("ImplementationOfServiceMoreThanOne1",
+                    ((ServiceMoreThanOne) itr.next()).myNameIs());
+        } else {
+            fail("Should load ImplementationOfServiceMoreThanOne1 or ImplementationOfServiceMoreThanOne2");
+        }
+        assertFalse(itr.hasNext());
+
+        // config file only contains comments
+        serviceLoader = ServiceLoader.load(ServiceForAllCommentTest.class, ucl);
+        itr = serviceLoader.iterator();
+        assertFalse(itr.hasNext());
+        try {
+            itr.next();
+            fail("Should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // expected
+        }
+
+        // empty config file
+        serviceLoader = ServiceLoader.load(ServiceForEmptyTest.class, ucl);
+        itr = serviceLoader.iterator();
+        assertFalse(itr.hasNext());
+        try {
+            itr.next();
+            fail("Should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // expected
+        }
+
+        // config file with illegal char
+        serviceLoader = ServiceLoader
+                .load(ServiceForIllegalNameTest.class, ucl);
+        itr = serviceLoader.iterator();
+        try {
+            itr.hasNext();
+            fail("Should throw ServiceConfigurationError");
+        } catch (ServiceConfigurationError e) {
+            // expected
+        }
+
+        // config file with legal string, but the class does not exist
+        serviceLoader = ServiceLoader.load(ServiceForWrongNameTest.class, ucl);
+        itr = serviceLoader.iterator();
+        assertTrue(itr.hasNext());
+        try {
+            itr.next();
+            fail("Should throw ServiceConfigurationError");
+        } catch (ServiceConfigurationError e) {
+            // expected
+        }
+
+        // config file for an internal class
+        serviceLoader = ServiceLoader.load(
+                AbstractService.InternalService.class, ucl);
+        itr = serviceLoader.iterator();
+        assertTrue(itr.hasNext());
+        assertEquals("ImplementationOfAbstractServiceInternalService",
+                ((AbstractService.InternalService) itr.next())
+                        .myInternalNameIs());
+        assertFalse(itr.hasNext());
+
+        // config files in the 2 jar files
+        serviceLoader = ServiceLoader.load(ServiceIn2File.class, ucl);
+        itr = serviceLoader.iterator();
+        assertTrue(itr.hasNext());
+        assertEquals("ImplementationOfServiceIn2File1", ((ServiceIn2File) itr
+                .next()).myNameIs());
+        assertFalse(itr.hasNext());
+        // add the second file
+        URL jarFile2 = prepareJar("hyts_services2.jar");
+        URLClassLoader ucl2 = new URLClassLoader(
+                new URL[] { jarFile, jarFile2 });
+        serviceLoader = ServiceLoader.load(ServiceIn2File.class, ucl2);
+        itr = serviceLoader.iterator();
+        assertTrue(itr.hasNext());
+        name = ((ServiceIn2File) itr.next()).myNameIs();
+        if ("ImplementationOfServiceIn2File1".equals(name)) {
+            assertEquals("ImplementationOfServiceIn2File2",
+                    ((ServiceIn2File) itr.next()).myNameIs());
+        } else if ("ImplementationOfServiceIn2File2".equals(name)) {
+            assertEquals("ImplementationOfServiceIn2File1",
+                    ((ServiceIn2File) itr.next()).myNameIs());
+        } else {
+            fail("Should load ImplementationOfServiceIn2File1 or ImplementationOfServiceIn2File2");
+        }
+        assertFalse(itr.hasNext());
+
+        // same config files in 2 jar files
+        serviceLoader = ServiceLoader.load(ServiceDuplicateIn2File.class, ucl2);
+        itr = serviceLoader.iterator();
+        assertTrue(itr.hasNext());
+        assertEquals("ImplementationOfServiceDuplicateIn2File_1",
+                ((ServiceDuplicateIn2File) itr.next()).myNameIs());
+        assertFalse(itr.hasNext());
+        ucl2 = new URLClassLoader(new URL[] { jarFile2, jarFile });
+        serviceLoader = ServiceLoader.load(ServiceDuplicateIn2File.class, ucl2);
+        itr = serviceLoader.iterator();
+        assertTrue(itr.hasNext());
+        assertEquals("ImplementationOfServiceDuplicateIn2File_2",
+                ((ServiceDuplicateIn2File) itr.next()).myNameIs());
+        assertFalse(itr.hasNext());
+
+        // one config file in one jar, another empty config in another jar.
+        serviceLoader = ServiceLoader.load(ServiceIn2FileWithEmptyConfig.class,
+                ucl);
+        itr = serviceLoader.iterator();
+        assertTrue(itr.hasNext());
+        assertEquals("ImplementationOfServiceIn2FileWithEmptyConfig",
+                ((ServiceIn2FileWithEmptyConfig) itr.next()).myNameIs());
+        assertFalse(itr.hasNext());
+        ucl2 = new URLClassLoader(new URL[] { jarFile, jarFile2 });
+        serviceLoader = ServiceLoader.load(ServiceIn2FileWithEmptyConfig.class,
+                ucl2);
+        itr = serviceLoader.iterator();
+        assertTrue(itr.hasNext());
+        assertEquals("ImplementationOfServiceIn2FileWithEmptyConfig",
+                ((ServiceIn2FileWithEmptyConfig) itr.next()).myNameIs());
+        assertFalse(itr.hasNext());
+
+        // config file with duplicate items
+        serviceLoader = ServiceLoader.load(ServiceWithDuplicateSons.class, ucl);
+        itr = serviceLoader.iterator();
+        assertTrue(itr.hasNext());
+        assertEquals("ImplementationOfServiceWithDuplicateSons",
+                ((ServiceWithDuplicateSons) itr.next()).myNameIs());
+        assertFalse(itr.hasNext());
+
+        // can not load by system classloader
+        serviceLoader = ServiceLoader.load(Service.class, ClassLoader
+                .getSystemClassLoader());
+        assertFalse(serviceLoader.iterator().hasNext());
+
+        // can not load by Thread.currentThread().getContextClassLoader()
+        serviceLoader = ServiceLoader.load(Service.class, Thread
+                .currentThread().getContextClassLoader());
+        assertFalse(serviceLoader.iterator().hasNext());
+
+        serviceLoader = ServiceLoader.load(Service.class, Service.class
+                .getClassLoader());
+        assertFalse(serviceLoader.iterator().hasNext());
+
+        // String is a final class, no sub-class for it
+        serviceLoader = ServiceLoader.load(String.class, ucl);
+        assertFalse(serviceLoader.iterator().hasNext());
+    }
+
+    /**
+     * {@link java.util.ServiceLoader#load(java.lang.Class)}.
+     */
+    @SuppressWarnings({ "nls", "unchecked" })
+    public void test_loadLjava_lang_Class() {
+        ServiceLoader serviceLoader = ServiceLoader.load(Service.class);
+        assertFalse(serviceLoader.iterator().hasNext());
+        // String is a final class, no sub-class for it
+        serviceLoader = ServiceLoader.load(String.class);
+        assertFalse(serviceLoader.iterator().hasNext());
+    }
+
+    /**
+     * @param fileName
+     * @return the URL of the jar file
+     * @throws MalformedURLException
+     */
+    @SuppressWarnings("nls")
+    private static URL prepareJar(String fileName) throws MalformedURLException {
+        File resources = Support_Resources.createTempFolder();
+        String resPath = resources.toString();
+        if (resPath.charAt(0) == '/' || resPath.charAt(0) == '\\') {
+            resPath = resPath.substring(1);
+        }
+        Support_Resources.copyFile(resources, "ServiceLoader", fileName);
+        URL resourceURL = new URL("file:/" + resPath + "/ServiceLoader/"
+                + fileName);
+        return resourceURL;
+    }
+
+    /**
+     * {@link java.util.ServiceLoader#loadInstalled(java.lang.Class)}.
+     */
+    public void test_loadInstalledLjava_lang_Class() {
+        ServiceLoader<Service> serviceLoader = ServiceLoader
+                .loadInstalled(Service.class);
+        assertFalse(serviceLoader.iterator().hasNext());
+
+        serviceLoader = ServiceLoader.loadInstalled(null);
+        Iterator<Service> itr = serviceLoader.iterator();
+        nullIteratorTester(itr);
+    }
+
+    /**
+     * {@link java.util.ServiceLoader#toString()}.
+     */
+    @SuppressWarnings({ "unchecked", "nls" })
+    public void test_toString() {
+        URLClassLoader ucl = new URLClassLoader(new URL[] { jarFile });
+        ServiceLoader serviceLoader = ServiceLoader.load(Service.class, ucl);
+        assertTrue(serviceLoader.toString().length() > 0);
+
+        serviceLoader = ServiceLoader.load(String.class, ucl);
+        assertTrue(serviceLoader.toString().length() > 0);
+
+        serviceLoader = ServiceLoader.load(Service.class);
+        assertTrue(serviceLoader.toString().length() > 0);
+
+        serviceLoader = ServiceLoader.load(String.class);
+        assertTrue(serviceLoader.toString().length() > 0);
+
+        serviceLoader = ServiceLoader.loadInstalled(Service.class);
+        assertTrue(serviceLoader.toString().length() > 0);
+
+        serviceLoader = ServiceLoader.loadInstalled(String.class);
+        assertTrue(serviceLoader.toString().length() > 0);
+
+        serviceLoader = ServiceLoader.load(null, ucl);
+        assertNotNull(serviceLoader);
+        try {
+            serviceLoader.toString();
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        serviceLoader = ServiceLoader.load(null, null);
+        assertNotNull(serviceLoader);
+        try {
+            serviceLoader.toString();
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        serviceLoader = ServiceLoader.load(Service.class, null);
+        assertTrue(serviceLoader.toString().length() > 0);
+
+        serviceLoader = ServiceLoader.load(null);
+        assertNotNull(serviceLoader);
+        try {
+            serviceLoader.toString();
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        serviceLoader = ServiceLoader.loadInstalled(null);
+        assertNotNull(serviceLoader);
+        try {
+            serviceLoader.toString();
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @see junit.framework.TestCase#setUp()
+     */
+    @SuppressWarnings("nls")
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        jarFile = prepareJar("hyts_services.jar");
+    }
+
+    /**
+     * @see junit.framework.TestCase#tearDown()
+     */
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        new File(jarFile.getFile()).delete();
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/util/SimpleEntryTest.java b/luni/src/test/java/tests/api/java/util/SimpleEntryTest.java
new file mode 100644
index 0000000..106ef2b
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/SimpleEntryTest.java
@@ -0,0 +1,122 @@
+/*
+ *  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.util;
+
+import java.util.AbstractMap;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.Map.Entry;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+import tests.util.SerializationTester;
+
+public class SimpleEntryTest extends TestCase {
+    public void test_SimpleEntry_Constructor_K_V() throws Exception {
+        new AbstractMap.SimpleEntry<Integer, String>(1, "test");
+        new AbstractMap.SimpleEntry(null, null);
+    }
+
+    public void test_SimpleEntry_Constructor_LEntry() throws Exception {
+        Map map = new TreeMap();
+        map.put(1, "test");
+        Entry entryToPut = (Entry) map.entrySet().iterator().next();
+        Entry testEntry = new AbstractMap.SimpleEntry(entryToPut);
+        assertEquals(1, testEntry.getKey());
+        assertEquals("test", testEntry.getValue());
+        map.clear();
+        map.put(null, null);
+        entryToPut = (Entry) map.entrySet().iterator().next();
+        testEntry = new AbstractMap.SimpleEntry(entryToPut);
+        assertNull(testEntry.getKey());
+        assertNull(testEntry.getValue());
+        try {
+            new AbstractMap.SimpleEntry(null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+    }
+
+    public void test_SimpleEntry_getKey() throws Exception {
+        Entry entry = new AbstractMap.SimpleEntry<Integer, String>(1, "test");
+        assertEquals(1, entry.getKey());
+        entry = new AbstractMap.SimpleEntry(null, null);
+        assertNull(entry.getKey());
+    }
+
+    public void test_SimpleEntry_getValue() throws Exception {
+        Entry entry = new AbstractMap.SimpleEntry<Integer, String>(1, "test");
+        assertEquals("test", entry.getValue());
+        entry = new AbstractMap.SimpleEntry(null, null);
+        assertNull(entry.getValue());
+    }
+
+    public void test_SimpleEntry_setValue() throws Exception {
+        Entry entry = new AbstractMap.SimpleEntry<Integer, String>(1, "test");
+        assertEquals("test", entry.getValue());
+        entry.setValue("Another String");
+        assertEquals("Another String", entry.getValue());
+        entry = new AbstractMap.SimpleEntry(null, null);
+        assertNull(entry.getKey());
+    }
+
+    public void test_SimpleEntry_equals() throws Exception {
+        Entry entry = new AbstractMap.SimpleEntry<Integer, String>(1, "test");
+        Map map = new TreeMap();
+        map.put(1, "test");
+        Entry entryToPut = (Entry) map.entrySet().iterator().next();
+        Entry testEntry = new AbstractMap.SimpleEntry(entryToPut);
+        assertEquals(entry, testEntry);
+        Entry ent = new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "test");
+        assertEquals(entry, ent);
+    }
+
+    public void test_SimpleEntry_hashCode() throws Exception {
+        Entry e = new AbstractMap.SimpleEntry<Integer, String>(1, "test");
+        assertEquals((e.getKey() == null ? 0 : e.getKey().hashCode())
+                ^ (e.getValue() == null ? 0 : e.getValue().hashCode()), e
+                .hashCode());
+    }
+
+    public void test_SimpleEntry_toString() throws Exception {
+        Entry e = new AbstractMap.SimpleEntry<Integer, String>(1, "test");
+        assertEquals(e.getKey() + "=" + e.getValue(), e.toString());
+    }
+
+    /**
+     * serialization/deserialization.
+     */
+    @SuppressWarnings({ "unchecked", "boxing" })
+    public void testSerializationSelf_SimpleEntry() throws Exception {
+        Entry e = new AbstractMap.SimpleEntry<Integer, String>(1, "test");
+        SerializationTest.verifySelf(e);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    @SuppressWarnings({ "unchecked", "boxing" })
+    public void testSerializationCompatibility_SimpleEntry() throws Exception {
+        SimpleEntry e = new AbstractMap.SimpleEntry<Integer, String>(1, "test");
+        SerializationTester.assertCompabilityEquals(e, "serialization/java/util/AbstractMapTest_SimpleEntry.golden.ser");
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/SimpleImmutableEntryTest.java b/luni/src/test/java/tests/api/java/util/SimpleImmutableEntryTest.java
new file mode 100644
index 0000000..c018e1d
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/SimpleImmutableEntryTest.java
@@ -0,0 +1,135 @@
+/*
+ *  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.util;
+
+import java.lang.reflect.Array;
+import java.util.AbstractMap;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.AbstractMap.SimpleImmutableEntry;
+import java.util.Map.Entry;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+import tests.util.SerializationTester;
+
+public class SimpleImmutableEntryTest extends TestCase {
+    public void test_SimpleImmutableEntry_Constructor_K_V() throws Exception {
+        new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "test");
+        new AbstractMap.SimpleImmutableEntry(null, null);
+    }
+
+    public void test_SimpleImmutableEntry_Constructor_LEntry() throws Exception {
+        Map map = new TreeMap();
+        map.put(1, "test");
+        Entry entryToPut = (Entry) map.entrySet().iterator().next();
+        Entry testEntry = new AbstractMap.SimpleImmutableEntry(entryToPut);
+        assertEquals(1, testEntry.getKey());
+        assertEquals("test", testEntry.getValue());
+        map.clear();
+        map.put(null, null);
+        entryToPut = (Entry) map.entrySet().iterator().next();
+        testEntry = new AbstractMap.SimpleImmutableEntry(entryToPut);
+        assertNull(testEntry.getKey());
+        assertNull(testEntry.getValue());
+        try {
+            new AbstractMap.SimpleImmutableEntry(null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+    }
+
+    public void test_SimpleImmutableEntry_getKey() throws Exception {
+        Entry entry = new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "test");
+        assertEquals(1, entry.getKey());
+        entry = new AbstractMap.SimpleImmutableEntry(null, null);
+        assertNull(entry.getKey());
+    }
+
+    public void test_SimpleImmutableEntry_getValue() throws Exception {
+        Entry entry = new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "test");
+        assertEquals("test", entry.getValue());
+        entry = new AbstractMap.SimpleImmutableEntry(null, null);
+        assertNull(entry.getValue());
+    }
+
+    public void test_SimpleImmutableEntry_setValue() throws Exception {
+        Entry entry = new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "test");
+        assertEquals("test", entry.getValue());
+        try {
+            entry.setValue("Another String");
+            fail("should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+        assertEquals("test", entry.getValue());
+        try {
+            entry.setValue(null);
+            fail("should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+    }
+
+    public void test_SimpleImmutableEntry_equals() throws Exception {
+        Entry entry = new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "test");
+        Map map = new TreeMap();
+        map.put(1, "test");
+        Entry entryToPut = (Entry) map.entrySet().iterator().next();
+        Entry testEntry = new AbstractMap.SimpleImmutableEntry(entryToPut);
+        assertEquals(entry, testEntry);
+    }
+
+    public void test_SimpleImmutableEntry_hashCode() throws Exception {
+        Entry e = new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "test");
+        assertEquals((e.getKey() == null ? 0 : e.getKey().hashCode())
+                ^ (e.getValue() == null ? 0 : e.getValue().hashCode()), e
+                .hashCode());
+    }
+
+    public void test_SimpleImmutableEntry_toString() throws Exception {
+        Entry e = new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "test");
+        assertEquals(e.getKey() + "=" + e.getValue(), e.toString());
+        Object array = Array.newInstance((byte[].class).getComponentType(), 10);
+        assertEquals(10, ((byte[]) array).length);
+    }
+
+    /**
+     * serialization/deserialization.
+     */
+    @SuppressWarnings({ "unchecked", "boxing" })
+    public void testSerializationSelf_SimpleImmutableEntry() throws Exception {
+        Entry e = new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "test");
+        SerializationTest.verifySelf(e);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    @SuppressWarnings({ "unchecked", "boxing" })
+    public void testSerializationCompatibility_SimpleImmutableEntry() throws Exception {
+        SimpleImmutableEntry e = new AbstractMap.SimpleImmutableEntry<Integer, String>(1, "test");
+        if (!(SerializationTester.readObject(e, "serialization/java/util/AbstractMapTest_SimpleImmutableEntry.golden.ser") instanceof SimpleImmutableEntry)) {
+            fail("should be SimpleImmutableEntry");
+        }
+        SerializationTester.assertCompabilityEquals(e, "serialization/java/util/AbstractMapTest_SimpleImmutableEntry.golden.ser");
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/SortedMapTestBase.java b/luni/src/test/java/tests/api/java/util/SortedMapTestBase.java
new file mode 100644
index 0000000..fbf2646
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/SortedMapTestBase.java
@@ -0,0 +1,369 @@
+/*
+ *  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.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Random;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import junit.framework.TestCase;
+
+public abstract class SortedMapTestBase extends TestCase {
+
+    final int N = 1000;
+    final int TRIES = 100;
+
+    SortedMap<Integer, Integer> map;
+    SortedMap<Integer, Integer> ref;
+
+    Random rnd;
+
+    protected void setUp() throws Exception {
+        rnd = new Random(-1);
+        for (int i = 0; i < N; i++) {
+            ref.put(rnd.nextInt(N) * 2, rnd.nextBoolean() ? null : rnd.nextInt(N) * 2);
+        }
+    }
+
+    public final void testClear() {
+        map.clear();
+        assertTrue(map.isEmpty());
+    }
+
+    public final void testContainsKey() {
+        for (int i = 0; i < TRIES; i++) {
+            int key = rnd.nextInt(N);
+            assertEquals(ref.containsKey(key), map.containsKey(key));
+        }
+    }
+
+
+    public final void testContainsValue() {
+        for (int i = 0; i < TRIES; i++) {
+            int value = rnd.nextInt(N);
+            assertEquals(ref.containsValue(value), map.containsValue(value));
+        }
+    }
+
+
+    public final void testEntrySet() {
+        Set<Map.Entry<Integer, Integer>> refSet = ref.entrySet();
+        Set<Map.Entry<Integer, Integer>> mapSet = map.entrySet();
+        for (Map.Entry<Integer, Integer> e : refSet) {
+            assertTrue(mapSet.contains(e));
+        }
+        for (Map.Entry<Integer, Integer> e : mapSet) {
+            assertTrue(refSet.contains(e));
+        }
+        assertEquals(ref.entrySet(), map.entrySet());
+    }
+
+
+    public final void testGet() {
+        for (int i = 0; i < TRIES; i++) {
+            int key = rnd.nextInt(N);
+            assertEquals(ref.get(key), map.get(key));
+        }
+    }
+
+
+    public final void testKeySet() {
+        assertEquals(ref.keySet(), map.keySet());
+        Iterator<Integer> i = ref.keySet().iterator();
+        Iterator<Integer> j = map.keySet().iterator();
+        while (i.hasNext()) {
+            assertEquals(i.next(), j.next());
+            if (rnd.nextBoolean()) {
+                j.remove();
+                i.remove();
+            }
+        }
+    }
+
+
+    public final void testPut() {
+        for (int i = 0; i < TRIES; i++) {
+            int key = rnd.nextInt(N);
+            int value = rnd.nextInt(N);
+            assertEquals(ref.put(key, value), map.put(key, value));
+            assertEquals(ref.get(key), map.get(key));
+            assertEquals(ref, map);
+        }
+    }
+
+    public final void testPut0() {
+        ref.clear();
+        map.clear();
+        for (int i = 0; i < N; i++) {
+            int key = rnd.nextInt(N);
+            int value = rnd.nextInt(N);
+            assertEquals(ref.put(key, value), map.put(key, value));
+            assertEquals(ref.get(key), map.get(key));
+        }
+    }
+
+    public final void testPutAll() {
+        Map<Integer, Integer> mixin = new HashMap<Integer, Integer>(TRIES);
+        for (int i = 0; i < TRIES; i++) {
+            mixin.put(rnd.nextInt(N), rnd.nextInt(N));
+        }
+        ref.putAll(mixin);
+        map.putAll(mixin);
+        assertEquals(ref, map);
+    }
+
+
+    public final void testRemove() {
+        for (int i = 0; i < N; i++) {
+            int key = rnd.nextInt(N);
+            assertEquals(ref.remove(key), map.remove(key));
+            if (i % (N / TRIES) == 0) {
+                assertEquals(ref, map);
+            }
+        }
+    }
+
+    public final void testRemove0() {
+        while (!ref.isEmpty()) {
+            int key = ref.tailMap((ref.firstKey() + ref.lastKey()) / 2)
+                    .firstKey();
+            assertEquals(ref.remove(key), map.remove(key));
+        }
+    }
+
+    public final void testSize() {
+        assertEquals(ref.size(), map.size());
+    }
+
+
+    public final void testValues() {
+        assertEquals(ref.values().size(), map.values().size());
+        assertTrue(ref.values().containsAll(map.values()));
+        assertTrue(map.values().containsAll(ref.values()));
+
+        Iterator<Integer> i = ref.values().iterator();
+        Iterator<Integer> j = map.values().iterator();
+        while (i.hasNext()) {
+            assertEquals(i.next(), j.next());
+            if (rnd.nextBoolean()) {
+                j.remove();
+                i.remove();
+            }
+        }
+    }
+
+    public final void testComparator() {
+        assertEquals(ref.comparator(), map.comparator());
+    }
+
+
+    public final void testFirstKey() {
+        assertEquals(ref.firstKey(), map.firstKey());
+    }
+
+
+    public final void testHeadMap() {
+        for (int i = 0; i < TRIES; i++) {
+            int key = rnd.nextInt(N);
+            checkSubMap(ref.headMap(key), map.headMap(key));
+        }
+        checkSubMap(ref.headMap(-1), map.headMap(-1));
+    }
+
+    public final void testLastKey() {
+        assertEquals(ref.lastKey(), map.lastKey());
+    }
+
+    public final void testSubMap() {
+        for (int i = 0; i < TRIES; i++) {
+            int key0 = rnd.nextInt(N / 2);
+            int key1 = rnd.nextInt(N / 2) + N / 2;
+            if (ref.comparator() != null &&
+                    ref.comparator().compare(key0, key1) > 0) {
+
+                int tmp = key0;
+                key0 = key1;
+                key1 = tmp;
+            }
+            checkSubMap(ref.subMap(key0, key1), map.subMap(key0, key1));
+        }
+        boolean caught = false;
+        try {
+            if (ref.comparator() != null && ref.comparator().compare(100, 0) < 0) {
+                map.subMap(0, 100);
+            } else {
+                map.subMap(100, 0);
+            }
+        } catch (IllegalArgumentException e) {
+            caught = true;
+        }
+        assertTrue(caught);
+
+        int firstKey = ref.firstKey();
+        Map.Entry<Integer, Integer> refE = ref.entrySet().iterator().next();
+        Map.Entry<Integer, Integer> mapE = map.entrySet().iterator().next();
+        mapE.setValue(-1);
+        refE.setValue(-1);
+        assertEquals(ref.get(firstKey), map.get(firstKey));
+    }
+
+
+    public final void testTailMap() {
+        for (int i = 0; i < TRIES; i++) {
+            int key = rnd.nextInt(2 * N);
+            checkSubMap(ref.tailMap(key), map.tailMap(key));
+        }
+        checkSubMap(ref.tailMap(2 * N + 1), map.tailMap(2 * N + 1));
+    }
+
+
+    public final void testHashCode() {
+        assertEquals(ref.hashCode(), map.hashCode());
+    }
+
+    public final void testEqualsObject() {
+        assertTrue(map.equals(ref));
+        map.put(N + 1, N + 1);
+        assertFalse(map.equals(ref));
+    }
+
+
+    public final void testIsEmpty() {
+        assertEquals(ref.isEmpty(), map.isEmpty());
+    }
+
+    public final void testIsEmpty2() {
+        TreeMap<String, String> map = new TreeMap<String, String>();
+        map.put("one", "1");
+        assertEquals("size should be one", 1, map.size());
+        map.clear();
+        assertEquals("size should be zero", 0, map.size());
+        assertTrue("Should not have entries", !map.entrySet().iterator()
+                .hasNext());
+
+        map.put("one", "1");
+        assertEquals("size should be one", 1, map.size());
+        map.remove("one");
+        assertEquals("size should be zero", 0, map.size());
+        assertTrue("Should not have entries", !map.entrySet().iterator()
+                .hasNext());
+
+        map.clear();
+        map.put("0", "1");
+        map.clear();
+        assertTrue(map.isEmpty());
+        assertFalse(map.entrySet().iterator().hasNext());
+        assertFalse(map.keySet().iterator().hasNext());
+        assertFalse(map.values().iterator().hasNext());
+    }
+
+    public final void testToString() {
+        assertEquals(ref.toString(), map.toString());
+    }
+
+    private void checkSubMap(SortedMap<Integer, Integer> ref,
+            SortedMap<Integer, Integer> map) {
+
+        assertEquals(ref.size(), map.size());
+        assertEquals(ref, map);
+        assertEquals(ref.isEmpty(), map.isEmpty());
+        if (!ref.isEmpty()) {
+            assertEquals(ref.firstKey(), map.firstKey());
+            assertEquals(ref.lastKey(), map.lastKey());
+
+            testViews(ref, map);
+        } else {
+            boolean caught = false;
+            try {
+                map.firstKey();
+            } catch (NoSuchElementException e) {
+                caught = true;
+            }
+            caught = false;
+            try {
+                map.lastKey();
+            } catch (NoSuchElementException e) {
+                caught = true;
+            }
+            assertTrue(caught);
+        }
+
+    }
+
+    public final void testViews() {
+        testViews(ref, map);
+    }
+
+    private void testViews(SortedMap<Integer, Integer> ref, SortedMap<Integer, Integer> map) {
+        assertEquals(ref.keySet().size(), map.keySet().size());
+        assertEquals(ref.keySet(), map.keySet());
+        compareIterators(ref.keySet(), map.keySet());
+
+        assertEquals(ref.values().size(), map.values().size());
+        compareIterators(ref.values(), map.values());
+
+        assertEquals(ref.entrySet(), map.entrySet());
+        compareIterators(ref.entrySet(), map.entrySet());
+    }
+
+    private void compareIterators(Collection ref, Collection map) {
+        Iterator i = ref.iterator();
+        Iterator j = map.iterator();
+        while (i.hasNext()) {
+            assertEquals(i.next(), j.next());
+            if (rnd.nextBoolean()) {
+                j.remove();
+                i.remove();
+                assertEquals(ref.size(), map.size());
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public final void testSerialization() throws IOException, ClassNotFoundException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+        oos.writeObject(map);
+        oos.close();
+        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
+        Object read = ois.readObject();
+        assertEquals(ref, read);
+    }
+
+    public final void testClone() throws Exception {
+        Method refClone = ref.getClass().getMethod("clone", new Class[0]);
+        Method mapClone = map.getClass().getMethod("clone", new Class[0]);
+        SortedMap<Integer, Integer> map2 = (SortedMap<Integer, Integer>) mapClone.invoke(map, new Object[0]);
+        assertEquals(refClone.invoke(ref, new Object[0]), map2);
+        map2.remove(map2.lastKey());
+        assertFalse(ref.equals(map2));
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/util/TimeZoneTest.java b/luni/src/test/java/tests/api/java/util/TimeZoneTest.java
new file mode 100644
index 0000000..8d9cfb8
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/TimeZoneTest.java
@@ -0,0 +1,278 @@
+/*
+ *  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.util;
+
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Formatter;
+import java.util.GregorianCalendar;
+import java.util.List;
+import java.util.Locale;
+import java.util.SimpleTimeZone;
+import java.util.TimeZone;
+
+import tests.support.Support_TimeZone;
+
+public class TimeZoneTest extends junit.framework.TestCase {
+
+    private static final int ONE_HOUR = 3600000;
+
+    /**
+     * java.util.TimeZone#getDefault()
+     */
+    public void test_getDefault() {
+        assertNotSame("returns identical",
+                TimeZone.getDefault(), TimeZone.getDefault());
+    }
+
+    /**
+     * java.util.TimeZone#getDSTSavings()
+     */
+    public void test_getDSTSavings() {
+        // Test for method int java.util.TimeZone.getDSTSavings()
+
+        // test on subclass SimpleTimeZone
+        TimeZone st1 = TimeZone.getTimeZone("EST");
+        assertEquals("T1A. Incorrect daylight savings returned",
+                ONE_HOUR, st1.getDSTSavings());
+
+        // a SimpleTimeZone with daylight savings different then 1 hour
+        st1 = TimeZone.getTimeZone("Australia/Lord_Howe");
+        assertEquals("T1B. Incorrect daylight savings returned",
+                1800000, st1.getDSTSavings());
+
+        // test on subclass Support_TimeZone, an instance with daylight savings
+        TimeZone tz1 = new Support_TimeZone(-5 * ONE_HOUR, true);
+        assertEquals("T2. Incorrect daylight savings returned",
+                ONE_HOUR, tz1.getDSTSavings());
+
+        // an instance without daylight savings
+        tz1 = new Support_TimeZone(3 * ONE_HOUR, false);
+        assertEquals("T3. Incorrect daylight savings returned, ",
+                0, tz1.getDSTSavings());
+    }
+
+    /**
+     * java.util.TimeZone#getOffset(long)
+     */
+    public void test_getOffset_long() {
+        // Test for method int java.util.TimeZone.getOffset(long time)
+
+        // test on subclass SimpleTimeZone
+        TimeZone st1 = TimeZone.getTimeZone("EST");
+        long time1 = new GregorianCalendar(1998, Calendar.NOVEMBER, 11)
+                .getTimeInMillis();
+        assertEquals("T1. Incorrect offset returned",
+                -(5 * ONE_HOUR), st1.getOffset(time1));
+
+        long time2 = new GregorianCalendar(1998, Calendar.JUNE, 11)
+                .getTimeInMillis();
+        st1 = TimeZone.getTimeZone("EST");
+        assertEquals("T2. Incorrect offset returned",
+                -(5 * ONE_HOUR), st1.getOffset(time2));
+
+        // test on subclass Support_TimeZone, an instance with daylight savings
+        TimeZone tz1 = new Support_TimeZone(-5 * ONE_HOUR, true);
+        assertEquals("T3. Incorrect offset returned, ",
+                -(5 * ONE_HOUR), tz1.getOffset(time1));
+        assertEquals("T4. Incorrect offset returned, ",
+                -(4 * ONE_HOUR), tz1.getOffset(time2));
+
+        // an instance without daylight savings
+        tz1 = new Support_TimeZone(3 * ONE_HOUR, false);
+        assertEquals("T5. Incorrect offset returned, ",
+                (3 * ONE_HOUR), tz1.getOffset(time1));
+        assertEquals("T6. Incorrect offset returned, ",
+                (3 * ONE_HOUR), tz1.getOffset(time2));
+    }
+
+    /**
+     * java.util.TimeZone#getTimeZone(java.lang.String)
+     */
+    public void test_getTimeZoneLjava_lang_String() {
+        assertEquals("Must return GMT when given an invalid TimeZone id SMT-8.",
+                "GMT", TimeZone.getTimeZone("SMT-8").getID());
+        assertEquals("Must return GMT when given an invalid TimeZone time GMT+28:70.",
+                "GMT", TimeZone.getTimeZone("GMT+28:70").getID());
+        assertEquals("Must return GMT when given an invalid TimeZone time GMT+28:30.",
+                "GMT", TimeZone.getTimeZone("GMT+28:30").getID());
+        assertEquals("Must return GMT when given an invalid TimeZone time GMT+8:70.",
+                "GMT", TimeZone.getTimeZone("GMT+8:70").getID());
+        assertEquals("Must return GMT when given an invalid TimeZone time GMT+3:.",
+                "GMT", TimeZone.getTimeZone("GMT+3:").getID());
+        assertEquals("Must return GMT when given an invalid TimeZone time GMT+3:0.",
+                "GMT", TimeZone.getTimeZone("GMT+3:0").getID());
+        assertEquals("Must return GMT when given an invalid TimeZone time GMT+2360.",
+                "GMT", TimeZone.getTimeZone("GMT+2360").getID());
+        assertEquals("Must return GMT when given an invalid TimeZone time GMT+892.",
+                "GMT", TimeZone.getTimeZone("GMT+892").getID());
+        assertEquals("Must return GMT when given an invalid TimeZone time GMT+082.",
+                "GMT", TimeZone.getTimeZone("GMT+082").getID());
+        assertEquals("Must return GMT when given an invalid TimeZone time GMT+28.",
+                "GMT", TimeZone.getTimeZone("GMT+28").getID());
+        assertEquals("Must return GMT when given an invalid TimeZone time GMT+30.",
+                "GMT", TimeZone.getTimeZone("GMT+30").getID());
+        assertEquals("Must return GMT when given TimeZone GMT.",
+                "GMT", TimeZone.getTimeZone("GMT").getID());
+        assertEquals("Must return GMT when given TimeZone GMT+.",
+                "GMT", TimeZone.getTimeZone("GMT+").getID());
+        assertEquals("Must return GMT when given TimeZone GMT-.",
+                "GMT", TimeZone.getTimeZone("GMT-").getID());
+        assertEquals("Must return GMT when given an invalid TimeZone time GMT-8.45.",
+                "GMT", TimeZone.getTimeZone("GMT-8.45").getID());
+        assertEquals("Must return GMT when given an invalid TimeZone time GMT-123:23.",
+                "GMT", TimeZone.getTimeZone("GMT-123:23").getID());
+        assertEquals("Must return proper GMT formatted string for GMT+8:30 (eg. GMT+08:20).",
+                "GMT+08:30", TimeZone.getTimeZone("GMT+8:30").getID());
+        assertEquals("Must return proper GMT formatted string for GMT+3 (eg. GMT+08:20).",
+                "GMT+03:00", TimeZone.getTimeZone("GMT+3").getID());
+        assertEquals("Must return proper GMT formatted string for GMT+3:02 (eg. GMT+08:20).",
+                "GMT+03:02", TimeZone.getTimeZone("GMT+3:02").getID());
+        assertEquals("Must return proper GMT formatted string for GMT+2359 (eg. GMT+08:20).",
+                "GMT+23:59", TimeZone.getTimeZone("GMT+2359").getID());
+        assertEquals("Must return proper GMT formatted string for GMT+520 (eg. GMT+08:20).",
+                "GMT+05:20", TimeZone.getTimeZone("GMT+520").getID());
+        assertEquals("Must return proper GMT formatted string for GMT+052 (eg. GMT+08:20).",
+                "GMT+00:52", TimeZone.getTimeZone("GMT+052").getID());
+        // GMT-0 is an available ID in ICU, so replace it with GMT-00
+        assertEquals("Must return proper GMT formatted string for GMT-00 (eg. GMT+08:20).",
+                "GMT-00:00", TimeZone.getTimeZone("GMT-00").getID());
+    }
+
+    /**
+     * java.util.TimeZone#setDefault(java.util.TimeZone)
+     */
+    public void test_setDefaultLjava_util_TimeZone() {
+        TimeZone oldDefault = TimeZone.getDefault();
+        TimeZone zone = new SimpleTimeZone(45, "TEST");
+        TimeZone.setDefault(zone);
+        assertEquals("timezone not set", zone, TimeZone.getDefault());
+        TimeZone.setDefault(null);
+        assertEquals("default not restored",
+                oldDefault, TimeZone.getDefault());
+    }
+
+    /**
+     * java.util.TimeZone#getDisplayName(java.util.Locale)
+     */
+    public void test_getDisplayNameLjava_util_Locale() {
+        TimeZone timezone = TimeZone.getTimeZone("Asia/Shanghai");
+        assertEquals("\u4e2d\u56fd\u6807\u51c6\u65f6\u95f4", timezone
+                .getDisplayName(Locale.CHINA));
+    }
+
+    /**
+     * java.util.TimeZone#getDisplayName(boolean, int, java.util.Locale)
+     */
+    public void test_getDisplayNameZILjava_util_Locale() {
+        TimeZone timezone = TimeZone.getTimeZone("Asia/Shanghai");
+        /* Time zone data was changed in ICU49.2.  Many common short names were removed. */
+        assertEquals("中国标准时间",
+                timezone.getDisplayName(false, TimeZone.LONG, Locale.CHINA));
+        assertEquals("GMT+0800",
+                timezone.getDisplayName(false, TimeZone.SHORT, Locale.CHINA));
+        try {
+            timezone.getDisplayName(false, 100, Locale.CHINA);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    /*
+     * Regression for HARMONY-5860
+     */
+    public void test_GetTimezoneOffset() {
+        // America/Toronto is lazy initialized 
+        TimeZone.setDefault(TimeZone.getTimeZone("America/Toronto"));
+        Date date = new Date(07, 2, 24);
+        assertEquals(300, date.getTimezoneOffset());
+        date = new Date(99, 8, 1);
+        assertEquals(240, date.getTimezoneOffset());
+    }
+
+    protected void setUp() {
+    }
+
+    protected void tearDown() {
+    }
+
+    /**
+     * @add test {@link java.util.TimeZone#getAvailableIDs(int)}
+     */
+    public void test_getAvailableIDs_I() {
+        TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
+        int rawoffset = tz.getRawOffset();
+        String[] ids = TimeZone.getAvailableIDs(rawoffset);
+        List<String> idList = Arrays.asList(ids);
+        assertTrue("Asia/shanghai and Hongkong should have the same rawoffset",
+                idList.contains("Hongkong"));
+    }
+
+    /**
+     * @add test {@link java.util.TimeZone#getDisplayName()}
+     */
+    public void test_getDisplayName() {
+        TimeZone defaultZone = TimeZone.getDefault();
+        Locale defaulLocal = Locale.getDefault();
+        String defaultName = defaultZone.getDisplayName();
+        String expectedName = defaultZone.getDisplayName(defaulLocal);
+        assertEquals(
+                "getDispalyName() did not return the default Locale suitable name",
+                expectedName, defaultName);
+    }
+
+    /**
+     * @add test {@link java.util.TimeZone#getDisplayName(boolean, int)}
+     */
+    public void test_getDisplayName_ZI() {
+        TimeZone defaultZone = TimeZone.getDefault();
+        Locale defaultLocale = Locale.getDefault();
+        String actualName = defaultZone.getDisplayName(false, TimeZone.LONG);
+        String expectedName = defaultZone.getDisplayName(false, TimeZone.LONG,
+                defaultLocale);
+        assertEquals(
+                "getDisplayName(daylight,style) did not return the default locale suitable name",
+                expectedName, actualName);
+    }
+
+    /**
+     * @add test {@link java.util.TimeZone#hasSameRules(TimeZone)}
+     */
+    public void test_hasSameRules_Ljava_util_TimeZone() {
+        TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
+        int offset = tz.getRawOffset();
+
+        String[] ids = TimeZone.getAvailableIDs(offset);
+        int i = 0;
+        if (ids.length != 0) {
+            while (true) {
+                if (!(ids[i].equalsIgnoreCase(tz.getID()))) {
+                    TimeZone sameZone = TimeZone.getTimeZone(ids[i]);
+                    assertTrue(tz.hasSameRules(sameZone));
+                    break;
+                } else {
+                    i++;
+                }
+            }
+        }
+        assertFalse("should return false when parameter is null", tz
+                .hasSameRules(null));
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/TreeMapExtendTest.java b/luni/src/test/java/tests/api/java/util/TreeMapExtendTest.java
new file mode 100644
index 0000000..f43039e
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/TreeMapExtendTest.java
@@ -0,0 +1,13498 @@
+package tests.api.java.util;
+
+/*
+ *  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.
+ */
+
+import junit.framework.TestCase;
+import tests.api.java.util.TreeMapTest.MockComparator;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.NavigableSet;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+
+// 
+public class TreeMapExtendTest extends TestCase {
+
+    TreeMap tm;
+
+    TreeMap tm_comparator;
+
+    SortedMap subMap_default;
+
+    SortedMap subMap_startExcluded_endExcluded;
+
+    SortedMap subMap_startExcluded_endIncluded;
+
+    SortedMap subMap_startIncluded_endExcluded;
+
+    SortedMap subMap_startIncluded_endIncluded;
+
+    SortedMap subMap_default_beforeStart_100;
+
+    SortedMap subMap_default_afterEnd_109;
+
+    NavigableMap navigableMap_startExcluded_endExcluded;
+
+    NavigableMap navigableMap_startExcluded_endIncluded;
+
+    NavigableMap navigableMap_startIncluded_endExcluded;
+
+    NavigableMap navigableMap_startIncluded_endIncluded;
+
+    SortedMap subMap_default_comparator;
+
+    SortedMap subMap_startExcluded_endExcluded_comparator;
+
+    SortedMap subMap_startExcluded_endIncluded_comparator;
+
+    SortedMap subMap_startIncluded_endExcluded_comparator;
+
+    SortedMap subMap_startIncluded_endIncluded_comparator;
+
+    Object objArray[] = new Object[1000];
+
+    public void test_TreeMap_Constructor_Default() {
+        TreeMap treeMap = new TreeMap();
+        assertTrue(treeMap.isEmpty());
+        assertNull(treeMap.comparator());
+        assertEquals(0, treeMap.size());
+
+        try {
+            treeMap.firstKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+        assertNull(treeMap.firstEntry());
+
+        try {
+            treeMap.lastKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+        assertNull(treeMap.lastEntry());
+
+        try {
+            treeMap.ceilingKey(1);
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+        assertNull(treeMap.ceilingEntry(1));
+
+        try {
+            treeMap.floorKey(1);
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+        assertNull(treeMap.floorEntry(1));
+        assertNull(treeMap.lowerKey(1));
+        assertNull(treeMap.lowerEntry(1));
+        assertNull(treeMap.higherKey(1));
+        assertNull(treeMap.higherEntry(1));
+        assertFalse(treeMap.containsKey(1));
+        assertFalse(treeMap.containsValue(1));
+        assertNull(treeMap.get(1));
+
+        assertNull(treeMap.pollFirstEntry());
+        assertNull(treeMap.pollLastEntry());
+        assertEquals(0, treeMap.values().size());
+    }
+
+    public void test_TreeMap_Constructor_Comparator() {
+        MockComparator mockComparator = new MockComparator();
+        TreeMap treeMap = new TreeMap(mockComparator);
+
+        assertEquals(mockComparator, treeMap.comparator());
+    }
+
+    public void test_TreeMap_Constructor_Map() {
+        TreeMap treeMap = new TreeMap(tm);
+        assertEquals(tm.size(), treeMap.size());
+        assertEquals(tm.firstKey(), treeMap.firstKey());
+        assertEquals(tm.firstEntry(), treeMap.firstEntry());
+        assertEquals(tm.lastKey(), treeMap.lastKey());
+        assertEquals(tm.lastEntry(), treeMap.lastEntry());
+        assertEquals(tm.keySet(), treeMap.keySet());
+
+        String key = new Integer(100).toString();
+        assertEquals(tm.ceilingKey(key), treeMap.ceilingKey(key));
+        assertEquals(tm.ceilingEntry(key), treeMap.ceilingEntry(key));
+        assertEquals(tm.floorKey(key), treeMap.floorKey(key));
+        assertEquals(tm.floorEntry(key), treeMap.floorEntry(key));
+        assertEquals(tm.lowerKey(key), treeMap.lowerKey(key));
+        assertEquals(tm.lowerEntry(key), treeMap.lowerEntry(key));
+        assertEquals(tm.higherKey(key), treeMap.higherKey(key));
+        assertEquals(tm.higherEntry(key), treeMap.higherEntry(key));
+        assertEquals(tm.entrySet(), treeMap.entrySet());
+    }
+
+    public void test_TreeMap_Constructor_SortedMap() {
+        TreeMap treeMap = new TreeMap(subMap_default);
+        assertEquals(subMap_default.size(), treeMap.size());
+        assertEquals(subMap_default.firstKey(), treeMap.firstKey());
+        assertEquals(subMap_default.lastKey(), treeMap.lastKey());
+        assertEquals(subMap_default.keySet(), treeMap.keySet());
+        assertEquals(subMap_default.entrySet(), treeMap.entrySet());
+    }
+
+    public void test_TreeMap_clear() {
+        tm.clear();
+        assertEquals(0, tm.size());
+    }
+
+    public void test_TreeMap_clone() {
+        TreeMap cloneTreeMap = (TreeMap) tm.clone();
+        assertEquals(tm, cloneTreeMap);
+    }
+
+    public void test_SubMap_Constructor() {
+    }
+
+    public void test_SubMap_clear() {
+        subMap_default.clear();
+        assertEquals(0, subMap_default.size());
+    }
+
+    public void test_SubMap_comparator() {
+        assertEquals(tm.comparator(), subMap_default.comparator());
+    }
+
+    public void test_SubMap_containsKey() {
+        String key = null;
+        for (int counter = 101; counter < 109; counter++) {
+            key = objArray[counter].toString();
+            assertTrue("SubMap contains incorrect elements", subMap_default
+                    .containsKey(key));
+            assertTrue("SubMap contains incorrect elements",
+                    subMap_startExcluded_endExcluded.containsKey(key));
+            assertTrue("SubMap contains incorrect elements",
+                    subMap_startExcluded_endIncluded.containsKey(key));
+            assertTrue("SubMap contains incorrect elements",
+                    subMap_startIncluded_endExcluded.containsKey(key));
+            assertTrue("SubMap contains incorrect elements",
+                    subMap_startIncluded_endIncluded.containsKey(key));
+        }
+
+        // Check boundary
+        key = objArray[100].toString();
+        assertTrue("SubMap contains incorrect elements", subMap_default
+                .containsKey(key));
+        assertFalse("SubMap contains incorrect elements",
+                subMap_startExcluded_endExcluded.containsKey(key));
+        assertFalse("SubMap contains incorrect elements",
+                subMap_startExcluded_endIncluded.containsKey(key));
+        assertTrue("SubMap contains incorrect elements",
+                subMap_startIncluded_endExcluded.containsKey(key));
+        assertTrue("SubMap contains incorrect elements",
+                subMap_startIncluded_endIncluded.containsKey(key));
+
+        key = objArray[109].toString();
+        assertFalse("SubMap contains incorrect elements", subMap_default
+                .containsKey(key));
+        assertFalse("SubMap contains incorrect elements",
+                subMap_startExcluded_endExcluded.containsKey(key));
+        assertTrue("SubMap contains incorrect elements",
+                subMap_startExcluded_endIncluded.containsKey(key));
+        assertFalse("SubMap contains incorrect elements",
+                subMap_startIncluded_endExcluded.containsKey(key));
+        assertTrue("SubMap contains incorrect elements",
+                subMap_startIncluded_endIncluded.containsKey(key));
+
+        // With Comparator
+        for (int counter = 101; counter < 109; counter++) {
+            key = objArray[counter].toString();
+            assertTrue("SubMap contains incorrect elements",
+                    subMap_default_comparator.containsKey(key));
+            assertTrue("SubMap contains incorrect elements",
+                    subMap_startExcluded_endExcluded_comparator
+                            .containsKey(key));
+            assertTrue("SubMap contains incorrect elements",
+                    subMap_startExcluded_endIncluded_comparator
+                            .containsKey(key));
+            assertTrue("SubMap contains incorrect elements",
+                    subMap_startIncluded_endExcluded_comparator
+                            .containsKey(key));
+            assertTrue("SubMap contains incorrect elements",
+                    subMap_startIncluded_endIncluded_comparator
+                            .containsKey(key));
+        }
+
+        // Check boundary
+        key = objArray[100].toString();
+        assertTrue("SubMap contains incorrect elements",
+                subMap_default_comparator.containsKey(key));
+        assertFalse("SubMap contains incorrect elements",
+                subMap_startExcluded_endExcluded_comparator.containsKey(key));
+        assertFalse("SubMap contains incorrect elements",
+                subMap_startExcluded_endIncluded_comparator.containsKey(key));
+        assertTrue("SubMap contains incorrect elements",
+                subMap_startIncluded_endExcluded_comparator.containsKey(key));
+        assertTrue("SubMap contains incorrect elements",
+                subMap_startIncluded_endIncluded_comparator.containsKey(key));
+
+        key = objArray[109].toString();
+        assertFalse("SubMap contains incorrect elements",
+                subMap_default_comparator.containsKey(key));
+        assertFalse("SubMap contains incorrect elements",
+                subMap_startExcluded_endExcluded_comparator.containsKey(key));
+        assertTrue("SubMap contains incorrect elements",
+                subMap_startExcluded_endIncluded_comparator.containsKey(key));
+        assertFalse("SubMap contains incorrect elements",
+                subMap_startIncluded_endExcluded_comparator.containsKey(key));
+        assertTrue("SubMap contains incorrect elements",
+                subMap_startIncluded_endIncluded_comparator.containsKey(key));
+    }
+
+    public void test_SubMap_containsValue() {
+        Object value = null;
+        for (int counter = 101; counter < 109; counter++) {
+            value = objArray[counter];
+            assertTrue("SubMap contains incorrect elements", subMap_default
+                    .containsValue(value));
+            assertTrue("SubMap contains incorrect elements",
+                    subMap_startExcluded_endExcluded.containsValue(value));
+            assertTrue("SubMap contains incorrect elements",
+                    subMap_startExcluded_endIncluded.containsValue(value));
+            assertTrue("SubMap contains incorrect elements",
+                    subMap_startIncluded_endExcluded.containsValue(value));
+            assertTrue("SubMap contains incorrect elements",
+                    subMap_startIncluded_endIncluded.containsValue(value));
+        }
+
+        // Check boundary
+        value = objArray[100];
+        assertTrue("SubMap contains incorrect elements", subMap_default
+                .containsValue(value));
+        assertFalse("SubMap contains incorrect elements",
+                subMap_startExcluded_endExcluded.containsValue(value));
+        assertFalse("SubMap contains incorrect elements",
+                subMap_startExcluded_endIncluded.containsValue(value));
+        assertTrue("SubMap contains incorrect elements",
+                subMap_startIncluded_endExcluded.containsValue(value));
+        assertTrue("SubMap contains incorrect elements",
+                subMap_startIncluded_endIncluded.containsValue(value));
+
+        value = objArray[109];
+        assertFalse("SubMap contains incorrect elements", subMap_default
+                .containsValue(value));
+        assertFalse("SubMap contains incorrect elements",
+                subMap_startExcluded_endExcluded.containsValue(value));
+        assertTrue("SubMap contains incorrect elements",
+                subMap_startExcluded_endIncluded.containsValue(value));
+        assertFalse("SubMap contains incorrect elements",
+                subMap_startIncluded_endExcluded.containsValue(value));
+        assertTrue("SubMap contains incorrect elements",
+                subMap_startIncluded_endIncluded.containsValue(value));
+
+        assertFalse(subMap_default.containsValue(null));
+
+        TreeMap tm_null = new TreeMap();
+        tm_null.put("0", 1);
+        tm_null.put("1", null);
+        tm_null.put("2", 2);
+        SortedMap subMap = tm_null.subMap("0", "2");
+        assertTrue(subMap.containsValue(null));
+
+        subMap.remove("1");
+        assertFalse(subMap.containsValue(null));
+    }
+
+    public void test_SubMap_entrySet() {
+        Set entrySet = subMap_default.entrySet();
+        assertFalse(entrySet.isEmpty());
+        assertEquals(9, entrySet.size());
+
+        entrySet = subMap_startExcluded_endExcluded.entrySet();
+        assertFalse(entrySet.isEmpty());
+        assertEquals(8, entrySet.size());
+
+        entrySet = subMap_startExcluded_endIncluded.entrySet();
+        assertFalse(entrySet.isEmpty());
+        assertEquals(9, entrySet.size());
+
+        entrySet = subMap_startIncluded_endExcluded.entrySet();
+        assertFalse(entrySet.isEmpty());
+        assertEquals(9, entrySet.size());
+
+        entrySet = subMap_startIncluded_endIncluded.entrySet();
+        assertFalse(entrySet.isEmpty());
+        assertEquals(10, entrySet.size());
+    }
+
+    public void test_SubMap_firstKey() {
+        String firstKey1 = new Integer(100).toString();
+        String firstKey2 = new Integer(101).toString();
+        assertEquals(firstKey1, subMap_default.firstKey());
+        assertEquals(firstKey2, subMap_startExcluded_endExcluded.firstKey());
+        assertEquals(firstKey2, subMap_startExcluded_endIncluded.firstKey());
+        assertEquals(firstKey1, subMap_startIncluded_endExcluded.firstKey());
+        assertEquals(firstKey1, subMap_startIncluded_endIncluded.firstKey());
+
+        try {
+            subMap_default.subMap(firstKey1, firstKey1).firstKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endExcluded.subMap(firstKey2, firstKey2)
+                    .firstKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endIncluded.subMap(firstKey2, firstKey2)
+                    .firstKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endExcluded.subMap(firstKey1, firstKey1)
+                    .firstKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endIncluded.subMap(firstKey1, firstKey1)
+                    .firstKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        // With Comparator
+        assertEquals(firstKey1, subMap_default_comparator.firstKey());
+        assertEquals(firstKey2, subMap_startExcluded_endExcluded_comparator
+                .firstKey());
+        assertEquals(firstKey2, subMap_startExcluded_endIncluded_comparator
+                .firstKey());
+        assertEquals(firstKey1, subMap_startIncluded_endExcluded_comparator
+                .firstKey());
+        assertEquals(firstKey1, subMap_startIncluded_endIncluded_comparator
+                .firstKey());
+
+        try {
+            subMap_default_comparator.subMap(firstKey1, firstKey1).firstKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endExcluded_comparator.subMap(firstKey2,
+                    firstKey2).firstKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endIncluded_comparator.subMap(firstKey2,
+                    firstKey2).firstKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endExcluded_comparator.subMap(firstKey1,
+                    firstKey1).firstKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endIncluded_comparator.subMap(firstKey1,
+                    firstKey1).firstKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+    }
+
+    public void test_SubMap_lastKey() {
+        String lastKey1 = new Integer(108).toString();
+        String lastKey2 = new Integer(109).toString();
+        assertEquals(lastKey1, subMap_default.lastKey());
+        assertEquals(lastKey1, subMap_startExcluded_endExcluded.lastKey());
+        assertEquals(lastKey2, subMap_startExcluded_endIncluded.lastKey());
+        assertEquals(lastKey1, subMap_startIncluded_endExcluded.lastKey());
+        assertEquals(lastKey2, subMap_startIncluded_endIncluded.lastKey());
+
+        try {
+            subMap_default.subMap(lastKey1, lastKey1).lastKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endExcluded.subMap(lastKey1, lastKey1)
+                    .lastKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endIncluded.subMap(lastKey2, lastKey2)
+                    .lastKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endExcluded.subMap(lastKey1, lastKey1)
+                    .lastKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endIncluded.subMap(lastKey2, lastKey2)
+                    .lastKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        // With Comparator
+        assertEquals(lastKey1, subMap_default_comparator.lastKey());
+        assertEquals(lastKey1, subMap_startExcluded_endExcluded_comparator
+                .lastKey());
+        assertEquals(lastKey2, subMap_startExcluded_endIncluded_comparator
+                .lastKey());
+        assertEquals(lastKey1, subMap_startIncluded_endExcluded_comparator
+                .lastKey());
+        assertEquals(lastKey2, subMap_startIncluded_endIncluded_comparator
+                .lastKey());
+
+        try {
+            subMap_default_comparator.subMap(lastKey1, lastKey1).lastKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endExcluded_comparator.subMap(lastKey1,
+                    lastKey1).lastKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endIncluded_comparator.subMap(lastKey2,
+                    lastKey2).lastKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endExcluded_comparator.subMap(lastKey1,
+                    lastKey1).lastKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endIncluded_comparator.subMap(lastKey2,
+                    lastKey2).lastKey();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+    }
+
+    public void test_SubMap_get() {
+        // left boundary
+        Integer value = new Integer(100);
+        assertEquals(value, subMap_default.get(value.toString()));
+        assertEquals(null, subMap_startExcluded_endExcluded.get(value
+                .toString()));
+        assertEquals(null, subMap_startExcluded_endIncluded.get(value
+                .toString()));
+        assertEquals(value, subMap_startIncluded_endExcluded.get(value
+                .toString()));
+        assertEquals(value, subMap_startIncluded_endIncluded.get(value
+                .toString()));
+
+        // normal value
+        value = new Integer(105);
+        assertEquals(value, subMap_default.get(value.toString()));
+        assertEquals(value, subMap_startExcluded_endExcluded.get(value
+                .toString()));
+        assertEquals(value, subMap_startExcluded_endIncluded.get(value
+                .toString()));
+        assertEquals(value, subMap_startIncluded_endExcluded.get(value
+                .toString()));
+        assertEquals(value, subMap_startIncluded_endIncluded.get(value
+                .toString()));
+
+        // right boundary
+        value = new Integer(109);
+        assertEquals(null, subMap_default.get(value.toString()));
+        assertEquals(null, subMap_startExcluded_endExcluded.get(value
+                .toString()));
+        assertEquals(value, subMap_startExcluded_endIncluded.get(value
+                .toString()));
+        assertEquals(null, subMap_startIncluded_endExcluded.get(value
+                .toString()));
+        assertEquals(value, subMap_startIncluded_endIncluded.get(value
+                .toString()));
+
+        // With Comparator to test inInRange
+        // left boundary
+        value = new Integer(100);
+        assertEquals(value, subMap_default_comparator.get(value.toString()));
+
+        // normal value
+        value = new Integer(105);
+        assertEquals(value, subMap_default_comparator.get(value.toString()));
+
+        // right boundary
+        value = new Integer(109);
+        assertEquals(null, subMap_default_comparator.get(value.toString()));
+    }
+
+    public void test_SubMap_headMap() {
+        String endKey = new Integer(99).toString();
+        try {
+            subMap_default.headMap(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endExcluded.headMap(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endIncluded.headMap(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endExcluded.headMap(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endIncluded.headMap(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        SortedMap headMap = null;
+        endKey = new Integer(100).toString();
+        headMap = subMap_default.headMap(endKey);
+        assertEquals(0, headMap.size());
+
+        headMap = subMap_startExcluded_endExcluded.headMap(endKey);
+        assertEquals(0, headMap.size());
+
+        headMap = subMap_startExcluded_endIncluded.headMap(endKey);
+        assertEquals(0, headMap.size());
+
+        headMap = subMap_startIncluded_endExcluded.headMap(endKey);
+        assertEquals(0, headMap.size());
+
+        headMap = subMap_startIncluded_endIncluded.headMap(endKey);
+        assertEquals(0, headMap.size());
+
+        for (int i = 0, j = 101; i < 8; i++) {
+            endKey = new Integer(i + j).toString();
+            headMap = subMap_default.headMap(endKey);
+            assertEquals(i + 1, headMap.size());
+
+            headMap = subMap_startExcluded_endExcluded.headMap(endKey);
+            assertEquals(i, headMap.size());
+
+            headMap = subMap_startExcluded_endIncluded.headMap(endKey);
+            assertEquals(i, headMap.size());
+
+            headMap = subMap_startIncluded_endExcluded.headMap(endKey);
+            assertEquals(i + 1, headMap.size());
+
+            headMap = subMap_startIncluded_endIncluded.headMap(endKey);
+            assertEquals(i + 1, headMap.size());
+        }
+
+        endKey = new Integer(109).toString();
+        headMap = subMap_default.headMap(endKey);
+        assertEquals(9, headMap.size());
+
+        headMap = subMap_startExcluded_endExcluded.headMap(endKey);
+        assertEquals(8, headMap.size());
+
+        headMap = subMap_startExcluded_endIncluded.headMap(endKey);
+        assertEquals(8, headMap.size());
+
+        headMap = subMap_startIncluded_endExcluded.headMap(endKey);
+        assertEquals(9, headMap.size());
+
+        headMap = subMap_startIncluded_endIncluded.headMap(endKey);
+        assertEquals(9, headMap.size());
+
+        endKey = new Integer(110).toString();
+        try {
+            subMap_default.headMap(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endExcluded.headMap(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endIncluded.headMap(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endExcluded.headMap(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endIncluded.headMap(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        // With Comparator
+        endKey = new Integer(99).toString();
+        try {
+            subMap_default_comparator.headMap(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endExcluded_comparator.headMap(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endIncluded_comparator.headMap(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endExcluded_comparator.headMap(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endIncluded_comparator.headMap(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        headMap = null;
+        endKey = new Integer(100).toString();
+        headMap = subMap_default_comparator.headMap(endKey);
+        assertEquals(0, headMap.size());
+
+        headMap = subMap_startExcluded_endExcluded_comparator.headMap(endKey);
+        assertEquals(0, headMap.size());
+
+        headMap = subMap_startExcluded_endIncluded_comparator.headMap(endKey);
+        assertEquals(0, headMap.size());
+
+        headMap = subMap_startIncluded_endExcluded_comparator.headMap(endKey);
+        assertEquals(0, headMap.size());
+
+        headMap = subMap_startIncluded_endIncluded_comparator.headMap(endKey);
+        assertEquals(0, headMap.size());
+
+        for (int i = 0, j = 101; i < 8; i++) {
+            endKey = new Integer(i + j).toString();
+            headMap = subMap_default_comparator.headMap(endKey);
+            assertEquals(i + 1, headMap.size());
+
+            headMap = subMap_startExcluded_endExcluded_comparator
+                    .headMap(endKey);
+            assertEquals(i, headMap.size());
+
+            headMap = subMap_startExcluded_endIncluded_comparator
+                    .headMap(endKey);
+            assertEquals(i, headMap.size());
+
+            headMap = subMap_startIncluded_endExcluded_comparator
+                    .headMap(endKey);
+            assertEquals(i + 1, headMap.size());
+
+            headMap = subMap_startIncluded_endIncluded_comparator
+                    .headMap(endKey);
+            assertEquals(i + 1, headMap.size());
+        }
+
+        endKey = new Integer(108).toString();
+        headMap = subMap_default_comparator.headMap(endKey);
+        assertEquals(8, headMap.size());
+
+        headMap = subMap_startExcluded_endExcluded_comparator.headMap(endKey);
+        assertEquals(7, headMap.size());
+
+        headMap = subMap_startExcluded_endIncluded_comparator.headMap(endKey);
+        assertEquals(7, headMap.size());
+
+        headMap = subMap_startIncluded_endExcluded_comparator.headMap(endKey);
+        assertEquals(8, headMap.size());
+
+        headMap = subMap_startIncluded_endIncluded_comparator.headMap(endKey);
+        assertEquals(8, headMap.size());
+
+        endKey = new Integer(110).toString();
+        try {
+            subMap_default_comparator.headMap(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endExcluded_comparator.headMap(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endIncluded_comparator.headMap(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endExcluded_comparator.headMap(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endIncluded_comparator.headMap(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+    }
+
+    public void test_SubMap_isEmpty() {
+        assertFalse(subMap_default.isEmpty());
+        assertFalse(subMap_startExcluded_endExcluded.isEmpty());
+        assertFalse(subMap_startExcluded_endIncluded.isEmpty());
+        assertFalse(subMap_startIncluded_endExcluded.isEmpty());
+        assertFalse(subMap_startIncluded_endIncluded.isEmpty());
+
+        Object startKey = new Integer(100);
+        Object endKey = startKey;
+        SortedMap subMap = tm.subMap(startKey.toString(), endKey.toString());
+        assertTrue(subMap.isEmpty());
+        subMap = subMap_default.subMap(startKey.toString(), endKey.toString());
+        assertTrue(subMap.isEmpty());
+        subMap = subMap_startIncluded_endExcluded.subMap(startKey.toString(),
+                endKey.toString());
+        assertTrue(subMap.isEmpty());
+        subMap = subMap_startIncluded_endIncluded.subMap(startKey.toString(),
+                endKey.toString());
+        assertTrue(subMap.isEmpty());
+
+        for (int i = 0, j = 101; i < 8; i++) {
+            startKey = i + j;
+            endKey = startKey;
+
+            subMap = subMap_default.subMap(startKey.toString(), endKey
+                    .toString());
+            assertTrue(subMap.isEmpty());
+
+            subMap = subMap_startExcluded_endExcluded.subMap(startKey
+                    .toString(), endKey.toString());
+            assertTrue(subMap.isEmpty());
+
+            subMap = subMap_startExcluded_endIncluded.subMap(startKey
+                    .toString(), endKey.toString());
+            assertTrue(subMap.isEmpty());
+
+            subMap = subMap_startIncluded_endExcluded.subMap(startKey
+                    .toString(), endKey.toString());
+            assertTrue(subMap.isEmpty());
+
+            subMap = subMap_startIncluded_endIncluded.subMap(startKey
+                    .toString(), endKey.toString());
+            assertTrue(subMap.isEmpty());
+        }
+
+        for (int i = 0, j = 101; i < 5; i++) {
+            startKey = i + j;
+            endKey = i + j + 4;
+
+            subMap = subMap_default.subMap(startKey.toString(), endKey
+                    .toString());
+            assertFalse(subMap.isEmpty());
+
+            subMap = subMap_startExcluded_endExcluded.subMap(startKey
+                    .toString(), endKey.toString());
+            assertFalse(subMap.isEmpty());
+
+            subMap = subMap_startExcluded_endIncluded.subMap(startKey
+                    .toString(), endKey.toString());
+            assertFalse(subMap.isEmpty());
+
+            subMap = subMap_startIncluded_endExcluded.subMap(startKey
+                    .toString(), endKey.toString());
+            assertFalse(subMap.isEmpty());
+
+            subMap = subMap_startIncluded_endIncluded.subMap(startKey
+                    .toString(), endKey.toString());
+            assertFalse(subMap.isEmpty());
+        }
+
+        startKey = new Integer(109).toString();
+        endKey = startKey;
+        subMap = tm.subMap(startKey.toString(), endKey.toString());
+        assertTrue(subMap.isEmpty());
+        subMap = subMap_startExcluded_endIncluded.subMap(startKey, endKey);
+        assertTrue(subMap.isEmpty());
+        subMap = subMap_startIncluded_endIncluded.subMap(startKey, endKey);
+        assertTrue(subMap.isEmpty());
+
+    }
+
+    public void test_SubMap_keySet() {
+        Set keySet = subMap_default.keySet();
+        assertFalse(keySet.isEmpty());
+        assertEquals(9, keySet.size());
+
+        keySet = subMap_startExcluded_endExcluded.entrySet();
+        assertFalse(keySet.isEmpty());
+        assertEquals(8, keySet.size());
+
+        keySet = subMap_startExcluded_endIncluded.entrySet();
+        assertFalse(keySet.isEmpty());
+        assertEquals(9, keySet.size());
+
+        keySet = subMap_startIncluded_endExcluded.entrySet();
+        assertFalse(keySet.isEmpty());
+        assertEquals(9, keySet.size());
+
+        keySet = subMap_startIncluded_endIncluded.entrySet();
+        assertFalse(keySet.isEmpty());
+        assertEquals(10, keySet.size());
+    }
+
+    public void test_SubMap_put() {
+        Integer value = new Integer(100);
+        int addValue = 5;
+
+        subMap_default.put(value.toString(), value + addValue);
+        assertEquals(value + addValue, subMap_default.get(value.toString()));
+
+        try {
+            subMap_startExcluded_endExcluded.put(value.toString(), value
+                    + addValue);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endIncluded.put(value.toString(), value
+                    + addValue);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        subMap_startIncluded_endExcluded
+                .put(value.toString(), value + addValue);
+        assertEquals(value + addValue, subMap_startIncluded_endExcluded
+                .get(value.toString()));
+
+        subMap_startIncluded_endIncluded
+                .put(value.toString(), value + addValue);
+        assertEquals(value + addValue, subMap_startIncluded_endIncluded
+                .get(value.toString()));
+
+        value = new Integer(109);
+        try {
+            subMap_default.put(value.toString(), value + addValue);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endExcluded.put(value.toString(), value
+                    + addValue);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        subMap_startExcluded_endIncluded
+                .put(value.toString(), value + addValue);
+        assertEquals(value + addValue, subMap_startExcluded_endIncluded
+                .get(value.toString()));
+
+        try {
+            subMap_startIncluded_endExcluded.put(value.toString(), value
+                    + addValue);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        subMap_startIncluded_endIncluded
+                .put(value.toString(), value + addValue);
+        assertEquals(value + addValue, subMap_startIncluded_endIncluded
+                .get(value.toString()));
+    }
+
+    public void test_SubMap_remove() {
+        Integer value = new Integer(100);
+
+        subMap_default.remove(value.toString());
+        assertNull(subMap_default.get(value.toString()));
+
+        subMap_startExcluded_endExcluded.remove(value.toString());
+        assertNull(subMap_startExcluded_endExcluded.get(value.toString()));
+
+        subMap_startExcluded_endIncluded.remove(value.toString());
+        assertNull(subMap_startExcluded_endIncluded.get(value.toString()));
+
+        subMap_startIncluded_endExcluded.remove(value.toString());
+        assertNull(subMap_startIncluded_endExcluded.get(value.toString()));
+
+        subMap_startIncluded_endIncluded.remove(value.toString());
+        assertNull(subMap_startIncluded_endIncluded.get(value.toString()));
+
+        value = new Integer(109);
+        subMap_default.remove(value.toString());
+        assertNull(subMap_default.get(value.toString()));
+
+        subMap_startExcluded_endExcluded.remove(value.toString());
+        assertNull(subMap_startExcluded_endExcluded.get(value.toString()));
+
+        subMap_startExcluded_endIncluded.remove(value.toString());
+        assertNull(subMap_startExcluded_endIncluded.get(value.toString()));
+
+        subMap_startIncluded_endExcluded.remove(value.toString());
+        assertNull(subMap_startIncluded_endExcluded.get(value.toString()));
+
+        subMap_startIncluded_endIncluded.remove(value.toString());
+        assertNull(subMap_startIncluded_endIncluded.get(value.toString()));
+    }
+
+    public void test_SubMap_subMap_NoComparator() {
+        String startKey = new Integer[100].toString();
+        String endKey = new Integer[100].toString();
+        try {
+            subMap_default.subMap(startKey, endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endExcluded.subMap(startKey, endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endIncluded.subMap(startKey, endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endExcluded.subMap(startKey, endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endIncluded.subMap(startKey, endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        SortedMap subSubMap = null;
+        for (int i = 101; i < 109; i++) {
+            startKey = new Integer(i).toString();
+            endKey = startKey;
+
+            subSubMap = subMap_default.subMap(startKey, endKey);
+            assertEquals(0, subSubMap.size());
+
+            subSubMap = subMap_startExcluded_endExcluded.subMap(startKey,
+                    endKey);
+            assertEquals(0, subSubMap.size());
+
+            subSubMap = subMap_startExcluded_endIncluded.subMap(startKey,
+                    endKey);
+            assertEquals(0, subSubMap.size());
+
+            subSubMap = subMap_startIncluded_endExcluded.subMap(startKey,
+                    endKey);
+            assertEquals(0, subSubMap.size());
+
+            subSubMap = subMap_startIncluded_endIncluded.subMap(startKey,
+                    endKey);
+            assertEquals(0, subSubMap.size());
+        }
+
+        for (int i = 101, j = 5; i < 105; i++) {
+            startKey = new Integer(i).toString();
+            endKey = new Integer(i + j).toString();
+
+            subSubMap = subMap_default.subMap(startKey, endKey);
+            assertEquals(j, subSubMap.size());
+
+            subSubMap = subMap_startExcluded_endExcluded.subMap(startKey,
+                    endKey);
+            assertEquals(j, subSubMap.size());
+
+            subSubMap = subMap_startExcluded_endIncluded.subMap(startKey,
+                    endKey);
+            assertEquals(j, subSubMap.size());
+
+            subSubMap = subMap_startIncluded_endExcluded.subMap(startKey,
+                    endKey);
+            assertEquals(j, subSubMap.size());
+
+            subSubMap = subMap_startIncluded_endIncluded.subMap(startKey,
+                    endKey);
+            assertEquals(j, subSubMap.size());
+        }
+
+        startKey = new Integer(108).toString();
+        endKey = new Integer(109).toString();
+
+        subSubMap = subMap_default.subMap(startKey, endKey);
+        assertEquals(1, subSubMap.size());
+
+        subSubMap = subMap_startExcluded_endExcluded.subMap(startKey, endKey);
+        assertEquals(1, subSubMap.size());
+
+        subSubMap = subMap_startExcluded_endIncluded.subMap(startKey, endKey);
+        assertEquals(1, subSubMap.size());
+
+        subSubMap = subMap_startIncluded_endExcluded.subMap(startKey, endKey);
+        assertEquals(1, subSubMap.size());
+
+        subSubMap = subMap_startIncluded_endIncluded.subMap(startKey, endKey);
+        assertEquals(1, subSubMap.size());
+
+        startKey = new Integer(109).toString();
+        endKey = new Integer(109).toString();
+
+        try {
+            subMap_default.subMap(startKey, endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endExcluded.subMap(startKey, endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        subSubMap = subMap_startExcluded_endIncluded.subMap(startKey, endKey);
+        assertEquals(0, subSubMap.size());
+
+        try {
+            subMap_startIncluded_endExcluded.subMap(startKey, endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        subSubMap = subMap_startIncluded_endIncluded.subMap(startKey, endKey);
+        assertEquals(0, subSubMap.size());
+    }
+
+    public void test_SubMap_subMap_Comparator() {
+        String startKey = new Integer[100].toString();
+        String endKey = new Integer[100].toString();
+        try {
+            subMap_default_comparator.subMap(startKey, endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endExcluded_comparator
+                    .subMap(startKey, endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endIncluded_comparator
+                    .subMap(startKey, endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endExcluded_comparator
+                    .subMap(startKey, endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endIncluded_comparator
+                    .subMap(startKey, endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        SortedMap subSubMap = null;
+        for (int i = 101; i < 109; i++) {
+            startKey = new Integer(i).toString();
+            endKey = startKey;
+
+            subSubMap = subMap_default_comparator.subMap(startKey, endKey);
+            assertEquals(0, subSubMap.size());
+
+            subSubMap = subMap_startExcluded_endExcluded_comparator.subMap(
+                    startKey, endKey);
+            assertEquals(0, subSubMap.size());
+
+            subSubMap = subMap_startExcluded_endIncluded_comparator.subMap(
+                    startKey, endKey);
+            assertEquals(0, subSubMap.size());
+
+            subSubMap = subMap_startIncluded_endExcluded_comparator.subMap(
+                    startKey, endKey);
+            assertEquals(0, subSubMap.size());
+
+            subSubMap = subMap_startIncluded_endIncluded_comparator.subMap(
+                    startKey, endKey);
+            assertEquals(0, subSubMap.size());
+        }
+
+        for (int i = 101, j = 5; i < 105; i++) {
+            startKey = new Integer(i).toString();
+            endKey = new Integer(i + j).toString();
+
+            subSubMap = subMap_default_comparator.subMap(startKey, endKey);
+            assertEquals(j, subSubMap.size());
+
+            subSubMap = subMap_startExcluded_endExcluded_comparator.subMap(
+                    startKey, endKey);
+            assertEquals(j, subSubMap.size());
+
+            subSubMap = subMap_startExcluded_endIncluded_comparator.subMap(
+                    startKey, endKey);
+            assertEquals(j, subSubMap.size());
+
+            subSubMap = subMap_startIncluded_endExcluded_comparator.subMap(
+                    startKey, endKey);
+            assertEquals(j, subSubMap.size());
+
+            subSubMap = subMap_startIncluded_endIncluded_comparator.subMap(
+                    startKey, endKey);
+            assertEquals(j, subSubMap.size());
+        }
+
+        startKey = new Integer(108).toString();
+        endKey = new Integer(109).toString();
+
+        subSubMap = subMap_default_comparator.subMap(startKey, endKey);
+        assertEquals(1, subSubMap.size());
+
+        subSubMap = subMap_startExcluded_endExcluded_comparator.subMap(
+                startKey, endKey);
+        assertEquals(1, subSubMap.size());
+
+        subSubMap = subMap_startExcluded_endIncluded_comparator.subMap(
+                startKey, endKey);
+        assertEquals(1, subSubMap.size());
+
+        subSubMap = subMap_startIncluded_endExcluded_comparator.subMap(
+                startKey, endKey);
+        assertEquals(1, subSubMap.size());
+
+        subSubMap = subMap_startIncluded_endIncluded_comparator.subMap(
+                startKey, endKey);
+        assertEquals(1, subSubMap.size());
+
+        startKey = new Integer(109).toString();
+        endKey = new Integer(109).toString();
+
+        try {
+            subMap_default_comparator.subMap(startKey, endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endExcluded_comparator
+                    .subMap(startKey, endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        subSubMap = subMap_startExcluded_endIncluded_comparator.subMap(
+                startKey, endKey);
+        assertEquals(0, subSubMap.size());
+
+        try {
+            subMap_startIncluded_endExcluded_comparator
+                    .subMap(startKey, endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        subSubMap = subMap_startIncluded_endIncluded_comparator.subMap(
+                startKey, endKey);
+        assertEquals(0, subSubMap.size());
+    }
+
+    public void test_SubMap_tailMap() {
+        String startKey = new Integer(99).toString();
+        try {
+            subMap_default.tailMap(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endExcluded.tailMap(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endIncluded.tailMap(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endExcluded.tailMap(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startIncluded_endIncluded.tailMap(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        SortedMap tailMap = null;
+
+        startKey = new Integer(100).toString();
+        tailMap = subMap_default.tailMap(startKey);
+        assertEquals(9, tailMap.size());
+
+        try {
+            subMap_startExcluded_endExcluded.tailMap(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endIncluded.tailMap(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        tailMap = subMap_startIncluded_endExcluded.tailMap(startKey);
+        assertEquals(9, tailMap.size());
+
+        tailMap = subMap_startIncluded_endIncluded.tailMap(startKey);
+        assertEquals(10, tailMap.size());
+
+        for (int i = 0, j = 101, end = 8; i < end; i++) {
+            startKey = new Integer(i + j).toString();
+            tailMap = subMap_default.tailMap(startKey);
+            assertEquals(end - i, tailMap.size());
+
+            tailMap = subMap_startExcluded_endExcluded.tailMap(startKey);
+            assertEquals(end - i, tailMap.size());
+
+            tailMap = subMap_startExcluded_endIncluded.tailMap(startKey);
+            assertEquals(end - i + 1, tailMap.size());
+
+            tailMap = subMap_startIncluded_endExcluded.tailMap(startKey);
+            assertEquals(end - i, tailMap.size());
+
+            tailMap = subMap_startIncluded_endIncluded.tailMap(startKey);
+            assertEquals(end - i + 1, tailMap.size());
+        }
+
+        startKey = new Integer(109).toString();
+        try {
+            subMap_default.tailMap(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            subMap_startExcluded_endExcluded.tailMap(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        tailMap = subMap_startExcluded_endIncluded.tailMap(startKey);
+        assertEquals(1, tailMap.size());
+
+        try {
+            subMap_startIncluded_endExcluded.tailMap(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        tailMap = subMap_startIncluded_endIncluded.tailMap(startKey);
+        assertEquals(1, tailMap.size());
+
+        startKey = new Integer(110).toString();
+        try {
+            subMap_default.tailMap(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            subMap_startExcluded_endExcluded.tailMap(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            subMap_startExcluded_endIncluded.tailMap(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            subMap_startIncluded_endExcluded.tailMap(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            subMap_startIncluded_endIncluded.tailMap(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+    }
+
+    public void test_SubMap_values() {
+        Collection values = subMap_default.values();
+
+        assertFalse(values.isEmpty());
+        assertTrue(values.contains(100));
+        for (int i = 101; i < 109; i++) {
+            assertTrue(values.contains(i));
+        }
+        assertFalse(values.contains(109));
+
+        values = subMap_startExcluded_endExcluded.values();
+        assertFalse(values.isEmpty());
+        assertFalse(values.contains(100));
+        for (int i = 101; i < 109; i++) {
+            assertTrue(values.contains(i));
+        }
+        assertFalse(values.contains(109));
+
+        values = subMap_startExcluded_endIncluded.values();
+        assertFalse(values.isEmpty());
+        assertFalse(values.contains(100));
+        for (int i = 101; i < 109; i++) {
+            assertTrue(values.contains(i));
+        }
+        assertTrue(values.contains(109));
+
+        values = subMap_startIncluded_endExcluded.values();
+        assertFalse(values.isEmpty());
+        assertTrue(values.contains(100));
+        for (int i = 101; i < 109; i++) {
+            assertTrue(values.contains(i));
+        }
+        assertFalse(values.contains(109));
+
+        values = subMap_startIncluded_endIncluded.values();
+        assertFalse(values.isEmpty());
+        assertTrue(values.contains(100));
+        for (int i = 100; i < 109; i++) {
+            assertTrue(values.contains(i));
+        }
+        assertTrue(values.contains(109));
+    }
+
+    public void test_SubMap_size() {
+        assertEquals(9, subMap_default.size());
+        assertEquals(8, subMap_startExcluded_endExcluded.size());
+        assertEquals(9, subMap_startExcluded_endIncluded.size());
+        assertEquals(9, subMap_startIncluded_endExcluded.size());
+        assertEquals(10, subMap_startIncluded_endIncluded.size());
+
+        assertEquals(9, subMap_default_comparator.size());
+        assertEquals(8, subMap_startExcluded_endExcluded_comparator.size());
+        assertEquals(9, subMap_startExcluded_endIncluded_comparator.size());
+        assertEquals(9, subMap_startIncluded_endExcluded_comparator.size());
+        assertEquals(10, subMap_startIncluded_endIncluded_comparator.size());
+    }
+
+    public void test_SubMap_readObject() throws Exception {
+        // SerializationTest.verifySelf(subMap_default);
+        // SerializationTest.verifySelf(subMap_startExcluded_endExcluded);
+        // SerializationTest.verifySelf(subMap_startExcluded_endIncluded);
+        // SerializationTest.verifySelf(subMap_startIncluded_endExcluded);
+        // SerializationTest.verifySelf(subMap_startIncluded_endIncluded);
+    }
+
+    public void test_AscendingSubMap_ceilingEntry() {
+        String key = new Integer(99).toString();
+        assertNull(navigableMap_startExcluded_endExcluded.ceilingEntry(key));
+        assertNull(navigableMap_startExcluded_endIncluded.ceilingEntry(key));
+        assertNull(navigableMap_startIncluded_endExcluded.ceilingEntry(key));
+        assertNull(navigableMap_startIncluded_endIncluded.ceilingEntry(key));
+
+        key = new Integer(100).toString();
+        assertEquals(101, navigableMap_startExcluded_endExcluded.ceilingEntry(
+                key).getValue());
+        assertEquals(101, navigableMap_startExcluded_endIncluded.ceilingEntry(
+                key).getValue());
+        assertEquals(100, navigableMap_startIncluded_endExcluded.ceilingEntry(
+                key).getValue());
+        assertEquals(100, navigableMap_startIncluded_endIncluded.ceilingEntry(
+                key).getValue());
+
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertEquals(i, navigableMap_startExcluded_endExcluded
+                    .ceilingEntry(key).getValue());
+            assertEquals(i, navigableMap_startExcluded_endIncluded
+                    .ceilingEntry(key).getValue());
+            assertEquals(i, navigableMap_startIncluded_endExcluded
+                    .ceilingEntry(key).getValue());
+            assertEquals(i, navigableMap_startIncluded_endIncluded
+                    .ceilingEntry(key).getValue());
+
+        }
+
+        key = new Integer(109).toString();
+        assertNull(navigableMap_startExcluded_endExcluded.ceilingEntry(key));
+        assertEquals(109, navigableMap_startExcluded_endIncluded.ceilingEntry(
+                key).getValue());
+        assertNull(navigableMap_startIncluded_endExcluded.ceilingEntry(key));
+        assertEquals(109, navigableMap_startIncluded_endIncluded.ceilingEntry(
+                key).getValue());
+
+        key = new Integer(110).toString();
+        assertNull(navigableMap_startExcluded_endExcluded.ceilingEntry(key));
+        assertNull(navigableMap_startExcluded_endIncluded.ceilingEntry(key));
+        assertNull(navigableMap_startIncluded_endExcluded.ceilingEntry(key));
+        assertNull(navigableMap_startIncluded_endIncluded.ceilingEntry(key));
+    }
+
+    public void test_AscendingSubMap_descendingMap() {
+        NavigableMap descendingMap = navigableMap_startExcluded_endExcluded
+                .descendingMap();
+        assertEquals(navigableMap_startExcluded_endExcluded.size(),
+                descendingMap.size());
+        assertNotNull(descendingMap.comparator());
+
+        assertEquals(navigableMap_startExcluded_endExcluded.firstKey(),
+                descendingMap.lastKey());
+        assertEquals(navigableMap_startExcluded_endExcluded.firstEntry(),
+                descendingMap.lastEntry());
+
+        assertEquals(navigableMap_startExcluded_endExcluded.lastKey(),
+                descendingMap.firstKey());
+        assertEquals(navigableMap_startExcluded_endExcluded.lastEntry(),
+                descendingMap.firstEntry());
+
+        descendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+        assertEquals(navigableMap_startExcluded_endIncluded.size(),
+                descendingMap.size());
+        assertNotNull(descendingMap.comparator());
+
+        assertEquals(navigableMap_startExcluded_endIncluded.firstKey(),
+                descendingMap.lastKey());
+        assertEquals(navigableMap_startExcluded_endIncluded.firstEntry(),
+                descendingMap.lastEntry());
+
+        assertEquals(navigableMap_startExcluded_endIncluded.lastKey(),
+                descendingMap.firstKey());
+        assertEquals(navigableMap_startExcluded_endIncluded.lastEntry(),
+                descendingMap.firstEntry());
+
+        descendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+        assertEquals(navigableMap_startIncluded_endExcluded.size(),
+                descendingMap.size());
+        assertNotNull(descendingMap.comparator());
+
+        assertEquals(navigableMap_startIncluded_endExcluded.firstKey(),
+                descendingMap.lastKey());
+        assertEquals(navigableMap_startIncluded_endExcluded.firstEntry(),
+                descendingMap.lastEntry());
+
+        assertEquals(navigableMap_startIncluded_endExcluded.lastKey(),
+                descendingMap.firstKey());
+        assertEquals(navigableMap_startIncluded_endExcluded.lastEntry(),
+                descendingMap.firstEntry());
+
+        descendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+        assertEquals(navigableMap_startIncluded_endIncluded.size(),
+                descendingMap.size());
+        assertNotNull(descendingMap.comparator());
+
+        assertEquals(navigableMap_startIncluded_endIncluded.firstKey(),
+                descendingMap.lastKey());
+        assertEquals(navigableMap_startIncluded_endIncluded.firstEntry(),
+                descendingMap.lastEntry());
+
+        assertEquals(navigableMap_startIncluded_endIncluded.lastKey(),
+                descendingMap.firstKey());
+        assertEquals(navigableMap_startIncluded_endIncluded.lastEntry(),
+                descendingMap.firstEntry());
+    }
+
+    public void test_AscendingSubMap_floorEntry() {
+        String key = new Integer(99).toString();
+        assertEquals(108, navigableMap_startExcluded_endExcluded
+                .floorEntry(key).getValue());
+        assertEquals(109, navigableMap_startExcluded_endIncluded
+                .floorEntry(key).getValue());
+        assertEquals(108, navigableMap_startIncluded_endExcluded
+                .floorEntry(key).getValue());
+        assertEquals(109, navigableMap_startIncluded_endIncluded
+                .floorEntry(key).getValue());
+
+        key = new Integer(100).toString();
+        assertNull(navigableMap_startExcluded_endExcluded.floorEntry(key));
+        assertNull(navigableMap_startExcluded_endIncluded.floorEntry(key));
+        assertEquals(100, navigableMap_startIncluded_endExcluded
+                .floorEntry(key).getValue());
+        assertEquals(100, navigableMap_startIncluded_endIncluded
+                .floorEntry(key).getValue());
+
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertEquals(i, navigableMap_startExcluded_endExcluded.floorEntry(
+                    key).getValue());
+            assertEquals(i, navigableMap_startExcluded_endIncluded.floorEntry(
+                    key).getValue());
+            assertEquals(i, navigableMap_startIncluded_endExcluded.floorEntry(
+                    key).getValue());
+            assertEquals(i, navigableMap_startIncluded_endIncluded.floorEntry(
+                    key).getValue());
+
+        }
+
+        key = new Integer(109).toString();
+        assertEquals(108, navigableMap_startExcluded_endExcluded
+                .floorEntry(key).getValue());
+        assertEquals(109, navigableMap_startExcluded_endIncluded
+                .floorEntry(key).getValue());
+        assertEquals(108, navigableMap_startIncluded_endExcluded
+                .floorEntry(key).getValue());
+        assertEquals(109, navigableMap_startIncluded_endIncluded
+                .floorEntry(key).getValue());
+
+        key = new Integer(110).toString();
+        assertEquals(108, navigableMap_startExcluded_endExcluded
+                .floorEntry(key).getValue());
+        assertEquals(109, navigableMap_startExcluded_endIncluded
+                .floorEntry(key).getValue());
+        assertEquals(108, navigableMap_startIncluded_endExcluded
+                .floorEntry(key).getValue());
+        assertEquals(109, navigableMap_startIncluded_endIncluded
+                .floorEntry(key).getValue());
+    }
+
+    public void test_AscendingSubMap_pollFirstEntry() {
+        assertEquals(101, navigableMap_startExcluded_endExcluded
+                .pollFirstEntry().getValue());
+        assertEquals(102, navigableMap_startExcluded_endIncluded
+                .pollFirstEntry().getValue());
+        assertEquals(100, navigableMap_startIncluded_endExcluded
+                .pollFirstEntry().getValue());
+        assertEquals(103, navigableMap_startIncluded_endIncluded
+                .pollFirstEntry().getValue());
+    }
+
+    public void test_AscendingSubMap_pollLastEntry() {
+        assertEquals(108, navigableMap_startExcluded_endExcluded
+                .pollLastEntry().getValue());
+        assertEquals(109, navigableMap_startExcluded_endIncluded
+                .pollLastEntry().getValue());
+        assertEquals(107, navigableMap_startIncluded_endExcluded
+                .pollLastEntry().getValue());
+        assertEquals(106, navigableMap_startIncluded_endIncluded
+                .pollLastEntry().getValue());
+    }
+
+    public void test_AscendingSubMap_entrySet() {
+        assertEquals(8, navigableMap_startExcluded_endExcluded.entrySet()
+                .size());
+        assertEquals(9, navigableMap_startExcluded_endIncluded.entrySet()
+                .size());
+        assertEquals(9, navigableMap_startIncluded_endExcluded.entrySet()
+                .size());
+        assertEquals(10, navigableMap_startIncluded_endIncluded.entrySet()
+                .size());
+    }
+
+    public void test_AscendingSubMap_subMap() {
+        Set entrySet;
+        Entry startEntry, endEntry;
+        int startIndex, endIndex;
+        SortedMap subMap;
+        Iterator subMapSetIterator;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        Iterator startIterator = entrySet.iterator();
+        while (startIterator.hasNext()) {
+            startEntry = (Entry) startIterator.next();
+            startIndex = (Integer) startEntry.getValue();
+            Iterator endIterator = entrySet.iterator();
+            while (endIterator.hasNext()) {
+                endEntry = (Entry) endIterator.next();
+                endIndex = (Integer) endEntry.getValue();
+
+                if (startIndex > endIndex) {
+                    try {
+                        navigableMap_startExcluded_endExcluded.subMap(
+                                startEntry.getKey(), endEntry.getKey());
+                        fail("should throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+                    try {
+                        navigableMap_startExcluded_endExcluded.subMap(
+                                startEntry.getKey(), false, endEntry.getKey(),
+                                false);
+                        fail("should throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+                    try {
+                        navigableMap_startExcluded_endExcluded.subMap(
+                                startEntry.getKey(), false, endEntry.getKey(),
+                                true);
+                        fail("should throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+                    try {
+                        navigableMap_startExcluded_endExcluded.subMap(
+                                startEntry.getKey(), true, endEntry.getKey(),
+                                false);
+                        fail("should throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+                    try {
+                        navigableMap_startExcluded_endExcluded.subMap(
+                                startEntry.getKey(), true, endEntry.getKey(),
+                                true);
+                        fail("should throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+                } else {
+                    subMap = navigableMap_startExcluded_endExcluded.subMap(
+                            startEntry.getKey(), endEntry.getKey());
+                    subMapSetIterator = subMap.entrySet().iterator();
+                    for (int index = startIndex; index < endIndex; index++) {
+                        assertEquals(index, ((Entry) subMapSetIterator.next())
+                                .getValue());
+                    }
+
+                    subMap = navigableMap_startExcluded_endExcluded.subMap(
+                            startEntry.getKey(), false, endEntry.getKey(),
+                            false);
+                    subMapSetIterator = subMap.entrySet().iterator();
+                    for (int index = startIndex + 1; index < endIndex; index++) {
+                        assertEquals(index, ((Entry) subMapSetIterator.next())
+                                .getValue());
+                    }
+
+                    subMap = navigableMap_startExcluded_endExcluded
+                            .subMap(startEntry.getKey(), false, endEntry
+                                    .getKey(), true);
+                    subMapSetIterator = subMap.entrySet().iterator();
+                    for (int index = startIndex + 1; index < endIndex; index++) {
+                        assertEquals(index, ((Entry) subMapSetIterator.next())
+                                .getValue());
+                    }
+
+                    subMap = navigableMap_startExcluded_endExcluded
+                            .subMap(startEntry.getKey(), true, endEntry
+                                    .getKey(), false);
+                    subMapSetIterator = subMap.entrySet().iterator();
+                    for (int index = startIndex; index < endIndex; index++) {
+                        assertEquals(index, ((Entry) subMapSetIterator.next())
+                                .getValue());
+                    }
+
+                    subMap = navigableMap_startExcluded_endExcluded.subMap(
+                            startEntry.getKey(), true, endEntry.getKey(), true);
+                    subMapSetIterator = subMap.entrySet().iterator();
+                    for (int index = startIndex; index <= endIndex; index++) {
+                        assertEquals(index, ((Entry) subMapSetIterator.next())
+                                .getValue());
+                    }
+                }
+            }
+        }
+    }
+
+    public void test_DescendingSubMap_ceilingEntry() {
+        NavigableMap decendingMap = tm.descendingMap();
+        String key = new Integer(-1).toString();
+        assertNull(decendingMap.ceilingEntry(key));
+        for (int i = 0; i < objArray.length; i++) {
+            key = objArray[i].toString();
+            assertEquals(objArray[i], decendingMap.ceilingEntry(key).getValue());
+        }
+        key = new Integer(1000).toString();
+        assertEquals(100, decendingMap.ceilingEntry(key).getValue());
+        key = new Integer(1001).toString();
+        assertEquals(100, decendingMap.ceilingEntry(key).getValue());
+
+        decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+        key = new Integer(100).toString();
+        assertNull(decendingMap.ceilingEntry(key));
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertEquals(i, decendingMap.ceilingEntry(key).getValue());
+        }
+        key = new Integer(109).toString();
+        assertEquals(108, decendingMap.ceilingEntry(key).getValue());
+
+        decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+        key = new Integer(100).toString();
+        assertNull(decendingMap.ceilingEntry(key));
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertEquals(i, decendingMap.ceilingEntry(key).getValue());
+        }
+        key = new Integer(109).toString();
+        assertEquals(109, decendingMap.ceilingEntry(key).getValue());
+
+        decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+        key = new Integer(100).toString();
+        assertEquals(100, decendingMap.ceilingEntry(key).getValue());
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertEquals(i, decendingMap.ceilingEntry(key).getValue());
+        }
+        key = new Integer(109).toString();
+        assertEquals(108, decendingMap.ceilingEntry(key).getValue());
+
+        decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+        key = new Integer(100).toString();
+        assertEquals(100, decendingMap.ceilingEntry(key).getValue());
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertEquals(i, decendingMap.ceilingEntry(key).getValue());
+        }
+        key = new Integer(109).toString();
+        assertEquals(109, decendingMap.ceilingEntry(key).getValue());
+
+        // With Comparator
+        decendingMap = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+                .descendingMap();
+        key = new Integer(100).toString();
+        assertNull(decendingMap.ceilingEntry(key));
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertEquals(i, decendingMap.ceilingEntry(key).getValue());
+        }
+        key = new Integer(109).toString();
+        assertEquals(108, decendingMap.ceilingEntry(key).getValue());
+
+        decendingMap = ((NavigableMap) subMap_startExcluded_endIncluded_comparator)
+                .descendingMap();
+        key = new Integer(100).toString();
+        assertNull(decendingMap.ceilingEntry(key));
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertEquals(i, decendingMap.ceilingEntry(key).getValue());
+        }
+        key = new Integer(109).toString();
+        assertEquals(109, decendingMap.ceilingEntry(key).getValue());
+
+        decendingMap = ((NavigableMap) subMap_startIncluded_endExcluded_comparator)
+                .descendingMap();
+        key = new Integer(100).toString();
+        assertEquals(100, decendingMap.ceilingEntry(key).getValue());
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertEquals(i, decendingMap.ceilingEntry(key).getValue());
+        }
+        key = new Integer(109).toString();
+        assertEquals(108, decendingMap.ceilingEntry(key).getValue());
+
+        decendingMap = ((NavigableMap) subMap_startIncluded_endIncluded_comparator)
+                .descendingMap();
+        key = new Integer(100).toString();
+        assertEquals(100, decendingMap.ceilingEntry(key).getValue());
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertEquals(i, decendingMap.ceilingEntry(key).getValue());
+        }
+        key = new Integer(109).toString();
+        assertEquals(109, decendingMap.ceilingEntry(key).getValue());
+    }
+
+    public void test_DescendingSubMap_descendingMap() {
+        NavigableMap decendingMap = tm.descendingMap();
+        NavigableMap decendingDecendingMap = decendingMap.descendingMap();
+        assertEquals(decendingMap, decendingDecendingMap);
+
+        NavigableMap decendingMapHeadMap = decendingMap.headMap(
+                new Integer(990).toString(), false);
+        NavigableMap decendingDecendingHeadMap = decendingMapHeadMap
+                .descendingMap();
+        assertNotNull(decendingMapHeadMap);
+        assertNotNull(decendingDecendingHeadMap);
+        assertEquals(decendingMapHeadMap, decendingDecendingHeadMap);
+
+        NavigableMap decendingMapTailMap = decendingMap.tailMap(
+                new Integer(990).toString(), false);
+        NavigableMap decendingDecendingTailMap = decendingMapTailMap
+                .descendingMap();
+        assertNotNull(decendingMapTailMap);
+        assertNotNull(decendingDecendingTailMap);
+        // assertEquals(decendingMapTailMap,decendingDecendingTailMap);
+
+        decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+        decendingDecendingMap = decendingMap.descendingMap();
+        assertEquals(decendingMap, decendingDecendingMap);
+
+        decendingMapHeadMap = decendingMap.headMap(new Integer(104).toString(),
+                false);
+        decendingDecendingHeadMap = decendingMapHeadMap.descendingMap();
+        assertEquals(decendingMapHeadMap, decendingDecendingHeadMap);
+
+        decendingMapTailMap = decendingMap.tailMap(new Integer(104).toString(),
+                false);
+        decendingDecendingTailMap = decendingMapTailMap.descendingMap();
+        assertEquals(decendingMapTailMap, decendingDecendingTailMap);
+
+        decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+        decendingDecendingMap = decendingMap.descendingMap();
+        assertEquals(decendingMap, decendingDecendingMap);
+
+        decendingMapHeadMap = decendingMap.headMap(new Integer(104).toString(),
+                false);
+        decendingDecendingHeadMap = decendingMapHeadMap.descendingMap();
+        assertEquals(decendingMapHeadMap, decendingDecendingHeadMap);
+
+        decendingMapTailMap = decendingMap.tailMap(new Integer(104).toString(),
+                false);
+        decendingDecendingTailMap = decendingMapTailMap.descendingMap();
+        assertEquals(decendingMapTailMap, decendingDecendingTailMap);
+
+        decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+        decendingDecendingMap = decendingMap.descendingMap();
+        assertEquals(decendingMap, decendingDecendingMap);
+
+        decendingMapHeadMap = decendingMap.headMap(new Integer(104).toString(),
+                false);
+        decendingDecendingHeadMap = decendingMapHeadMap.descendingMap();
+        assertEquals(decendingMapHeadMap, decendingDecendingHeadMap);
+
+        decendingMapTailMap = decendingMap.tailMap(new Integer(104).toString(),
+                false);
+        decendingDecendingTailMap = decendingMapTailMap.descendingMap();
+        assertEquals(decendingMapTailMap, decendingDecendingTailMap);
+
+        decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+        decendingDecendingMap = decendingMap.descendingMap();
+        assertEquals(decendingMap, decendingDecendingMap);
+
+        decendingMapHeadMap = decendingMap.headMap(new Integer(104).toString(),
+                false);
+        decendingDecendingHeadMap = decendingMapHeadMap.descendingMap();
+        assertEquals(decendingMapHeadMap, decendingDecendingHeadMap);
+
+        decendingMapTailMap = decendingMap.tailMap(new Integer(104).toString(),
+                false);
+        decendingDecendingTailMap = decendingMapTailMap.descendingMap();
+        assertEquals(decendingMapTailMap, decendingDecendingTailMap);
+    }
+
+    public void test_DescendingSubMap_firstEntry() {
+        NavigableMap decendingMap = tm.descendingMap();
+        assertEquals(999, decendingMap.firstEntry().getValue());
+
+        decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+        assertEquals(108, decendingMap.firstEntry().getValue());
+
+        decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+        assertEquals(109, decendingMap.firstEntry().getValue());
+
+        decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+        assertEquals(108, decendingMap.firstEntry().getValue());
+
+        decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+        assertEquals(109, decendingMap.firstEntry().getValue());
+    }
+
+    public void test_DescendingSubMap_floorEntry() {
+        NavigableMap decendingMap = tm.descendingMap();
+        String key = new Integer(-1).toString();
+        assertEquals(0, decendingMap.floorEntry(key).getValue());
+        for (int i = 0; i < objArray.length; i++) {
+            key = objArray[i].toString();
+            assertEquals(objArray[i], decendingMap.floorEntry(key).getValue());
+        }
+        key = new Integer(1000).toString();
+        assertEquals(101, decendingMap.floorEntry(key).getValue());
+        key = new Integer(1001).toString();
+        assertEquals(101, decendingMap.floorEntry(key).getValue());
+
+        decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+        key = new Integer(100).toString();
+        assertEquals(101, decendingMap.floorEntry(key).getValue());
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertEquals(i, decendingMap.floorEntry(key).getValue());
+        }
+        key = new Integer(109).toString();
+        assertNull(decendingMap.floorEntry(key));
+
+        decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+        key = new Integer(100).toString();
+        assertEquals(101, decendingMap.floorEntry(key).getValue());
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertEquals(i, decendingMap.floorEntry(key).getValue());
+        }
+        key = new Integer(109).toString();
+        assertEquals(109, decendingMap.floorEntry(key).getValue());
+
+        decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+        key = new Integer(100).toString();
+        assertEquals(100, decendingMap.floorEntry(key).getValue());
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertEquals(i, decendingMap.floorEntry(key).getValue());
+        }
+        key = new Integer(109).toString();
+        assertNull(decendingMap.floorEntry(key));
+
+        decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+        key = new Integer(100).toString();
+        assertEquals(100, decendingMap.floorEntry(key).getValue());
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertEquals(i, decendingMap.floorEntry(key).getValue());
+        }
+        key = new Integer(109).toString();
+        assertEquals(109, decendingMap.floorEntry(key).getValue());
+
+        // With Comparator
+        decendingMap = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+                .descendingMap();
+        key = new Integer(100).toString();
+        assertEquals(101, decendingMap.floorEntry(key).getValue());
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertEquals(i, decendingMap.floorEntry(key).getValue());
+        }
+        key = new Integer(109).toString();
+        assertNull(decendingMap.floorEntry(key));
+
+        decendingMap = ((NavigableMap) subMap_startExcluded_endIncluded_comparator)
+                .descendingMap();
+        key = new Integer(100).toString();
+        assertEquals(101, decendingMap.floorEntry(key).getValue());
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertEquals(i, decendingMap.floorEntry(key).getValue());
+        }
+        key = new Integer(109).toString();
+        assertEquals(109, decendingMap.floorEntry(key).getValue());
+
+        decendingMap = ((NavigableMap) subMap_startIncluded_endExcluded_comparator)
+                .descendingMap();
+        key = new Integer(100).toString();
+        assertEquals(100, decendingMap.floorEntry(key).getValue());
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertEquals(i, decendingMap.floorEntry(key).getValue());
+        }
+        key = new Integer(109).toString();
+        assertNull(decendingMap.floorEntry(key));
+
+        decendingMap = ((NavigableMap) subMap_startIncluded_endIncluded_comparator)
+                .descendingMap();
+        key = new Integer(100).toString();
+        assertEquals(100, decendingMap.floorEntry(key).getValue());
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertEquals(i, decendingMap.floorEntry(key).getValue());
+        }
+        key = new Integer(109).toString();
+        assertEquals(109, decendingMap.floorEntry(key).getValue());
+    }
+
+    public void test_DescendingSubMap_lastEntry() {
+        NavigableMap decendingMap = tm.descendingMap();
+        assertEquals(0, decendingMap.lastEntry().getValue());
+
+        decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+        assertEquals(101, decendingMap.lastEntry().getValue());
+
+        decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+        assertEquals(101, decendingMap.lastEntry().getValue());
+
+        decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+        assertEquals(100, decendingMap.lastEntry().getValue());
+
+        decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+        assertEquals(100, decendingMap.lastEntry().getValue());
+    }
+
+    public void test_DescendingSubMap_higherEntry() {
+        NavigableMap decendingMap;
+        NavigableMap decendingTailMap;
+        Integer value;
+        Entry entry;
+        decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+        value = new Integer(101);
+        assertNull(decendingMap.higherEntry(value.toString()));
+
+        for (int i = 108; i > 101; i--) {
+            value = new Integer(i);
+            entry = decendingMap.higherEntry(value.toString());
+            assertEquals(value - 1, entry.getValue());
+        }
+
+        value = new Integer(109);
+        entry = decendingMap.higherEntry(value.toString());
+        assertEquals(108, entry.getValue());
+
+        decendingTailMap = decendingMap.tailMap(new Integer(104).toString(),
+                false);
+        value = new Integer(109);
+        entry = decendingTailMap.higherEntry(value.toString());
+        assertEquals(103, entry.getValue());
+
+        decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+        value = new Integer(100);
+        assertNull(decendingMap.higherEntry(value.toString()));
+
+        for (int i = 108; i > 100; i--) {
+            value = new Integer(i);
+            entry = decendingMap.higherEntry(value.toString());
+            assertEquals(value - 1, entry.getValue());
+        }
+
+        value = new Integer(109);
+        entry = decendingMap.higherEntry(value.toString());
+        assertEquals(108, entry.getValue());
+
+        decendingTailMap = decendingMap.tailMap(new Integer(104).toString(),
+                false);
+        value = new Integer(109);
+        entry = decendingTailMap.higherEntry(value.toString());
+        assertEquals(103, entry.getValue());
+
+        decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+        value = new Integer(101);
+        assertNull(decendingMap.higherEntry(value.toString()));
+
+        for (int i = 109; i > 101; i--) {
+            value = new Integer(i);
+            entry = decendingMap.higherEntry(value.toString());
+            assertEquals(value - 1, entry.getValue());
+        }
+
+        value = new Integer(2);
+        entry = decendingMap.higherEntry(value.toString());
+        assertEquals(109, entry.getValue());
+
+        decendingTailMap = decendingMap.tailMap(new Integer(104).toString(),
+                false);
+        value = new Integer(109);
+        entry = decendingTailMap.higherEntry(value.toString());
+        assertEquals(103, entry.getValue());
+
+        decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+        value = new Integer(100);
+        assertNull(decendingMap.higherEntry(value.toString()));
+
+        for (int i = 109; i > 100; i--) {
+            value = new Integer(i);
+            entry = decendingMap.higherEntry(value.toString());
+            assertEquals(value - 1, entry.getValue());
+        }
+
+        value = new Integer(2);
+        entry = decendingMap.higherEntry(value.toString());
+        assertEquals(109, entry.getValue());
+
+        decendingTailMap = decendingMap.tailMap(new Integer(104).toString(),
+                false);
+        value = new Integer(109);
+        entry = decendingTailMap.higherEntry(value.toString());
+        assertEquals(103, entry.getValue());
+    }
+
+    public void test_DescendingSubMap_lowerEntry() {
+        NavigableMap decendingMap;
+        NavigableMap decendingHeadMap;
+        Integer value;
+        Entry entry;
+        decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+        value = new Integer(99);
+        assertNull(decendingMap.lowerEntry(value.toString()));
+        for (int i = 100; i < 108; i++) {
+            value = new Integer(i);
+            entry = decendingMap.lowerEntry(value.toString());
+            assertEquals(value + 1, entry.getValue());
+        }
+        value = new Integer(109);
+        assertNull(decendingMap.lowerEntry(value.toString()));
+
+        decendingHeadMap = decendingMap.headMap(new Integer(103).toString(),
+                false);
+        for (int i = 104; i < 106; i++) {
+            value = new Integer(i);
+            entry = decendingHeadMap.lowerEntry(value.toString());
+            assertEquals(value + 1, entry.getValue());
+        }
+        value = new Integer(102);
+        entry = decendingHeadMap.lowerEntry(value.toString());
+        assertEquals(104, entry.getValue());
+
+        value = new Integer(109);
+        entry = decendingHeadMap.lowerEntry(value.toString());
+        assertNull(entry);
+
+        decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+        value = new Integer(99);
+        assertNull(decendingMap.lowerEntry(value.toString()));
+        for (int i = 100; i < 109; i++) {
+            value = new Integer(i);
+            entry = decendingMap.lowerEntry(value.toString());
+            assertEquals(value + 1, entry.getValue());
+        }
+        value = new Integer(110);
+        assertNull(decendingMap.lowerEntry(value.toString()));
+
+        decendingHeadMap = decendingMap.headMap(new Integer(103).toString(),
+                false);
+        for (int i = 104; i < 109; i++) {
+            value = new Integer(i);
+            entry = decendingHeadMap.lowerEntry(value.toString());
+            assertEquals(value + 1, entry.getValue());
+        }
+        value = new Integer(102);
+        entry = decendingHeadMap.lowerEntry(value.toString());
+        assertEquals(104, entry.getValue());
+
+        value = new Integer(2);
+        entry = decendingHeadMap.lowerEntry(value.toString());
+        assertNull(entry);
+
+        decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+        value = new Integer(99);
+        assertNull(decendingMap.lowerEntry(value.toString()));
+        for (int i = 100; i < 108; i++) {
+            value = new Integer(i);
+            entry = decendingMap.lowerEntry(value.toString());
+            assertEquals(value + 1, entry.getValue());
+        }
+        value = new Integer(109);
+        assertNull(decendingMap.lowerEntry(value.toString()));
+
+        decendingHeadMap = decendingMap.headMap(new Integer(103).toString(),
+                false);
+        for (int i = 104; i < 107; i++) {
+            value = new Integer(i);
+            entry = decendingHeadMap.lowerEntry(value.toString());
+            assertEquals(value + 1, entry.getValue());
+        }
+        value = new Integer(102);
+        entry = decendingHeadMap.lowerEntry(value.toString());
+        assertEquals(104, entry.getValue());
+
+        value = new Integer(2);
+        entry = decendingHeadMap.lowerEntry(value.toString());
+        assertNull(entry);
+
+        decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+        value = new Integer(99);
+        assertNull(decendingMap.lowerEntry(value.toString()));
+        for (int i = 100; i < 109; i++) {
+            value = new Integer(i);
+            entry = decendingMap.lowerEntry(value.toString());
+            assertEquals(value + 1, entry.getValue());
+        }
+        value = new Integer(110);
+        assertNull(decendingMap.lowerEntry(value.toString()));
+
+        decendingHeadMap = decendingMap.headMap(new Integer(103).toString(),
+                false);
+        for (int i = 104; i < 109; i++) {
+            value = new Integer(i);
+            entry = decendingHeadMap.lowerEntry(value.toString());
+            assertEquals(value + 1, entry.getValue());
+        }
+        value = new Integer(102);
+        entry = decendingHeadMap.lowerEntry(value.toString());
+        assertEquals(104, entry.getValue());
+
+        value = new Integer(2);
+        entry = decendingHeadMap.lowerEntry(value.toString());
+        assertNull(entry);
+    }
+
+    public void test_DescendingSubMap_pollFirstEntry() {
+        NavigableMap decendingMap = tm.descendingMap();
+        assertEquals(999, decendingMap.pollFirstEntry().getValue());
+
+        decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+        assertEquals(108, decendingMap.pollFirstEntry().getValue());
+
+        decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+        assertEquals(109, decendingMap.pollFirstEntry().getValue());
+
+        decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+        assertEquals(107, decendingMap.pollFirstEntry().getValue());
+
+        decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+        assertEquals(106, decendingMap.pollFirstEntry().getValue());
+    }
+
+    public void test_DescendingSubMap_pollLastEntry() {
+        NavigableMap decendingMap = tm.descendingMap();
+        assertEquals(0, decendingMap.pollLastEntry().getValue());
+
+        decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+        assertEquals(101, decendingMap.pollLastEntry().getValue());
+
+        decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+        assertEquals(102, decendingMap.pollLastEntry().getValue());
+
+        decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+        assertEquals(100, decendingMap.pollLastEntry().getValue());
+
+        decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+        assertEquals(103, decendingMap.pollLastEntry().getValue());
+    }
+
+    public void test_DescendingSubMap_values() {
+        NavigableMap decendingMap = tm.descendingMap();
+        Collection values = decendingMap.values();
+        assertFalse(values.isEmpty());
+        assertFalse(values.contains(1000));
+        for (int i = 999; i > 0; i--) {
+            assertTrue(values.contains(i));
+        }
+        assertTrue(values.contains(0));
+
+        String endKey = new Integer(99).toString();
+        NavigableMap headMap = decendingMap.headMap(endKey, false);
+        values = headMap.values();
+        Iterator it = values.iterator();
+        for (int i = 999; i > 990; i--) {
+            assertTrue(values.contains(i));
+            assertEquals(i, it.next());
+        }
+
+        String startKey = new Integer(11).toString();
+        NavigableMap tailMap = decendingMap.tailMap(startKey, false);
+        values = tailMap.values();
+        it = values.iterator();
+        for (int i = 109; i > 100; i--) {
+            assertTrue(values.contains(i));
+            assertEquals(i, it.next());
+        }
+
+        decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+        values = decendingMap.values();
+        assertFalse(values.isEmpty());
+        assertFalse(values.contains(109));
+        for (int i = 108; i > 100; i--) {
+            assertTrue(values.contains(i));
+        }
+        assertFalse(values.contains(100));
+
+        decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+        values = decendingMap.values();
+        assertFalse(values.isEmpty());
+        assertFalse(values.contains(100));
+        for (int i = 108; i > 100; i--) {
+            assertTrue(values.contains(i));
+        }
+        assertTrue(values.contains(109));
+
+        decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+        values = decendingMap.values();
+        assertFalse(values.isEmpty());
+        assertTrue(values.contains(100));
+        for (int i = 108; i > 100; i--) {
+            assertTrue(values.contains(i));
+        }
+        assertFalse(values.contains(109));
+
+        decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+        values = decendingMap.values();
+        assertFalse(values.isEmpty());
+        assertTrue(values.contains(100));
+        for (int i = 108; i > 100; i--) {
+            assertTrue(values.contains(i));
+        }
+        assertTrue(values.contains(109));
+    }
+
+    public void test_DescendingSubMap_headMap() {
+        NavigableMap decendingMap = tm.descendingMap();
+        String endKey = new Integer(0).toString(), key;
+        SortedMap subDecendingMap_Included = decendingMap.headMap(endKey, true);
+        SortedMap subDecendingMap_Excluded = decendingMap
+                .headMap(endKey, false);
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+        for (int i = 1; i < 1000; i++) {
+            key = new Integer(i).toString();
+            assertTrue(subDecendingMap_Included.containsKey(key));
+            assertTrue(subDecendingMap_Excluded.containsKey(key));
+        }
+        key = new Integer(1000).toString();
+        assertFalse(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+        endKey = new Integer(100).toString();
+        try {
+            decendingMap.headMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+        key = endKey;
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(101).toString();
+        subDecendingMap_Included = decendingMap.headMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        for (int i = 102; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertTrue(subDecendingMap_Included.containsKey(key));
+            assertTrue(subDecendingMap_Excluded.containsKey(key));
+        }
+        key = new Integer(109).toString();
+        assertFalse(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+        endKey = new Integer(100).toString();
+        try {
+            decendingMap.headMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+        key = endKey;
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(101).toString();
+        subDecendingMap_Included = decendingMap.headMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        for (int i = 102; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertTrue(subDecendingMap_Included.containsKey(key));
+            assertTrue(subDecendingMap_Excluded.containsKey(key));
+        }
+        key = new Integer(109).toString();
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertTrue(subDecendingMap_Excluded.containsKey(key));
+
+        decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+        endKey = new Integer(100).toString();
+        subDecendingMap_Included = decendingMap.headMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(101).toString();
+        subDecendingMap_Included = decendingMap.headMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        for (int i = 102; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertTrue(subDecendingMap_Included.containsKey(key));
+            assertTrue(subDecendingMap_Excluded.containsKey(key));
+        }
+        key = new Integer(109).toString();
+        assertFalse(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+        endKey = new Integer(100).toString();
+        subDecendingMap_Included = decendingMap.headMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(101).toString();
+        subDecendingMap_Included = decendingMap.headMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        for (int i = 102; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertTrue(subDecendingMap_Included.containsKey(key));
+            assertTrue(subDecendingMap_Excluded.containsKey(key));
+        }
+        key = new Integer(109).toString();
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertTrue(subDecendingMap_Excluded.containsKey(key));
+
+        // With Comparator
+
+        decendingMap = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+                .descendingMap();
+        endKey = new Integer(100).toString();
+        try {
+            decendingMap.headMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+        key = endKey;
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(101).toString();
+        subDecendingMap_Included = decendingMap.headMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        for (int i = 102; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertTrue(subDecendingMap_Included.containsKey(key));
+            assertTrue(subDecendingMap_Excluded.containsKey(key));
+        }
+        key = new Integer(109).toString();
+        assertFalse(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        decendingMap = ((NavigableMap) subMap_startExcluded_endIncluded_comparator)
+                .descendingMap();
+        endKey = new Integer(100).toString();
+        try {
+            decendingMap.headMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+        key = endKey;
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(101).toString();
+        subDecendingMap_Included = decendingMap.headMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        for (int i = 102; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertTrue(subDecendingMap_Included.containsKey(key));
+            assertTrue(subDecendingMap_Excluded.containsKey(key));
+        }
+        key = new Integer(109).toString();
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertTrue(subDecendingMap_Excluded.containsKey(key));
+
+        decendingMap = ((NavigableMap) subMap_startIncluded_endExcluded_comparator)
+                .descendingMap();
+        endKey = new Integer(100).toString();
+        subDecendingMap_Included = decendingMap.headMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(101).toString();
+        subDecendingMap_Included = decendingMap.headMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        for (int i = 102; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertTrue(subDecendingMap_Included.containsKey(key));
+            assertTrue(subDecendingMap_Excluded.containsKey(key));
+        }
+        key = new Integer(109).toString();
+        assertFalse(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        decendingMap = ((NavigableMap) subMap_startIncluded_endIncluded_comparator)
+                .descendingMap();
+        endKey = new Integer(100).toString();
+        subDecendingMap_Included = decendingMap.headMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(101).toString();
+        subDecendingMap_Included = decendingMap.headMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.headMap(endKey, false);
+
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        for (int i = 102; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertTrue(subDecendingMap_Included.containsKey(key));
+            assertTrue(subDecendingMap_Excluded.containsKey(key));
+        }
+        key = new Integer(109).toString();
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertTrue(subDecendingMap_Excluded.containsKey(key));
+    }
+
+    public void test_DescendingSubMap_subMap() {
+        NavigableMap descendingMap = tm.descendingMap();
+        String startKey = new Integer(109).toString();
+        String endKey = new Integer(100).toString();
+        try {
+            descendingMap.subMap(endKey, false, startKey, false);
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        SortedMap subDescendingMap = descendingMap.subMap(startKey, false,
+                endKey, false);
+        String key = new Integer(100).toString();
+        assertFalse(subDescendingMap.containsKey(key));
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertTrue(subDescendingMap.containsKey(key));
+        }
+        key = new Integer(109).toString();
+        assertFalse(subDescendingMap.containsKey(key));
+
+        subDescendingMap = descendingMap.subMap(startKey, false, endKey, true);
+        key = new Integer(100).toString();
+        assertTrue(subDescendingMap.containsKey(key));
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertTrue(subDescendingMap.containsKey(key));
+        }
+        key = new Integer(109).toString();
+        assertFalse(subDescendingMap.containsKey(key));
+
+        subDescendingMap = descendingMap.subMap(startKey, true, endKey, false);
+        key = new Integer(100).toString();
+        assertFalse(subDescendingMap.containsKey(key));
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertTrue(subDescendingMap.containsKey(key));
+        }
+        key = new Integer(109).toString();
+        assertTrue(subDescendingMap.containsKey(key));
+
+        subDescendingMap = descendingMap.subMap(startKey, true, endKey, true);
+        key = new Integer(100).toString();
+        assertTrue(subDescendingMap.containsKey(key));
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertTrue(subDescendingMap.containsKey(key));
+        }
+        key = new Integer(109).toString();
+        assertTrue(subDescendingMap.containsKey(key));
+
+        TreeMap<Integer, String> treeMap = new TreeMap<Integer, String>();
+        for (int i = -10; i < 10; i++) {
+            treeMap.put(i, String.valueOf(i));
+        }
+        descendingMap = treeMap.descendingMap();
+        subDescendingMap = descendingMap.subMap(5, 0);
+        assertEquals(5, subDescendingMap.size());
+    }
+
+    public void test_DescendingSubMap_tailMap() {
+        // tm
+        NavigableMap decendingMap = tm.descendingMap();
+        String endKey = new Integer(1000).toString(), key;
+        SortedMap subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        SortedMap subDecendingMap_Excluded = decendingMap
+                .tailMap(endKey, false);
+
+        key = endKey;
+        assertFalse(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+        key = new Integer(100).toString();
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertTrue(subDecendingMap_Excluded.containsKey(key));
+
+        key = new Integer(10).toString();
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertTrue(subDecendingMap_Excluded.containsKey(key));
+
+        key = new Integer(1).toString();
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertTrue(subDecendingMap_Excluded.containsKey(key));
+
+        key = new Integer(0).toString();
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertTrue(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(999).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+        for (int i = 998; i > 0; i--) {
+            key = new Integer(i).toString();
+            assertTrue(subDecendingMap_Included.containsKey(key));
+            assertTrue(subDecendingMap_Excluded.containsKey(key));
+        }
+        key = new Integer(0).toString();
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertTrue(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(0).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        assertEquals(1, subDecendingMap_Included.size());
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertTrue(subDecendingMap_Excluded.isEmpty());
+
+        // navigableMap_startExcluded_endExcluded
+        decendingMap = navigableMap_startExcluded_endExcluded.descendingMap();
+        endKey = new Integer(110).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            decendingMap.tailMap(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(109).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(108).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+        for (int i = 107; i > 100; i--) {
+            key = new Integer(i).toString();
+            assertTrue(subDecendingMap_Included.containsKey(key));
+            assertTrue(subDecendingMap_Excluded.containsKey(key));
+        }
+        key = new Integer(100).toString();
+        assertFalse(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Included.containsKey(key));
+
+        endKey = new Integer(101).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertEquals(1, subDecendingMap_Included.size());
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertTrue(subDecendingMap_Excluded.isEmpty());
+
+        endKey = new Integer(100).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        assertTrue(subDecendingMap_Excluded.isEmpty());
+
+        endKey = new Integer(99).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            decendingMap.tailMap(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        // navigableMap_startExcluded_endIncluded
+        decendingMap = navigableMap_startExcluded_endIncluded.descendingMap();
+        endKey = new Integer(110).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            decendingMap.tailMap(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(109).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(108).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+        for (int i = 107; i > 100; i--) {
+            key = new Integer(i).toString();
+            assertTrue(subDecendingMap_Included.containsKey(key));
+            assertTrue(subDecendingMap_Excluded.containsKey(key));
+        }
+        key = new Integer(100).toString();
+        assertFalse(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Included.containsKey(key));
+
+        endKey = new Integer(101).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertEquals(1, subDecendingMap_Included.size());
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertTrue(subDecendingMap_Excluded.isEmpty());
+
+        endKey = new Integer(100).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        assertTrue(subDecendingMap_Excluded.isEmpty());
+
+        endKey = new Integer(99).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            decendingMap.tailMap(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        // navigableMap_startIncluded_endExcluded
+        decendingMap = navigableMap_startIncluded_endExcluded.descendingMap();
+        endKey = new Integer(110).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            decendingMap.tailMap(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(109).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(108).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+        for (int i = 107; i > 100; i--) {
+            key = new Integer(i).toString();
+            assertTrue(subDecendingMap_Included.containsKey(key));
+            assertTrue(subDecendingMap_Excluded.containsKey(key));
+        }
+        key = new Integer(100).toString();
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertTrue(subDecendingMap_Included.containsKey(key));
+
+        endKey = new Integer(101).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertEquals(2, subDecendingMap_Included.size());
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(100).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(99).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            decendingMap.tailMap(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        // navigableMap_startIncluded_endIncluded
+        decendingMap = navigableMap_startIncluded_endIncluded.descendingMap();
+        endKey = new Integer(110).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            decendingMap.tailMap(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(109).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(108).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+        for (int i = 107; i > 100; i--) {
+            key = new Integer(i).toString();
+            assertTrue(subDecendingMap_Included.containsKey(key));
+            assertTrue(subDecendingMap_Excluded.containsKey(key));
+        }
+        key = new Integer(100).toString();
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertTrue(subDecendingMap_Included.containsKey(key));
+
+        endKey = new Integer(101).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertEquals(2, subDecendingMap_Included.size());
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(100).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(99).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            decendingMap.tailMap(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        // With Comparator
+        decendingMap = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+                .descendingMap();
+        endKey = new Integer(110).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            decendingMap.tailMap(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(109).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(108).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+        for (int i = 107; i > 100; i--) {
+            key = new Integer(i).toString();
+            assertTrue(subDecendingMap_Included.containsKey(key));
+            assertTrue(subDecendingMap_Excluded.containsKey(key));
+        }
+        key = new Integer(100).toString();
+        assertFalse(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Included.containsKey(key));
+
+        endKey = new Integer(101).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertEquals(1, subDecendingMap_Included.size());
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertTrue(subDecendingMap_Excluded.isEmpty());
+
+        endKey = new Integer(100).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        assertTrue(subDecendingMap_Excluded.isEmpty());
+
+        endKey = new Integer(99).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            decendingMap.tailMap(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        decendingMap = ((NavigableMap) subMap_startExcluded_endIncluded_comparator)
+                .descendingMap();
+        endKey = new Integer(110).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            decendingMap.tailMap(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(109).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(108).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+        for (int i = 107; i > 100; i--) {
+            key = new Integer(i).toString();
+            assertTrue(subDecendingMap_Included.containsKey(key));
+            assertTrue(subDecendingMap_Excluded.containsKey(key));
+        }
+        key = new Integer(100).toString();
+        assertFalse(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Included.containsKey(key));
+
+        endKey = new Integer(101).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertEquals(1, subDecendingMap_Included.size());
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertTrue(subDecendingMap_Excluded.isEmpty());
+
+        endKey = new Integer(100).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        assertTrue(subDecendingMap_Excluded.isEmpty());
+
+        endKey = new Integer(99).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            decendingMap.tailMap(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        // navigableMap_startIncluded_endExcluded
+        decendingMap = ((NavigableMap) subMap_startIncluded_endExcluded)
+                .descendingMap();
+        endKey = new Integer(110).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            decendingMap.tailMap(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(109).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(108).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+        for (int i = 107; i > 100; i--) {
+            key = new Integer(i).toString();
+            assertTrue(subDecendingMap_Included.containsKey(key));
+            assertTrue(subDecendingMap_Excluded.containsKey(key));
+        }
+        key = new Integer(100).toString();
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertTrue(subDecendingMap_Included.containsKey(key));
+
+        endKey = new Integer(101).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertEquals(2, subDecendingMap_Included.size());
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(100).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(99).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            decendingMap.tailMap(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        decendingMap = ((NavigableMap) subMap_startIncluded_endIncluded)
+                .descendingMap();
+        endKey = new Integer(110).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            decendingMap.tailMap(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(109).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(108).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+        for (int i = 107; i > 100; i--) {
+            key = new Integer(i).toString();
+            assertTrue(subDecendingMap_Included.containsKey(key));
+            assertTrue(subDecendingMap_Excluded.containsKey(key));
+        }
+        key = new Integer(100).toString();
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertTrue(subDecendingMap_Included.containsKey(key));
+
+        endKey = new Integer(101).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertEquals(2, subDecendingMap_Included.size());
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(100).toString();
+        subDecendingMap_Included = decendingMap.tailMap(endKey, true);
+        subDecendingMap_Excluded = decendingMap.tailMap(endKey, false);
+        key = endKey;
+        assertTrue(subDecendingMap_Included.containsKey(key));
+        assertFalse(subDecendingMap_Excluded.containsKey(key));
+
+        endKey = new Integer(99).toString();
+        try {
+            decendingMap.tailMap(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            decendingMap.tailMap(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+    }
+
+    public void test_Entry_setValue() {
+        TreeMap treeMap = new TreeMap();
+        Integer value = null;
+        for (int i = 0; i < 50; i++) {
+            value = new Integer(i);
+            treeMap.put(value, value);
+        }
+        Map checkedMap = Collections.checkedMap(treeMap, Integer.class,
+                Integer.class);
+        Set entrySet = checkedMap.entrySet();
+        Iterator iterator = entrySet.iterator();
+        Entry entry;
+        value = new Integer(0);
+        for (; iterator.hasNext(); value++) {
+            entry = (Entry) iterator.next();
+            assertEquals(value, entry.setValue(value + 1));
+            assertEquals(value + 1, entry.getValue());
+        }
+    }
+
+    public void test_DescendingSubMapEntrySet_comparator() {
+        Set entrySet;
+        NavigableSet descendingSet;
+        Comparator comparator;
+        Entry[] entryArray;
+        Integer value1, value2;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSet = ((NavigableSet) entrySet).descendingSet();
+            assertNull(((NavigableSet) entrySet).comparator());
+            comparator = descendingSet.comparator();
+            assertNotNull(comparator);
+
+            entryArray = (Entry[]) descendingSet
+                    .toArray(new Entry[descendingSet.size()]);
+            for (int i = 1; i < entryArray.length; i++) {
+                value1 = (Integer) entryArray[i - 1].getValue();
+                value2 = (Integer) entryArray[i].getValue();
+                assertTrue(value1 > value2);
+                assertTrue(comparator.compare(value1, value2) < 0);
+            }
+        }
+
+        entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSet = ((NavigableSet) entrySet).descendingSet();
+            assertNull(((NavigableSet) entrySet).comparator());
+            comparator = descendingSet.comparator();
+            assertNotNull(comparator);
+
+            entryArray = (Entry[]) descendingSet
+                    .toArray(new Entry[descendingSet.size()]);
+            for (int i = 1; i < entryArray.length; i++) {
+                value1 = (Integer) entryArray[i - 1].getValue();
+                value2 = (Integer) entryArray[i].getValue();
+                assertTrue(value1 > value2);
+                assertTrue(comparator.compare(value1, value2) < 0);
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSet = ((NavigableSet) entrySet).descendingSet();
+            assertNull(((NavigableSet) entrySet).comparator());
+            comparator = descendingSet.comparator();
+            assertNotNull(comparator);
+
+            entryArray = (Entry[]) descendingSet
+                    .toArray(new Entry[descendingSet.size()]);
+            for (int i = 1; i < entryArray.length; i++) {
+                value1 = (Integer) entryArray[i - 1].getValue();
+                value2 = (Integer) entryArray[i].getValue();
+                assertTrue(value1 > value2);
+                assertTrue(comparator.compare(value1, value2) < 0);
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSet = ((NavigableSet) entrySet).descendingSet();
+            assertNull(((NavigableSet) entrySet).comparator());
+            comparator = descendingSet.comparator();
+            assertNotNull(comparator);
+
+            entryArray = (Entry[]) descendingSet
+                    .toArray(new Entry[descendingSet.size()]);
+            for (int i = 1; i < entryArray.length; i++) {
+                value1 = (Integer) entryArray[i - 1].getValue();
+                value2 = (Integer) entryArray[i].getValue();
+                assertTrue(value1 > value2);
+                assertTrue(comparator.compare(value1, value2) < 0);
+            }
+        }
+
+        String endKey = new Integer(2).toString();
+        entrySet = tm.headMap(endKey, true).entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSet = ((NavigableSet) entrySet).descendingSet();
+            assertNotNull(descendingSet.comparator());
+        }
+    }
+
+    public void test_DescendingSubMapEntrySet_descendingSet() {
+        Set entrySet;
+        NavigableSet ascendingSubMapEntrySet, descendingSet, descendingDescedingSet;
+        Entry[] ascendingEntryArray, descendingDescendingArray;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            descendingDescedingSet = descendingSet.descendingSet();
+            ascendingEntryArray = (Entry[]) ascendingSubMapEntrySet
+                    .toArray(new Entry[ascendingSubMapEntrySet.size()]);
+
+            descendingDescendingArray = (Entry[]) descendingDescedingSet
+                    .toArray(new Entry[descendingDescedingSet.size()]);
+
+            assertEquals(ascendingEntryArray.length,
+                    descendingDescendingArray.length);
+            for (int i = 0; i < ascendingEntryArray.length; i++) {
+                assertEquals(ascendingEntryArray[i],
+                        descendingDescendingArray[i]);
+            }
+        }
+
+        entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            descendingDescedingSet = descendingSet.descendingSet();
+            ascendingEntryArray = (Entry[]) ascendingSubMapEntrySet
+                    .toArray(new Entry[ascendingSubMapEntrySet.size()]);
+
+            descendingDescendingArray = (Entry[]) descendingDescedingSet
+                    .toArray(new Entry[descendingDescedingSet.size()]);
+
+            assertEquals(ascendingEntryArray.length,
+                    descendingDescendingArray.length);
+            for (int i = 0; i < ascendingEntryArray.length; i++) {
+                assertEquals(ascendingEntryArray[i],
+                        descendingDescendingArray[i]);
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            descendingDescedingSet = descendingSet.descendingSet();
+            ascendingEntryArray = (Entry[]) ascendingSubMapEntrySet
+                    .toArray(new Entry[ascendingSubMapEntrySet.size()]);
+
+            descendingDescendingArray = (Entry[]) descendingDescedingSet
+                    .toArray(new Entry[descendingDescedingSet.size()]);
+
+            assertEquals(ascendingEntryArray.length,
+                    descendingDescendingArray.length);
+            for (int i = 0; i < ascendingEntryArray.length; i++) {
+                assertEquals(ascendingEntryArray[i],
+                        descendingDescendingArray[i]);
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            descendingDescedingSet = descendingSet.descendingSet();
+            ascendingEntryArray = (Entry[]) ascendingSubMapEntrySet
+                    .toArray(new Entry[ascendingSubMapEntrySet.size()]);
+
+            descendingDescendingArray = (Entry[]) descendingDescedingSet
+                    .toArray(new Entry[descendingDescedingSet.size()]);
+
+            assertEquals(ascendingEntryArray.length,
+                    descendingDescendingArray.length);
+            for (int i = 0; i < ascendingEntryArray.length; i++) {
+                assertEquals(ascendingEntryArray[i],
+                        descendingDescendingArray[i]);
+            }
+        }
+
+        String endKey = new Integer(2).toString();
+        entrySet = tm.headMap(endKey, true).entrySet();// 0...2
+        if (entrySet instanceof NavigableSet) {
+            // [2...0]
+            descendingSet = ((NavigableSet) entrySet).descendingSet();
+            // [0...2]
+            descendingDescedingSet = descendingSet.descendingSet();
+            Iterator iterator = descendingDescedingSet.iterator();
+            assertEquals(0, ((Entry) iterator.next()).getValue());
+        }
+
+        String startKey = new Integer(2).toString();
+        entrySet = tm.tailMap(startKey, true).entrySet();// 2...
+        if (entrySet instanceof NavigableSet) {
+            // [2...0]
+            descendingSet = ((NavigableSet) entrySet).descendingSet();
+            // [0...2]
+            descendingDescedingSet = descendingSet.descendingSet();
+            Iterator iterator = descendingDescedingSet.iterator();
+            assertEquals(2, ((Entry) iterator.next()).getValue());
+        }
+
+    }
+
+    public void test_DescendingSubMapEntrySet_first() {
+        Set entrySet;
+        NavigableSet ascendingSubMapEntrySet, descendingSet;
+        Entry entry;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            entry = (Entry) descendingSet.first();
+            assertEquals(101, entry.getValue());
+        }
+
+        entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            entry = (Entry) descendingSet.first();
+            assertEquals(101, entry.getValue());
+        }
+
+        entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            entry = (Entry) descendingSet.first();
+            assertEquals(100, entry.getValue());
+        }
+
+        entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            entry = (Entry) descendingSet.first();
+            assertEquals(100, entry.getValue());
+        }
+    }
+
+    public void test_DescendingSubMapEntrySet_last() {
+        Set entrySet;
+        NavigableSet ascendingSubMapEntrySet, descendingSet;
+        Entry entry;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            entry = (Entry) descendingSet.last();
+            assertEquals(108, entry.getValue());
+        }
+
+        entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            entry = (Entry) descendingSet.last();
+            assertEquals(109, entry.getValue());
+        }
+
+        entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            entry = (Entry) descendingSet.last();
+            assertEquals(108, entry.getValue());
+        }
+
+        entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            entry = (Entry) descendingSet.last();
+            assertEquals(109, entry.getValue());
+        }
+    }
+
+    public void test_DescendingSubMapEntrySet_pollFirst_startExcluded_endExcluded() {
+        Set entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        Entry entry;
+        if (entrySet instanceof NavigableSet) {
+            NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            assertEquals(8, descendingSubMapEntrySet.size());
+            for (int i = 101; i < 109; i++) {
+                entry = (Entry) descendingSubMapEntrySet.pollFirst();
+                assertEquals(i, entry.getValue());
+            }
+            assertNull(descendingSubMapEntrySet.pollFirst());
+        }
+    }
+
+    public void test_DescendingSubMapEntrySet_pollFirst_startExcluded_endIncluded() {
+        Set entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        Entry entry;
+        if (entrySet instanceof NavigableSet) {
+            NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            assertEquals(9, descendingSubMapEntrySet.size());
+            for (int i = 101; i < 110; i++) {
+                entry = (Entry) descendingSubMapEntrySet.pollFirst();
+                assertEquals(i, entry.getValue());
+            }
+            assertNull(descendingSubMapEntrySet.pollFirst());
+        }
+    }
+
+    public void test_DescendingSubMapEntrySet_pollFirst_startIncluded_endExcluded() {
+        Set entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        Entry entry;
+        if (entrySet instanceof NavigableSet) {
+            NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            assertEquals(9, descendingSubMapEntrySet.size());
+            for (int i = 100; i < 109; i++) {
+                entry = (Entry) descendingSubMapEntrySet.pollFirst();
+                assertEquals(i, entry.getValue());
+            }
+            assertNull(descendingSubMapEntrySet.pollFirst());
+        }
+    }
+
+    public void test_DescendingSubMapEntrySet_pollFirst_startIncluded_endIncluded() {
+        Set entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        Entry entry;
+        if (entrySet instanceof NavigableSet) {
+            NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            assertEquals(10, descendingSubMapEntrySet.size());
+            for (int i = 100; i < 110; i++) {
+                entry = (Entry) descendingSubMapEntrySet.pollFirst();
+                assertEquals(i, entry.getValue());
+            }
+            assertNull(descendingSubMapEntrySet.pollFirst());
+        }
+    }
+
+    public void test_DescendingSubMapEntrySet_pollFirst() {
+        String key = new Integer(2).toString();
+        Set entrySet = tm.headMap(key, true).entrySet();// [0...2]
+        NavigableSet descendingEntrySet;
+        Entry entry;
+
+        if (entrySet instanceof NavigableSet) {
+            // [2...0]
+            descendingEntrySet = ((NavigableSet) entrySet).descendingSet();
+            entry = (Entry) descendingEntrySet.pollFirst();
+            assertEquals(0, entry.getValue());
+        }
+
+        entrySet = tm.tailMap(key, true).entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingEntrySet = ((NavigableSet) entrySet).descendingSet();
+            entry = (Entry) descendingEntrySet.pollFirst();
+            assertEquals(2, entry.getValue());
+        }
+    }
+
+    public void test_DescendingSubMapEntrySet_pollLast_startExcluded_endExclued() {
+        Set entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        Entry entry;
+        if (entrySet instanceof NavigableSet) {
+            NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            assertEquals(8, descendingSubMapEntrySet.size());
+            for (int i = 108; i > 100; i--) {
+                entry = (Entry) descendingSubMapEntrySet.pollLast();
+                assertEquals(i, entry.getValue());
+            }
+            assertNull(descendingSubMapEntrySet.pollFirst());
+        }
+    }
+
+    public void test_DescendingSubMapEntrySet_pollLast_startExcluded_endInclued() {
+        Set entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        Entry entry;
+        if (entrySet instanceof NavigableSet) {
+            NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            assertEquals(9, descendingSubMapEntrySet.size());
+            for (int i = 109; i > 100; i--) {
+                entry = (Entry) descendingSubMapEntrySet.pollLast();
+                assertEquals(i, entry.getValue());
+            }
+            assertNull(descendingSubMapEntrySet.pollFirst());
+        }
+    }
+
+    public void test_DescendingSubMapEntrySet_pollLast_startIncluded_endExclued() {
+        Set entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        Entry entry;
+        if (entrySet instanceof NavigableSet) {
+            NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            assertEquals(9, descendingSubMapEntrySet.size());
+            for (int i = 108; i > 99; i--) {
+                entry = (Entry) descendingSubMapEntrySet.pollLast();
+                assertEquals(i, entry.getValue());
+            }
+            assertNull(descendingSubMapEntrySet.pollFirst());
+        }
+    }
+
+    public void test_DescendingSubMapEntrySet_pollLast_startIncluded_endInclued() {
+        Set entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        Entry entry;
+        if (entrySet instanceof NavigableSet) {
+            NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            assertEquals(10, descendingSubMapEntrySet.size());
+            for (int i = 109; i > 99; i--) {
+                entry = (Entry) descendingSubMapEntrySet.pollLast();
+                assertEquals(i, entry.getValue());
+            }
+            assertNull(descendingSubMapEntrySet.pollFirst());
+        }
+    }
+
+    public void test_DescendingSubMapEntrySet_pollLast() {
+        String key = new Integer(2).toString();
+        Set entrySet = tm.headMap(key, true).entrySet();// [0...2]
+        NavigableSet descendingEntrySet;
+        Entry entry;
+
+        if (entrySet instanceof NavigableSet) {
+            // [2...0]
+            descendingEntrySet = ((NavigableSet) entrySet).descendingSet();
+            entry = (Entry) descendingEntrySet.pollLast();
+            assertEquals(2, entry.getValue());
+        }
+
+        entrySet = tm.tailMap(key, true).entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingEntrySet = ((NavigableSet) entrySet).descendingSet();
+            entry = (Entry) descendingEntrySet.pollLast();
+            assertEquals(999, entry.getValue());
+        }
+    }
+
+    public void test_DescendingSubMapEntrySet_descendingIterator() {
+        Set entrySet;
+        NavigableSet descendingSet;
+        Iterator iterator;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSet = ((NavigableSet) entrySet).descendingSet();
+            iterator = descendingSet.iterator();
+            for (int value = 108; value > 100; value--) {
+                assertTrue(iterator.hasNext());
+                assertEquals(value, ((Entry) iterator.next()).getValue());
+            }
+            assertFalse(iterator.hasNext());
+            try {
+                iterator.next();
+                fail("should throw NoSuchElementException");
+            } catch (NoSuchElementException e) {
+                // Expected
+            }
+        }
+
+        entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSet = ((NavigableSet) entrySet).descendingSet();
+            iterator = descendingSet.iterator();
+            for (int value = 109; value > 100; value--) {
+                assertTrue(iterator.hasNext());
+                assertEquals(value, ((Entry) iterator.next()).getValue());
+            }
+            assertFalse(iterator.hasNext());
+            try {
+                iterator.next();
+                fail("should throw NoSuchElementException");
+            } catch (NoSuchElementException e) {
+                // Expected
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSet = ((NavigableSet) entrySet).descendingSet();
+            iterator = descendingSet.iterator();
+            for (int value = 108; value > 99; value--) {
+                assertTrue(iterator.hasNext());
+                assertEquals(value, ((Entry) iterator.next()).getValue());
+            }
+            assertFalse(iterator.hasNext());
+            try {
+                iterator.next();
+                fail("should throw NoSuchElementException");
+            } catch (NoSuchElementException e) {
+                // Expected
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSet = ((NavigableSet) entrySet).descendingSet();
+            iterator = descendingSet.iterator();
+            for (int value = 109; value > 99; value--) {
+                assertTrue(iterator.hasNext());
+                assertEquals(value, ((Entry) iterator.next()).getValue());
+            }
+            assertFalse(iterator.hasNext());
+            try {
+                iterator.next();
+                fail("should throw NoSuchElementException");
+            } catch (NoSuchElementException e) {
+                // Expected
+            }
+        }
+
+        String endKey = new Integer(2).toString();
+        entrySet = tm.headMap(endKey, true).entrySet();// 0...2
+        if (entrySet instanceof NavigableSet) {
+            // [2...0]
+            descendingSet = ((NavigableSet) entrySet).descendingSet();
+            iterator = descendingSet.descendingIterator();
+            assertEquals(0, ((Entry) iterator.next()).getValue());// 0...2
+        }
+    }
+
+    public void test_DescendingSubMapEntrySet_headSet() {
+        Set entrySet, headSet;
+        NavigableSet descendingSubMapEntrySet;
+        Iterator iterator, headSetIterator;
+        Entry entry;
+        int value;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            iterator = descendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                headSet = descendingSubMapEntrySet.headSet(entry);
+                headSetIterator = headSet.iterator();
+                for (value = 108; headSetIterator.hasNext(); value--) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                headSet = descendingSubMapEntrySet.headSet(entry, false);
+                headSetIterator = headSet.iterator();
+                for (value = 108; headSetIterator.hasNext(); value--) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                headSet = descendingSubMapEntrySet.headSet(entry, true);
+                headSetIterator = headSet.iterator();
+                for (value = 108; headSetIterator.hasNext(); value--) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+            }
+        }
+
+        entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            iterator = descendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                headSet = descendingSubMapEntrySet.headSet(entry);
+                headSetIterator = headSet.iterator();
+                for (value = 109; headSetIterator.hasNext(); value--) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                headSet = descendingSubMapEntrySet.headSet(entry, false);
+                headSetIterator = headSet.iterator();
+                for (value = 109; headSetIterator.hasNext(); value--) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                headSet = descendingSubMapEntrySet.headSet(entry, true);
+                headSetIterator = headSet.iterator();
+                for (value = 109; headSetIterator.hasNext(); value--) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            iterator = descendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                headSet = descendingSubMapEntrySet.headSet(entry);
+                headSetIterator = headSet.iterator();
+                for (value = 108; headSetIterator.hasNext(); value--) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                headSet = descendingSubMapEntrySet.headSet(entry, false);
+                headSetIterator = headSet.iterator();
+                for (value = 108; headSetIterator.hasNext(); value--) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                headSet = descendingSubMapEntrySet.headSet(entry, true);
+                headSetIterator = headSet.iterator();
+                for (value = 108; headSetIterator.hasNext(); value--) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            iterator = descendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                headSet = descendingSubMapEntrySet.headSet(entry);
+                headSetIterator = headSet.iterator();
+                for (value = 109; headSetIterator.hasNext(); value--) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                headSet = descendingSubMapEntrySet.headSet(entry, false);
+                headSetIterator = headSet.iterator();
+                for (value = 109; headSetIterator.hasNext(); value--) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                headSet = descendingSubMapEntrySet.headSet(entry, true);
+                headSetIterator = headSet.iterator();
+                for (value = 109; headSetIterator.hasNext(); value--) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+            }
+        }
+
+        String endKey = new Integer(2).toString();
+        entrySet = tm.headMap(endKey, true).entrySet();// 0...2
+        if (entrySet instanceof NavigableSet) {
+            // [2...0]
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            iterator = descendingSubMapEntrySet.iterator();
+            iterator.next();// 2
+            iterator.next();// 199
+            entry = (Entry) iterator.next();// 198
+            headSet = descendingSubMapEntrySet.headSet(entry);
+            assertEquals(2, headSet.size());// 2 199
+            headSetIterator = headSet.iterator();
+            assertEquals(2, ((Entry) headSetIterator.next()).getValue());
+            assertEquals(199, ((Entry) headSetIterator.next()).getValue());
+
+            headSet = descendingSubMapEntrySet.headSet(entry, true);
+            assertEquals(3, headSet.size());// 2 199
+            headSetIterator = headSet.iterator();
+            assertEquals(2, ((Entry) headSetIterator.next()).getValue());
+            assertEquals(199, ((Entry) headSetIterator.next()).getValue());
+            assertEquals(198, ((Entry) headSetIterator.next()).getValue());
+        }
+    }
+
+    public void test_DescendingSubMapEntrySet_tailSet() {
+        Set entrySet, tailSet;
+        NavigableSet descendingSubMapEntrySet;
+        Iterator iterator, tailSetIterator;
+        Entry entry;
+        int value;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            iterator = descendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                tailSet = descendingSubMapEntrySet.tailSet(entry);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue(); tailSetIterator
+                        .hasNext(); value--) {
+                    assertEquals(value, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                tailSet = descendingSubMapEntrySet.tailSet(entry, false);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue(); tailSetIterator
+                        .hasNext(); value--) {
+                    assertEquals(value - 1, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                tailSet = descendingSubMapEntrySet.tailSet(entry, true);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue(); tailSetIterator
+                        .hasNext(); value--) {
+                    assertEquals(value, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+            }
+        }
+
+        entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            iterator = descendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                tailSet = descendingSubMapEntrySet.tailSet(entry);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue(); tailSetIterator
+                        .hasNext(); value--) {
+                    assertEquals(value, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                tailSet = descendingSubMapEntrySet.tailSet(entry, false);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue(); tailSetIterator
+                        .hasNext(); value--) {
+                    assertEquals(value - 1, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                tailSet = descendingSubMapEntrySet.tailSet(entry, true);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue(); tailSetIterator
+                        .hasNext(); value--) {
+                    assertEquals(value, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            iterator = descendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                tailSet = descendingSubMapEntrySet.tailSet(entry);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue(); tailSetIterator
+                        .hasNext(); value--) {
+                    assertEquals(value, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                tailSet = descendingSubMapEntrySet.tailSet(entry, false);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue(); tailSetIterator
+                        .hasNext(); value--) {
+                    assertEquals(value - 1, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                tailSet = descendingSubMapEntrySet.tailSet(entry, true);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue(); tailSetIterator
+                        .hasNext(); value--) {
+                    assertEquals(value, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            iterator = descendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                tailSet = descendingSubMapEntrySet.tailSet(entry);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue(); tailSetIterator
+                        .hasNext(); value--) {
+                    assertEquals(value, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                tailSet = descendingSubMapEntrySet.tailSet(entry, false);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue(); tailSetIterator
+                        .hasNext(); value--) {
+                    assertEquals(value - 1, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                tailSet = descendingSubMapEntrySet.tailSet(entry, true);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue(); tailSetIterator
+                        .hasNext(); value--) {
+                    assertEquals(value, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+            }
+        }
+
+        String endKey = new Integer(2).toString();
+        entrySet = tm.headMap(endKey, true).entrySet();// 0...2
+        if (entrySet instanceof NavigableSet) {
+            // [2...0]
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            iterator = descendingSubMapEntrySet.iterator();
+            iterator.next();// 2
+            entry = (Entry) iterator.next();// 199
+            tailSet = descendingSubMapEntrySet.tailSet(entry);
+            tailSetIterator = tailSet.iterator();
+            assertEquals(199, ((Entry) tailSetIterator.next()).getValue());
+
+            tailSet = descendingSubMapEntrySet.tailSet(entry, false);
+            tailSetIterator = tailSet.iterator();
+            assertEquals(198, ((Entry) tailSetIterator.next()).getValue());
+
+            tailSet = descendingSubMapEntrySet.tailSet(entry, true);
+            tailSetIterator = tailSet.iterator();
+            assertEquals(199, ((Entry) tailSetIterator.next()).getValue());
+        }
+    }
+
+    public void test_DescendingSubMapEntrySet_subSet() {
+        Set entrySet, subSet;
+        NavigableSet descendingSubMapEntrySet;
+        Entry startEntry, endEntry;
+        Iterator subSetIterator;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            Iterator iteratorStart = descendingSubMapEntrySet.iterator();
+            while (iteratorStart.hasNext()) {
+                startEntry = (Entry) iteratorStart.next();
+                Iterator iteratorEnd = descendingSubMapEntrySet.iterator();
+                while (iteratorEnd.hasNext()) {
+                    endEntry = (Entry) iteratorEnd.next();
+                    int startIndex = (Integer) startEntry.getValue();
+                    int endIndex = (Integer) endEntry.getValue();
+                    if (startIndex < endIndex) {
+                        try {
+                            descendingSubMapEntrySet.subSet(startEntry,
+                                    endEntry);
+                            fail("should throw IllegalArgumentException");
+                        } catch (IllegalArgumentException e) {
+                            // Expected
+                        }
+
+                        try {
+                            descendingSubMapEntrySet.subSet(startEntry, false,
+                                    endEntry, false);
+                            fail("should throw IllegalArgumentException");
+                        } catch (IllegalArgumentException e) {
+                            // Expected
+                        }
+
+                        try {
+                            descendingSubMapEntrySet.subSet(startEntry, false,
+                                    endEntry, true);
+                            fail("should throw IllegalArgumentException");
+                        } catch (IllegalArgumentException e) {
+                            // Expected
+                        }
+
+                        try {
+                            descendingSubMapEntrySet.subSet(startEntry, true,
+                                    endEntry, false);
+                            fail("should throw IllegalArgumentException");
+                        } catch (IllegalArgumentException e) {
+                            // Expected
+                        }
+
+                        try {
+                            descendingSubMapEntrySet.subSet(startEntry, true,
+                                    endEntry, true);
+                            fail("should throw IllegalArgumentException");
+                        } catch (IllegalArgumentException e) {
+                            // Expected
+                        }
+                    } else {
+                        subSet = descendingSubMapEntrySet.subSet(startEntry,
+                                endEntry);
+                        subSetIterator = subSet.iterator();
+                        for (int index = startIndex; subSetIterator.hasNext(); index--) {
+                            assertEquals(index, ((Entry) subSetIterator.next())
+                                    .getValue());
+                        }
+
+                        subSet = descendingSubMapEntrySet.subSet(startEntry,
+                                false, endEntry, false);
+                        subSetIterator = subSet.iterator();
+                        for (int index = startIndex - 1; subSetIterator
+                                .hasNext(); index--) {
+                            assertEquals(index, ((Entry) subSetIterator.next())
+                                    .getValue());
+                        }
+
+                        subSet = descendingSubMapEntrySet.subSet(startEntry,
+                                false, endEntry, true);
+                        subSetIterator = subSet.iterator();
+                        for (int index = startIndex - 1; subSetIterator
+                                .hasNext(); index--) {
+                            assertEquals(index, ((Entry) subSetIterator.next())
+                                    .getValue());
+                        }
+
+                        subSet = descendingSubMapEntrySet.subSet(startEntry,
+                                true, endEntry, false);
+                        subSetIterator = subSet.iterator();
+                        for (int index = startIndex; subSetIterator.hasNext(); index--) {
+                            assertEquals(index, ((Entry) subSetIterator.next())
+                                    .getValue());
+                        }
+
+                        subSet = descendingSubMapEntrySet.subSet(startEntry,
+                                true, endEntry, true);
+                        subSetIterator = subSet.iterator();
+                        for (int index = startIndex; subSetIterator.hasNext(); index--) {
+                            assertEquals(index, ((Entry) subSetIterator.next())
+                                    .getValue());
+                        }
+                    }
+                }
+            }
+        }
+
+        String endKey = new Integer(2).toString();
+        entrySet = tm.headMap(endKey, true).entrySet();
+        if (entrySet instanceof NavigableSet) {
+            // [2...0]
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            Iterator iterator = descendingSubMapEntrySet.iterator();
+            startEntry = (Entry) iterator.next();
+            iterator.next();
+            endEntry = (Entry) iterator.next();
+            subSet = descendingSubMapEntrySet.subSet(startEntry, endEntry);
+            assertEquals(2, subSet.size());
+
+            subSet = descendingSubMapEntrySet.subSet(startEntry, false,
+                    endEntry, false);
+            assertEquals(1, subSet.size());
+            subSetIterator = subSet.iterator();
+            assertEquals(199, ((Entry) subSetIterator.next()).getValue());
+
+            subSet = descendingSubMapEntrySet.subSet(startEntry, false,
+                    endEntry, true);
+            assertEquals(2, subSet.size());
+            subSetIterator = subSet.iterator();
+            assertEquals(199, ((Entry) subSetIterator.next()).getValue());
+            assertEquals(198, ((Entry) subSetIterator.next()).getValue());
+
+            subSet = descendingSubMapEntrySet.subSet(startEntry, true,
+                    endEntry, false);
+            assertEquals(2, subSet.size());
+            subSetIterator = subSet.iterator();
+            assertEquals(2, ((Entry) subSetIterator.next()).getValue());
+            assertEquals(199, ((Entry) subSetIterator.next()).getValue());
+
+            subSet = descendingSubMapEntrySet.subSet(startEntry, true,
+                    endEntry, true);
+            assertEquals(3, subSet.size());
+            subSetIterator = subSet.iterator();
+            assertEquals(2, ((Entry) subSetIterator.next()).getValue());
+            assertEquals(199, ((Entry) subSetIterator.next()).getValue());
+            assertEquals(198, ((Entry) subSetIterator.next()).getValue());
+        }
+
+        // With Comnparator
+        entrySet = subMap_startExcluded_endExcluded_comparator.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            Iterator iteratorStart = descendingSubMapEntrySet.iterator();
+            while (iteratorStart.hasNext()) {
+                startEntry = (Entry) iteratorStart.next();
+                Iterator iteratorEnd = descendingSubMapEntrySet.iterator();
+                while (iteratorEnd.hasNext()) {
+                    endEntry = (Entry) iteratorEnd.next();
+                    int startIndex = (Integer) startEntry.getValue();
+                    int endIndex = (Integer) endEntry.getValue();
+                    if (startIndex < endIndex) {
+                        try {
+                            descendingSubMapEntrySet.subSet(startEntry,
+                                    endEntry);
+                            fail("should throw IllegalArgumentException");
+                        } catch (IllegalArgumentException e) {
+                            // Expected
+                        }
+
+                        try {
+                            descendingSubMapEntrySet.subSet(startEntry, false,
+                                    endEntry, false);
+                            fail("should throw IllegalArgumentException");
+                        } catch (IllegalArgumentException e) {
+                            // Expected
+                        }
+
+                        try {
+                            descendingSubMapEntrySet.subSet(startEntry, false,
+                                    endEntry, true);
+                            fail("should throw IllegalArgumentException");
+                        } catch (IllegalArgumentException e) {
+                            // Expected
+                        }
+
+                        try {
+                            descendingSubMapEntrySet.subSet(startEntry, true,
+                                    endEntry, false);
+                            fail("should throw IllegalArgumentException");
+                        } catch (IllegalArgumentException e) {
+                            // Expected
+                        }
+
+                        try {
+                            descendingSubMapEntrySet.subSet(startEntry, true,
+                                    endEntry, true);
+                            fail("should throw IllegalArgumentException");
+                        } catch (IllegalArgumentException e) {
+                            // Expected
+                        }
+                    } else {
+                        subSet = descendingSubMapEntrySet.subSet(startEntry,
+                                endEntry);
+                        subSetIterator = subSet.iterator();
+                        for (int index = startIndex; subSetIterator.hasNext(); index--) {
+                            assertEquals(index, ((Entry) subSetIterator.next())
+                                    .getValue());
+                        }
+
+                        subSet = descendingSubMapEntrySet.subSet(startEntry,
+                                false, endEntry, false);
+                        subSetIterator = subSet.iterator();
+                        for (int index = startIndex - 1; subSetIterator
+                                .hasNext(); index--) {
+                            assertEquals(index, ((Entry) subSetIterator.next())
+                                    .getValue());
+                        }
+
+                        subSet = descendingSubMapEntrySet.subSet(startEntry,
+                                false, endEntry, true);
+                        subSetIterator = subSet.iterator();
+                        for (int index = startIndex - 1; subSetIterator
+                                .hasNext(); index--) {
+                            assertEquals(index, ((Entry) subSetIterator.next())
+                                    .getValue());
+                        }
+
+                        subSet = descendingSubMapEntrySet.subSet(startEntry,
+                                true, endEntry, false);
+                        subSetIterator = subSet.iterator();
+                        for (int index = startIndex; subSetIterator.hasNext(); index--) {
+                            assertEquals(index, ((Entry) subSetIterator.next())
+                                    .getValue());
+                        }
+
+                        subSet = descendingSubMapEntrySet.subSet(startEntry,
+                                true, endEntry, true);
+                        subSetIterator = subSet.iterator();
+                        for (int index = startIndex; subSetIterator.hasNext(); index--) {
+                            assertEquals(index, ((Entry) subSetIterator.next())
+                                    .getValue());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void test_DescendingSubMapEntrySet_lower() {
+        Set entrySet, subSet;
+        NavigableSet descendingSubMapEntrySet;
+        Iterator iterator;
+        Entry entry, lowerEntry;
+        int value;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            iterator = descendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) descendingSubMapEntrySet.lower(entry);
+                value = (Integer) entry.getValue();
+                if (value < 108) {
+                    assertEquals(value + 1, lowerEntry.getValue());
+                } else {
+                    assertNull(lowerEntry);
+                }
+            }
+
+            // System.out.println(descendingSubMapEntrySet);
+            // System.out.println(tm);
+            Object afterEnd = this.subMap_default_afterEnd_109.entrySet()
+                    .iterator().next();
+            // System.out.println("o:" + afterEnd);
+            Object x = descendingSubMapEntrySet.lower(afterEnd);
+            // System.out.println("x:" + x);
+            assertNull(x);
+            Object beforeStart = this.subMap_default_beforeStart_100.entrySet()
+                    .iterator().next();
+            // System.out.println("before: " + beforeStart);
+            Object y = descendingSubMapEntrySet.lower(beforeStart);
+            // System.out.println("y: " + y);
+            assertNotNull(y);
+            assertEquals(101, (((Entry) y).getValue()));
+        }
+
+        entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            iterator = descendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) descendingSubMapEntrySet.lower(entry);
+                value = (Integer) entry.getValue();
+                if (value < 109) {
+                    assertEquals(value + 1, lowerEntry.getValue());
+                } else {
+                    assertNull(lowerEntry);
+                }
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            iterator = descendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) descendingSubMapEntrySet.lower(entry);
+                value = (Integer) entry.getValue();
+                if (value < 108) {
+                    assertEquals(value + 1, lowerEntry.getValue());
+                } else {
+                    assertNull(lowerEntry);
+                }
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            iterator = descendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) descendingSubMapEntrySet.lower(entry);
+                value = (Integer) entry.getValue();
+                if (value < 109) {
+                    assertEquals(value + 1, lowerEntry.getValue());
+                } else {
+                    assertNull(lowerEntry);
+                }
+            }
+        }
+
+        String endKey = new Integer(2).toString();
+        entrySet = tm.headMap(endKey, true).entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            iterator = descendingSubMapEntrySet.iterator();
+            iterator.next();// 2
+            iterator.next();// 199
+            entry = (Entry) iterator.next();// 198
+            lowerEntry = (Entry) descendingSubMapEntrySet.lower(entry);
+            assertEquals(199, lowerEntry.getValue());
+        }
+    }
+
+    public void test_DescendingSubMapEntrySet_higher() {
+        Set entrySet, subSet;
+        NavigableSet descendingSubMapEntrySet;
+        Iterator iterator;
+        Entry entry, higherEntry;
+        int value;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            iterator = descendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                higherEntry = (Entry) descendingSubMapEntrySet.higher(entry);
+                value = (Integer) entry.getValue();
+                if (value > 101) {
+                    assertEquals(value - 1, higherEntry.getValue());
+                } else {
+                    assertNull(higherEntry);
+                }
+            }
+
+            Object afterEnd = this.subMap_default_afterEnd_109.entrySet()
+                    .iterator().next();
+            Object x = descendingSubMapEntrySet.higher(afterEnd);
+            assertNotNull(x);
+            assertEquals(108, ((Entry) x).getValue());
+            Object beforeStart = this.subMap_default_beforeStart_100.entrySet()
+                    .iterator().next();
+            Object y = descendingSubMapEntrySet.higher(beforeStart);
+            assertNull(y);
+        }
+
+        entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            iterator = descendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                higherEntry = (Entry) descendingSubMapEntrySet.higher(entry);
+                value = (Integer) entry.getValue();
+                if (value > 101) {
+                    assertEquals(value - 1, higherEntry.getValue());
+                } else {
+                    assertNull(higherEntry);
+                }
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            iterator = descendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                higherEntry = (Entry) descendingSubMapEntrySet.higher(entry);
+                value = (Integer) entry.getValue();
+                if (value > 100) {
+                    assertEquals(value - 1, higherEntry.getValue());
+                } else {
+                    assertNull(higherEntry);
+                }
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            iterator = descendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                higherEntry = (Entry) descendingSubMapEntrySet.higher(entry);
+                value = (Integer) entry.getValue();
+                if (value > 100) {
+                    assertEquals(value - 1, higherEntry.getValue());
+                } else {
+                    assertNull(higherEntry);
+                }
+            }
+        }
+
+        String endKey = new Integer(2).toString();
+        entrySet = tm.headMap(endKey, true).entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            iterator = descendingSubMapEntrySet.iterator();
+            iterator.next();// 2
+            iterator.next();// 199
+            entry = (Entry) iterator.next();// 198
+            higherEntry = (Entry) descendingSubMapEntrySet.higher(entry);
+            assertEquals(197, higherEntry.getValue());
+        }
+
+        // With Comparator
+        entrySet = subMap_startExcluded_endExcluded_comparator.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSubMapEntrySet = ((NavigableSet) entrySet)
+                    .descendingSet();
+            iterator = descendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                higherEntry = (Entry) descendingSubMapEntrySet.higher(entry);
+                value = (Integer) entry.getValue();
+                if (value > 101) {
+                    assertEquals(value - 1, higherEntry.getValue());
+                } else {
+                    assertNull(higherEntry);
+                }
+            }
+
+            Object afterEnd = this.subMap_default_afterEnd_109.entrySet()
+                    .iterator().next();
+            Object x = descendingSubMapEntrySet.higher(afterEnd);
+            assertNotNull(x);
+            assertEquals(108, ((Entry) x).getValue());
+            Object beforeStart = this.subMap_default_beforeStart_100.entrySet()
+                    .iterator().next();
+            Object y = descendingSubMapEntrySet.higher(beforeStart);
+            assertNull(y);
+        }
+    }
+
+    public void test_DescendingSubMapEntrySet_ceiling() {
+        Set entrySet;
+        NavigableSet ascendingSubMapEntrySet, descendingSet;
+        Entry entry;
+        Entry[] entryArray;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            try {
+                descendingSet.ceiling(null);
+                fail("should throw NPE");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            entryArray = (Entry[]) descendingSet
+                    .toArray(new Entry[descendingSet.size()]);
+            for (int i = 0, j = 108; i < entryArray.length; i++) {
+                entry = (Entry) descendingSet.ceiling(entryArray[i]);
+                assertEquals(j - i, entry.getValue());
+            }
+
+            // System.out.println(descendingSet);
+            // System.out.println(tm);
+            Object afterEnd = this.subMap_default_afterEnd_109.entrySet()
+                    .iterator().next();
+            // System.out.println("o:" + afterEnd);//110
+            Object x = descendingSet.ceiling(afterEnd);
+            assertNotNull(x);
+            // System.out.println("x:" + x);
+            assertEquals(108, ((Entry) x).getValue());
+            Object beforeStart = this.subMap_default_beforeStart_100.entrySet()
+                    .iterator().next();
+            // System.out.println("before: " + beforeStart);//0
+            Object y = descendingSet.ceiling(beforeStart);
+            assertNull(y);
+        }
+
+        entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            try {
+                descendingSet.ceiling(null);
+                fail("should throw NPE");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            entryArray = (Entry[]) descendingSet
+                    .toArray(new Entry[descendingSet.size()]);
+            for (int i = 0, j = 109; i < entryArray.length; i++) {
+                entry = (Entry) descendingSet.ceiling(entryArray[i]);
+                assertEquals(j - i, entry.getValue());
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            try {
+                descendingSet.ceiling(null);
+                fail("should throw NPE");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            entryArray = (Entry[]) descendingSet
+                    .toArray(new Entry[descendingSet.size()]);
+            for (int i = 0, j = 108; i < entryArray.length; i++) {
+                entry = (Entry) descendingSet.ceiling(entryArray[i]);
+                assertEquals(j - i, entry.getValue());
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSet = ((NavigableSet) entrySet).descendingSet();
+            try {
+                descendingSet.ceiling(null);
+                fail("should throw NPE");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            entryArray = (Entry[]) descendingSet
+                    .toArray(new Entry[descendingSet.size()]);
+            for (int i = 0, j = 109; i < entryArray.length; i++) {
+                entry = (Entry) descendingSet.ceiling(entryArray[i]);
+                assertEquals(j - i, entry.getValue());
+            }
+        }
+
+        String endKey = new Integer(2).toString();
+        entrySet = tm.headMap(endKey, true).entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSet = ((NavigableSet) entrySet).descendingSet();
+            try {
+                descendingSet.ceiling(null);
+                fail("should throw NPE");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            Iterator iterator = descendingSet.iterator();
+            Entry ceilingEntry;
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                ceilingEntry = (Entry) descendingSet.ceiling(entry);
+                assertEquals(entry, ceilingEntry);
+            }
+        }
+
+    }
+
+    public void test_DescendingSubMapEntrySet_floor() {
+        Set entrySet;
+        NavigableSet ascendingSubMapEntrySet, descendingSet;
+        Entry entry;
+        Entry[] entryArray;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            try {
+                descendingSet.floor(null);
+                fail("should throw NPE");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            entryArray = (Entry[]) descendingSet
+                    .toArray(new Entry[descendingSet.size()]);
+            for (int i = 0, j = 108; i < entryArray.length; i++) {
+                entry = (Entry) descendingSet.floor(entryArray[i]);
+                assertEquals(j - i, entry.getValue());
+            }
+
+            Object afterEnd = this.subMap_default_afterEnd_109.entrySet()
+                    .iterator().next();
+            Object x = descendingSet.floor(afterEnd);
+            assertNull(x);
+
+            Object beforeStart = this.subMap_default_beforeStart_100.entrySet()
+                    .iterator().next();
+            Object y = descendingSet.floor(beforeStart);
+            assertNotNull(y);
+            assertEquals(101, (((Entry) y).getValue()));
+        }
+
+        entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            try {
+                descendingSet.floor(null);
+                fail("should throw NPE");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            entryArray = (Entry[]) descendingSet
+                    .toArray(new Entry[descendingSet.size()]);
+            for (int i = 0, j = 109; i < entryArray.length; i++) {
+                entry = (Entry) descendingSet.floor(entryArray[i]);
+                assertEquals(j - i, entry.getValue());
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            try {
+                descendingSet.floor(null);
+                fail("should throw NPE");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            entryArray = (Entry[]) descendingSet
+                    .toArray(new Entry[descendingSet.size()]);
+            for (int i = 0, j = 108; i < entryArray.length; i++) {
+                entry = (Entry) descendingSet.floor(entryArray[i]);
+                assertEquals(j - i, entry.getValue());
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSet = ((NavigableSet) entrySet).descendingSet();
+            try {
+                descendingSet.floor(null);
+                fail("should throw NPE");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            entryArray = (Entry[]) descendingSet
+                    .toArray(new Entry[descendingSet.size()]);
+            for (int i = 0, j = 109; i < entryArray.length; i++) {
+                entry = (Entry) descendingSet.floor(entryArray[i]);
+                assertEquals(j - i, entry.getValue());
+            }
+        }
+
+        String endKey = new Integer(2).toString();
+        entrySet = tm.headMap(endKey, true).entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSet = ((NavigableSet) entrySet).descendingSet();
+
+            Iterator iterator = descendingSet.iterator();
+            Entry floorEntry;
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                floorEntry = (Entry) descendingSet.floor(entry);
+                assertEquals(entry, floorEntry);
+            }
+        }
+
+        // With Comparator
+        entrySet = subMap_startExcluded_endExcluded_comparator.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            try {
+                descendingSet.floor(null);
+                fail("should throw NPE");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            entryArray = (Entry[]) descendingSet
+                    .toArray(new Entry[descendingSet.size()]);
+            for (int i = 0, j = 108; i < entryArray.length; i++) {
+                entry = (Entry) descendingSet.floor(entryArray[i]);
+                assertEquals(j - i, entry.getValue());
+            }
+        }
+
+        entrySet = subMap_startExcluded_endIncluded_comparator.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            try {
+                descendingSet.floor(null);
+                fail("should throw NPE");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            entryArray = (Entry[]) descendingSet
+                    .toArray(new Entry[descendingSet.size()]);
+            for (int i = 0, j = 109; i < entryArray.length; i++) {
+                entry = (Entry) descendingSet.floor(entryArray[i]);
+                assertEquals(j - i, entry.getValue());
+            }
+        }
+
+        entrySet = subMap_startIncluded_endExcluded_comparator.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            try {
+                descendingSet.floor(null);
+                fail("should throw NPE");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            entryArray = (Entry[]) descendingSet
+                    .toArray(new Entry[descendingSet.size()]);
+            for (int i = 0, j = 108; i < entryArray.length; i++) {
+                entry = (Entry) descendingSet.floor(entryArray[i]);
+                assertEquals(j - i, entry.getValue());
+            }
+        }
+
+        entrySet = subMap_startIncluded_endIncluded_comparator.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            descendingSet = ((NavigableSet) entrySet).descendingSet();
+            try {
+                descendingSet.floor(null);
+                fail("should throw NPE");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            entryArray = (Entry[]) descendingSet
+                    .toArray(new Entry[descendingSet.size()]);
+            for (int i = 0, j = 109; i < entryArray.length; i++) {
+                entry = (Entry) descendingSet.floor(entryArray[i]);
+                assertEquals(j - i, entry.getValue());
+            }
+        }
+    }
+
+    public void test_DescendingSubMapKeySet_comparator() {
+        NavigableSet keySet, descendingKeySet;
+        Comparator comparator;
+        String[] keyArray;
+        Integer value1, value2;
+
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+        assertNull(keySet.comparator());
+        descendingKeySet = keySet.descendingSet();
+        comparator = descendingKeySet.comparator();
+        assertNotNull(comparator);
+        keyArray = (String[]) descendingKeySet
+                .toArray(new String[descendingKeySet.size()]);
+        for (int i = 1; i < keyArray.length; i++) {
+            value1 = Integer.valueOf(keyArray[i - 1]);
+            value2 = Integer.valueOf(keyArray[i]);
+            assertTrue(value1 > value2);
+            assertTrue(comparator.compare(value1, value2) < 0);
+        }
+
+        keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+        assertNull(keySet.comparator());
+        descendingKeySet = keySet.descendingSet();
+        comparator = descendingKeySet.comparator();
+        assertNotNull(comparator);
+        keyArray = (String[]) descendingKeySet
+                .toArray(new String[descendingKeySet.size()]);
+        for (int i = 1; i < keyArray.length; i++) {
+            value1 = Integer.valueOf(keyArray[i - 1]);
+            value2 = Integer.valueOf(keyArray[i]);
+            assertTrue(value1 > value2);
+            assertTrue(comparator.compare(value1, value2) < 0);
+        }
+
+        keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+        assertNull(keySet.comparator());
+        descendingKeySet = keySet.descendingSet();
+        comparator = descendingKeySet.comparator();
+        assertNotNull(comparator);
+        keyArray = (String[]) descendingKeySet
+                .toArray(new String[descendingKeySet.size()]);
+        for (int i = 1; i < keyArray.length; i++) {
+            value1 = Integer.valueOf(keyArray[i - 1]);
+            value2 = Integer.valueOf(keyArray[i]);
+            assertTrue(value1 > value2);
+            assertTrue(comparator.compare(value1, value2) < 0);
+        }
+
+        keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+        assertNull(keySet.comparator());
+        descendingKeySet = keySet.descendingSet();
+        comparator = descendingKeySet.comparator();
+        assertNotNull(comparator);
+        keyArray = (String[]) descendingKeySet
+                .toArray(new String[descendingKeySet.size()]);
+        for (int i = 1; i < keyArray.length; i++) {
+            value1 = Integer.valueOf(keyArray[i - 1]);
+            value2 = Integer.valueOf(keyArray[i]);
+            assertTrue(value1 > value2);
+            assertTrue(comparator.compare(value1, value2) < 0);
+        }
+
+        String endKey = new Integer(2).toString();
+        keySet = tm.headMap(endKey, true).navigableKeySet();
+        assertNull(keySet.comparator());
+        descendingKeySet = keySet.descendingSet();
+        assertNotNull(descendingKeySet.comparator());
+    }
+
+    public void test_AscendingSubMapKeySet_first() {
+        NavigableSet keySet;
+        String firstKey1 = new Integer(100).toString();
+        String firstKey2 = new Integer(101).toString();
+
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+        assertEquals(firstKey2, keySet.first());
+
+        keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+        assertEquals(firstKey2, keySet.first());
+
+        keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+        assertEquals(firstKey1, keySet.first());
+
+        keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+        assertEquals(firstKey1, keySet.first());
+    }
+
+    public void test_DescendingSubMapKeySet_pollFirst_startExcluded_endExcluded() {
+        NavigableSet keySet = navigableMap_startExcluded_endExcluded
+                .navigableKeySet();
+        NavigableSet descendingKeySet = keySet.descendingSet();
+        Iterator iterator = descendingKeySet.iterator();
+        assertEquals(8, keySet.size());
+        for (int value = 101; value < 109; value++) {
+            assertEquals(new Integer(value).toString(), keySet.pollFirst());
+        }
+        assertEquals(0, keySet.size());
+        assertNull(keySet.pollLast());
+    }
+
+    public void test_DescendingSubMapKeySet_pollFirst_startExcluded_endIncluded() {
+        NavigableSet keySet = navigableMap_startExcluded_endIncluded
+                .navigableKeySet();
+        NavigableSet descendingKeySet = keySet.descendingSet();
+        Iterator iterator = descendingKeySet.iterator();
+        assertEquals(9, keySet.size());
+        for (int value = 101; value < 110; value++) {
+            assertEquals(new Integer(value).toString(), keySet.pollFirst());
+        }
+        assertEquals(0, keySet.size());
+        assertNull(keySet.pollLast());
+    }
+
+    public void test_DescendingSubMapKeySet_pollFirst_startIncluded_endExcluded() {
+        NavigableSet keySet = navigableMap_startIncluded_endExcluded
+                .navigableKeySet();
+        NavigableSet descendingKeySet = keySet.descendingSet();
+        Iterator iterator = descendingKeySet.iterator();
+        assertEquals(9, keySet.size());
+        for (int value = 100; value < 109; value++) {
+            assertEquals(new Integer(value).toString(), keySet.pollFirst());
+        }
+        assertEquals(0, keySet.size());
+        assertNull(keySet.pollLast());
+    }
+
+    public void test_DescendingSubMapKeySet_pollFirst_startIncluded_endIncluded() {
+        NavigableSet keySet = navigableMap_startIncluded_endIncluded
+                .navigableKeySet();
+        NavigableSet descendingKeySet = keySet.descendingSet();
+        Iterator iterator = descendingKeySet.iterator();
+        assertEquals(10, keySet.size());
+        for (int value = 100; value < 110; value++) {
+            assertEquals(new Integer(value).toString(), keySet.pollFirst());
+        }
+        assertEquals(0, keySet.size());
+        assertNull(keySet.pollLast());
+    }
+
+    public void test_DescendingSubMapKeySet_pollFirst() {
+        String endKey = new Integer(2).toString();
+        NavigableSet keySet = tm.headMap(endKey, true).navigableKeySet();
+        NavigableSet descendingKeySet = keySet.descendingSet();
+        assertEquals(endKey, descendingKeySet.pollFirst());
+    }
+
+    public void test_DescendingSubMapKeySet_pollLast_startExcluded_endExcluded() {
+        NavigableSet keySet = navigableMap_startExcluded_endExcluded
+                .navigableKeySet();
+        NavigableSet descendingKeySet = keySet.descendingSet();
+        Iterator iterator = descendingKeySet.iterator();
+        assertEquals(8, keySet.size());
+        for (int value = 108; value > 100; value--) {
+            assertEquals(new Integer(value).toString(), keySet.pollLast());
+        }
+        assertEquals(0, keySet.size());
+        assertNull(keySet.pollLast());
+    }
+
+    public void test_DescendingSubMapKeySet_pollLast_startExcluded_endIncluded() {
+        NavigableSet keySet = navigableMap_startExcluded_endIncluded
+                .navigableKeySet();
+        NavigableSet descendingKeySet = keySet.descendingSet();
+        Iterator iterator = descendingKeySet.iterator();
+        assertEquals(9, keySet.size());
+        for (int value = 109; value > 100; value--) {
+            assertEquals(new Integer(value).toString(), keySet.pollLast());
+        }
+        assertEquals(0, keySet.size());
+        assertNull(keySet.pollLast());
+    }
+
+    public void test_DescendingSubMapKeySet_pollLast_startIncluded_endExcluded() {
+        NavigableSet keySet = navigableMap_startIncluded_endExcluded
+                .navigableKeySet();
+        NavigableSet descendingKeySet = keySet.descendingSet();
+        Iterator iterator = descendingKeySet.iterator();
+        assertEquals(9, keySet.size());
+        for (int value = 108; value > 99; value--) {
+            assertEquals(new Integer(value).toString(), keySet.pollLast());
+        }
+        assertEquals(0, keySet.size());
+        assertNull(keySet.pollLast());
+    }
+
+    public void test_DescendingSubMapKeySet_pollLast_startIncluded_endIncluded() {
+        NavigableSet keySet = navigableMap_startIncluded_endIncluded
+                .navigableKeySet();
+        NavigableSet descendingKeySet = keySet.descendingSet();
+        Iterator iterator = descendingKeySet.iterator();
+        assertEquals(10, keySet.size());
+        for (int value = 109; value > 99; value--) {
+            assertEquals(new Integer(value).toString(), keySet.pollLast());
+        }
+        assertEquals(0, keySet.size());
+        assertNull(keySet.pollLast());
+    }
+
+    public void test_DescendingSubMapKeySet_pollLast() {
+        String endKey = new Integer(2).toString();
+        NavigableSet keySet = tm.headMap(endKey, true).navigableKeySet();
+        NavigableSet descendingKeySet = keySet.descendingSet();
+        assertEquals(new Integer(0).toString(), descendingKeySet.pollLast());
+    }
+
+    public void test_DescendingSubMapKeySet_headSet() {
+        NavigableSet keySet, descendingKeySet;
+        SortedSet headSet;
+        String endKey, key;
+        Iterator iterator;
+        int index;
+
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        endKey = new Integer(99).toString();
+        try {
+            descendingKeySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(100).toString();
+        headSet = descendingKeySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 108; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(100, index);
+
+        headSet = descendingKeySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 108; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(100, index);
+
+        try {
+            descendingKeySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(101).toString();
+        headSet = descendingKeySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 108; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(101, index);
+
+        headSet = descendingKeySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 108; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(101, index);
+
+        headSet = descendingKeySet.headSet(endKey, true);
+        iterator = headSet.iterator();
+        for (index = 108; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(100, index);
+
+        for (int i = 102; i < 109; i++) {
+            endKey = new Integer(i).toString();
+            headSet = descendingKeySet.headSet(endKey);
+            iterator = headSet.iterator();
+            int j;
+            for (j = 108; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = descendingKeySet.headSet(endKey, false);
+            iterator = headSet.iterator();
+            for (j = 108; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = descendingKeySet.headSet(endKey, true);
+            iterator = headSet.iterator();
+            for (j = 108; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i - 1, j);
+        }
+
+        endKey = new Integer(109).toString();
+        headSet = descendingKeySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 108; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(108, index);
+
+        headSet = descendingKeySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 108; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(108, index);
+
+        try {
+            descendingKeySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(110).toString();
+        try {
+            descendingKeySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        endKey = new Integer(99).toString();
+        try {
+            descendingKeySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(100).toString();
+        headSet = descendingKeySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(100, index);
+
+        headSet = descendingKeySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(100, index);
+
+        try {
+            descendingKeySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(101).toString();
+        headSet = descendingKeySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(101, index);
+
+        headSet = descendingKeySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(101, index);
+
+        headSet = descendingKeySet.headSet(endKey, true);
+        iterator = headSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(100, index);
+
+        for (int i = 102; i < 109; i++) {
+            endKey = new Integer(i).toString();
+            headSet = descendingKeySet.headSet(endKey);
+            iterator = headSet.iterator();
+            int j;
+            for (j = 109; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = descendingKeySet.headSet(endKey, false);
+            iterator = headSet.iterator();
+            for (j = 109; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = descendingKeySet.headSet(endKey, true);
+            iterator = headSet.iterator();
+            for (j = 109; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i - 1, j);
+        }
+
+        endKey = new Integer(109).toString();
+        headSet = descendingKeySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        headSet = descendingKeySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        headSet = descendingKeySet.headSet(endKey, true);
+        iterator = headSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(108, index);
+
+        endKey = new Integer(110).toString();
+        try {
+            descendingKeySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        endKey = new Integer(99).toString();
+        try {
+            descendingKeySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(100).toString();
+        headSet = descendingKeySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 108; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(100, index);
+
+        headSet = descendingKeySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 108; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(100, index);
+
+        headSet = descendingKeySet.headSet(endKey, true);
+        iterator = headSet.iterator();
+        for (index = 108; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(99, index);
+
+        endKey = new Integer(101).toString();
+        headSet = descendingKeySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 108; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(101, index);
+
+        headSet = descendingKeySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 108; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(101, index);
+
+        headSet = descendingKeySet.headSet(endKey, true);
+        iterator = headSet.iterator();
+        for (index = 108; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(100, index);
+
+        for (int i = 102; i < 109; i++) {
+            endKey = new Integer(i).toString();
+            headSet = descendingKeySet.headSet(endKey);
+            iterator = headSet.iterator();
+            int j;
+            for (j = 108; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = descendingKeySet.headSet(endKey, false);
+            iterator = headSet.iterator();
+            for (j = 108; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = descendingKeySet.headSet(endKey, true);
+            iterator = headSet.iterator();
+            for (j = 108; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i - 1, j);
+        }
+
+        endKey = new Integer(109).toString();
+        headSet = descendingKeySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 108; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(108, index);
+
+        headSet = descendingKeySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 108; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(108, index);
+
+        try {
+            descendingKeySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(110).toString();
+        try {
+            descendingKeySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        endKey = new Integer(99).toString();
+        try {
+            descendingKeySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(100).toString();
+        headSet = descendingKeySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(100, index);
+
+        headSet = descendingKeySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(100, index);
+
+        headSet = descendingKeySet.headSet(endKey, true);
+        iterator = headSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(99, index);
+
+        endKey = new Integer(101).toString();
+        headSet = descendingKeySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(101, index);
+
+        headSet = descendingKeySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(101, index);
+
+        headSet = descendingKeySet.headSet(endKey, true);
+        iterator = headSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(100, index);
+
+        for (int i = 102; i < 109; i++) {
+            endKey = new Integer(i).toString();
+            headSet = descendingKeySet.headSet(endKey);
+            iterator = headSet.iterator();
+            int j;
+            for (j = 109; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = descendingKeySet.headSet(endKey, false);
+            iterator = headSet.iterator();
+            for (j = 109; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = descendingKeySet.headSet(endKey, true);
+            iterator = headSet.iterator();
+            for (j = 109; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i - 1, j);
+        }
+
+        endKey = new Integer(109).toString();
+        headSet = descendingKeySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        headSet = descendingKeySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        headSet = descendingKeySet.headSet(endKey, true);
+        iterator = headSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(108, index);
+
+        endKey = new Integer(110).toString();
+        try {
+            descendingKeySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        key = new Integer(2).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        iterator.next();
+        endKey = (String) iterator.next();
+
+        headSet = descendingKeySet.headSet(endKey);
+        assertEquals(1, headSet.size());
+
+        headSet = descendingKeySet.headSet(endKey, false);
+        assertEquals(1, headSet.size());
+
+        headSet = descendingKeySet.headSet(endKey, true);
+        assertEquals(2, headSet.size());
+
+        key = new Integer(2).toString();
+        keySet = tm.tailMap(key, true).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        iterator.next();
+        endKey = (String) iterator.next();
+        headSet = descendingKeySet.headSet(endKey);
+        assertEquals(1, headSet.size());
+        iterator = headSet.iterator();
+        assertEquals(999, Integer.parseInt((String) iterator.next()));
+    }
+
+    public void test_DescendingSubMapKeySet_tailSet() {
+        NavigableSet keySet, descendingKeySet;
+        SortedSet tailSet;
+        String startKey, key;
+        Iterator iterator;
+        int index;
+
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        startKey = new Integer(99).toString();
+        try {
+            descendingKeySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            descendingKeySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            descendingKeySet.tailSet(startKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        startKey = new Integer(100).toString();
+        try {
+            descendingKeySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        tailSet = descendingKeySet.tailSet(startKey, false);
+        assertEquals(0, tailSet.size());
+
+        startKey = new Integer(101).toString();
+        tailSet = descendingKeySet.tailSet(startKey);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(100, index);
+
+        tailSet = descendingKeySet.tailSet(startKey, true);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(100, index);
+
+        tailSet = descendingKeySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(101, index);
+
+        for (int i = 102; i < 109; i++) {
+            startKey = new Integer(i).toString();
+
+            tailSet = descendingKeySet.tailSet(startKey);
+            iterator = tailSet.iterator();
+            int j;
+            for (j = i; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(100, j);
+
+            tailSet = descendingKeySet.tailSet(startKey, true);
+            iterator = tailSet.iterator();
+            for (j = i; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(100, j);
+
+            tailSet = descendingKeySet.tailSet(startKey, false);
+            iterator = tailSet.iterator();
+            for (j = i; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j - 1).toString(), key);
+            }
+            assertEquals(101, j);
+        }
+
+        startKey = new Integer(109).toString();
+        try {
+            descendingKeySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        tailSet = descendingKeySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index - 1).toString(), key);
+        }
+        assertEquals(101, index);
+
+        startKey = new Integer(110).toString();
+        try {
+            descendingKeySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.tailSet(startKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        startKey = new Integer(99).toString();
+        try {
+            descendingKeySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            descendingKeySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            descendingKeySet.tailSet(startKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        startKey = new Integer(100).toString();
+        try {
+            descendingKeySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        tailSet = descendingKeySet.tailSet(startKey, false);
+        assertEquals(0, tailSet.size());
+
+        startKey = new Integer(101).toString();
+        tailSet = descendingKeySet.tailSet(startKey);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(100, index);
+
+        tailSet = descendingKeySet.tailSet(startKey, true);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(100, index);
+
+        tailSet = descendingKeySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(101, index);
+
+        for (int i = 102; i < 109; i++) {
+            startKey = new Integer(i).toString();
+
+            tailSet = descendingKeySet.tailSet(startKey);
+            iterator = tailSet.iterator();
+            int j;
+            for (j = i; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(100, j);
+
+            tailSet = descendingKeySet.tailSet(startKey, true);
+            iterator = tailSet.iterator();
+            for (j = i; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(100, j);
+
+            tailSet = descendingKeySet.tailSet(startKey, false);
+            iterator = tailSet.iterator();
+            for (j = i; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j - 1).toString(), key);
+            }
+            assertEquals(101, j);
+        }
+
+        startKey = new Integer(109).toString();
+        tailSet = descendingKeySet.tailSet(startKey);
+        iterator = tailSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(100, index);
+
+        tailSet = descendingKeySet.tailSet(startKey, true);
+        iterator = tailSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(100, index);
+
+        tailSet = descendingKeySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index - 1).toString(), key);
+        }
+        assertEquals(101, index);
+
+        startKey = new Integer(110).toString();
+        try {
+            descendingKeySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.tailSet(startKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        startKey = new Integer(99).toString();
+        try {
+            descendingKeySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.tailSet(startKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        startKey = new Integer(100).toString();
+        tailSet = descendingKeySet.tailSet(startKey);
+        assertEquals(1, tailSet.size());
+        iterator = tailSet.iterator();
+        assertEquals(startKey, iterator.next());
+
+        tailSet = descendingKeySet.tailSet(startKey, true);
+        assertEquals(1, tailSet.size());
+        iterator = tailSet.iterator();
+        assertEquals(startKey, iterator.next());
+
+        tailSet = descendingKeySet.tailSet(startKey, false);
+        assertEquals(0, tailSet.size());
+
+        startKey = new Integer(101).toString();
+        tailSet = descendingKeySet.tailSet(startKey);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(99, index);
+
+        tailSet = descendingKeySet.tailSet(startKey, true);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(99, index);
+
+        tailSet = descendingKeySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index - 1).toString(), key);
+        }
+        assertEquals(100, index);
+
+        for (int i = 102; i < 109; i++) {
+            startKey = new Integer(i).toString();
+
+            tailSet = descendingKeySet.tailSet(startKey);
+            iterator = tailSet.iterator();
+            int j;
+            for (j = i; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(99, j);
+
+            tailSet = descendingKeySet.tailSet(startKey, true);
+            iterator = tailSet.iterator();
+            for (j = i; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(99, j);
+
+            tailSet = descendingKeySet.tailSet(startKey, false);
+            iterator = tailSet.iterator();
+            for (j = i; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j - 1).toString(), key);
+            }
+            assertEquals(100, j);
+        }
+
+        startKey = new Integer(109).toString();
+        try {
+            descendingKeySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        tailSet = descendingKeySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index - 1).toString(), key);
+        }
+        assertEquals(100, index);
+
+        startKey = new Integer(110).toString();
+        try {
+            descendingKeySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.tailSet(startKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        startKey = new Integer(99).toString();
+        try {
+            descendingKeySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.tailSet(startKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        startKey = new Integer(100).toString();
+        tailSet = descendingKeySet.tailSet(startKey);
+        assertEquals(1, tailSet.size());
+        iterator = tailSet.iterator();
+        assertEquals(startKey, iterator.next());
+
+        tailSet = descendingKeySet.tailSet(startKey, true);
+        assertEquals(1, tailSet.size());
+        iterator = tailSet.iterator();
+        assertEquals(startKey, iterator.next());
+
+        tailSet = descendingKeySet.tailSet(startKey, false);
+        assertEquals(0, tailSet.size());
+
+        startKey = new Integer(101).toString();
+        tailSet = descendingKeySet.tailSet(startKey);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(99, index);
+
+        tailSet = descendingKeySet.tailSet(startKey, true);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(99, index);
+
+        tailSet = descendingKeySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index - 1).toString(), key);
+        }
+        assertEquals(100, index);
+
+        for (int i = 102; i < 109; i++) {
+            startKey = new Integer(i).toString();
+
+            tailSet = descendingKeySet.tailSet(startKey);
+            iterator = tailSet.iterator();
+            int j;
+            for (j = i; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(99, j);
+
+            tailSet = descendingKeySet.tailSet(startKey, true);
+            iterator = tailSet.iterator();
+            for (j = i; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(99, j);
+
+            tailSet = descendingKeySet.tailSet(startKey, false);
+            iterator = tailSet.iterator();
+            for (j = i; iterator.hasNext(); j--) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j - 1).toString(), key);
+            }
+            assertEquals(100, j);
+        }
+
+        startKey = new Integer(109).toString();
+        tailSet = descendingKeySet.tailSet(startKey);
+        iterator = tailSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(99, index);
+
+        tailSet = descendingKeySet.tailSet(startKey, true);
+        iterator = tailSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(99, index);
+
+        tailSet = descendingKeySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 109; iterator.hasNext(); index--) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index - 1).toString(), key);
+        }
+        assertEquals(100, index);
+
+        startKey = new Integer(110).toString();
+        try {
+            descendingKeySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            descendingKeySet.tailSet(startKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        key = new Integer(2).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        iterator.next();
+        startKey = (String) iterator.next();
+
+        tailSet = descendingKeySet.tailSet(startKey);
+        assertEquals(112, tailSet.size());
+        Iterator tailIterator = tailSet.iterator();
+        assertEquals(new Integer(199).toString(), tailIterator.next());
+
+        tailSet = descendingKeySet.tailSet(startKey, true);
+        assertEquals(112, tailSet.size());
+        tailIterator = tailSet.iterator();
+        assertEquals(new Integer(199).toString(), tailIterator.next());
+
+        tailSet = descendingKeySet.tailSet(startKey, false);
+        assertEquals(111, tailSet.size());
+        tailIterator = tailSet.iterator();
+        assertEquals(new Integer(198).toString(), tailIterator.next());
+    }
+
+    public void test_DescendingSubMapKeySet_subSet() {
+        NavigableSet keySet, descendingKeySet;
+        SortedSet subSet;
+        String startKey, endKey, key;
+        Iterator startIterator, endIterator, subSetIterator;
+
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        startIterator = descendingKeySet.iterator();
+        while (startIterator.hasNext()) {
+            startKey = (String) startIterator.next();
+            endIterator = descendingKeySet.iterator();
+            while (endIterator.hasNext()) {
+                endKey = (String) endIterator.next();
+                int startIndex = Integer.valueOf(startKey);
+                int endIndex = Integer.valueOf(endKey);
+                if (startIndex < endIndex) {
+                    try {
+                        descendingKeySet.subSet(startKey, endKey);
+                        fail("should throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+
+                    try {
+                        descendingKeySet.subSet(startKey, false, endKey, false);
+                        fail("shoudl throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+
+                    try {
+                        descendingKeySet.subSet(startKey, false, endKey, true);
+                        fail("shoudl throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+
+                    try {
+                        descendingKeySet.subSet(startKey, true, endKey, false);
+                        fail("shoudl throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+
+                    try {
+                        descendingKeySet.subSet(startKey, true, endKey, true);
+                        fail("shoudl throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+                } else {
+                    subSet = descendingKeySet.subSet(startKey, endKey);
+                    subSetIterator = subSet.iterator();
+                    for (int index = startIndex; subSetIterator.hasNext(); index--) {
+                        assertEquals(new Integer(index).toString(),
+                                subSetIterator.next());
+                    }
+
+                    subSet = descendingKeySet.subSet(startKey, false, endKey,
+                            false);
+                    subSetIterator = subSet.iterator();
+                    for (int index = startIndex - 1; subSetIterator.hasNext(); index--) {
+                        assertEquals(new Integer(index).toString(),
+                                subSetIterator.next());
+                    }
+
+                    subSet = descendingKeySet.subSet(startKey, false, endKey,
+                            true);
+                    subSetIterator = subSet.iterator();
+                    for (int index = startIndex - 1; subSetIterator.hasNext(); index--) {
+                        assertEquals(new Integer(index).toString(),
+                                subSetIterator.next());
+                    }
+
+                    subSet = descendingKeySet.subSet(startKey, true, endKey,
+                            false);
+                    subSetIterator = subSet.iterator();
+                    for (int index = startIndex; subSetIterator.hasNext(); index--) {
+                        assertEquals(new Integer(index).toString(),
+                                subSetIterator.next());
+                    }
+
+                    subSet = descendingKeySet.subSet(startKey, true, endKey,
+                            true);
+                    subSetIterator = subSet.iterator();
+                    for (int index = startIndex; subSetIterator.hasNext(); index--) {
+                        assertEquals(new Integer(index).toString(),
+                                subSetIterator.next());
+                    }
+                }
+            }
+        }
+
+        endKey = new Integer(2).toString();
+        keySet = tm.headMap(endKey, true).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        Iterator iterator = descendingKeySet.iterator();
+
+        startKey = (String) iterator.next();
+        iterator.next();
+        endKey = (String) iterator.next();
+
+        subSet = descendingKeySet.subSet(startKey, endKey);
+        assertEquals(2, subSet.size());
+        subSetIterator = subSet.iterator();
+        assertEquals(startKey, subSetIterator.next());
+        subSetIterator.next();
+        try {
+            subSetIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        subSet = descendingKeySet.subSet(startKey, false, endKey, false);
+        assertEquals(1, subSet.size());
+        subSetIterator = subSet.iterator();
+        subSetIterator.next();
+        try {
+            subSetIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        subSet = descendingKeySet.subSet(startKey, false, endKey, true);
+        assertEquals(2, subSet.size());
+        subSetIterator = subSet.iterator();
+        subSetIterator.next();
+        assertEquals(endKey, subSetIterator.next());
+        try {
+            subSetIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        subSet = descendingKeySet.subSet(startKey, true, endKey, false);
+        assertEquals(2, subSet.size());
+        subSetIterator = subSet.iterator();
+        assertEquals(startKey, subSetIterator.next());
+        subSetIterator.next();
+        try {
+            subSetIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        subSet = descendingKeySet.subSet(startKey, true, endKey, true);
+        assertEquals(3, subSet.size());
+        subSetIterator = subSet.iterator();
+        assertEquals(startKey, subSetIterator.next());
+        subSetIterator.next();
+        assertEquals(endKey, subSetIterator.next());
+        try {
+            subSetIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        // With Comparator
+        keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+                .navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        startIterator = descendingKeySet.iterator();
+        while (startIterator.hasNext()) {
+            startKey = (String) startIterator.next();
+            endIterator = descendingKeySet.iterator();
+            while (endIterator.hasNext()) {
+                endKey = (String) endIterator.next();
+                int startIndex = Integer.valueOf(startKey);
+                int endIndex = Integer.valueOf(endKey);
+                if (startIndex < endIndex) {
+                    try {
+                        descendingKeySet.subSet(startKey, endKey);
+                        fail("should throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+
+                    try {
+                        descendingKeySet.subSet(startKey, false, endKey, false);
+                        fail("shoudl throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+
+                    try {
+                        descendingKeySet.subSet(startKey, false, endKey, true);
+                        fail("shoudl throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+
+                    try {
+                        descendingKeySet.subSet(startKey, true, endKey, false);
+                        fail("shoudl throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+
+                    try {
+                        descendingKeySet.subSet(startKey, true, endKey, true);
+                        fail("shoudl throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+                } else {
+                    subSet = descendingKeySet.subSet(startKey, endKey);
+                    subSetIterator = subSet.iterator();
+                    for (int index = startIndex; subSetIterator.hasNext(); index--) {
+                        assertEquals(new Integer(index).toString(),
+                                subSetIterator.next());
+                    }
+
+                    subSet = descendingKeySet.subSet(startKey, false, endKey,
+                            false);
+                    subSetIterator = subSet.iterator();
+                    for (int index = startIndex - 1; subSetIterator.hasNext(); index--) {
+                        assertEquals(new Integer(index).toString(),
+                                subSetIterator.next());
+                    }
+
+                    subSet = descendingKeySet.subSet(startKey, false, endKey,
+                            true);
+                    subSetIterator = subSet.iterator();
+                    for (int index = startIndex - 1; subSetIterator.hasNext(); index--) {
+                        assertEquals(new Integer(index).toString(),
+                                subSetIterator.next());
+                    }
+
+                    subSet = descendingKeySet.subSet(startKey, true, endKey,
+                            false);
+                    subSetIterator = subSet.iterator();
+                    for (int index = startIndex; subSetIterator.hasNext(); index--) {
+                        assertEquals(new Integer(index).toString(),
+                                subSetIterator.next());
+                    }
+
+                    subSet = descendingKeySet.subSet(startKey, true, endKey,
+                            true);
+                    subSetIterator = subSet.iterator();
+                    for (int index = startIndex; subSetIterator.hasNext(); index--) {
+                        assertEquals(new Integer(index).toString(),
+                                subSetIterator.next());
+                    }
+                }
+            }
+        }
+    }
+
+    public void test_DescendingSubMapKeySet_descendingSet() {
+        NavigableSet keySet, descendingSet, descendingDescendingSet;
+        int value;
+        Iterator iterator;
+
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+        descendingSet = keySet.descendingSet();
+        descendingDescendingSet = descendingSet.descendingSet();
+        iterator = descendingDescendingSet.iterator();
+        assertTrue(iterator.hasNext());
+        for (value = 101; iterator.hasNext(); value++) {
+            assertEquals(new Integer(value).toString(), iterator.next());
+        }
+        assertEquals(109, value);
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+        descendingSet = keySet.descendingSet();
+        descendingDescendingSet = descendingSet.descendingSet();
+        iterator = descendingDescendingSet.iterator();
+        assertTrue(iterator.hasNext());
+        for (value = 101; iterator.hasNext(); value++) {
+            assertEquals(new Integer(value).toString(), iterator.next());
+        }
+        assertEquals(110, value);
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+        descendingSet = keySet.descendingSet();
+        descendingDescendingSet = descendingSet.descendingSet();
+        iterator = descendingDescendingSet.iterator();
+        assertTrue(iterator.hasNext());
+        for (value = 100; iterator.hasNext(); value++) {
+            assertEquals(new Integer(value).toString(), iterator.next());
+        }
+        assertEquals(109, value);
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+        descendingSet = keySet.descendingSet();
+        descendingDescendingSet = descendingSet.descendingSet();
+        iterator = descendingDescendingSet.iterator();
+        assertTrue(iterator.hasNext());
+        for (value = 100; iterator.hasNext(); value++) {
+            assertEquals(new Integer(value).toString(), iterator.next());
+        }
+        assertEquals(110, value);
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        String endKey = new Integer(2).toString();
+        keySet = tm.headMap(endKey, true).navigableKeySet();
+        descendingSet = keySet.descendingSet();
+        descendingDescendingSet = descendingSet.descendingSet();
+        assertEquals(keySet, descendingDescendingSet);
+
+        String startKey = new Integer(2).toString();
+        keySet = tm.tailMap(startKey, true).navigableKeySet();
+        descendingSet = keySet.descendingSet();
+        descendingDescendingSet = descendingSet.descendingSet();
+        assertEquals(keySet, descendingDescendingSet);
+    }
+
+    public void test_DescendingSubMapKeySet_descendingIterator() {
+        NavigableSet keySet, descendingSet;
+        int value;
+        Iterator iterator, descendingIterator;
+
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+        descendingSet = keySet.descendingSet();
+        descendingIterator = descendingSet.descendingIterator();
+        assertTrue(descendingIterator.hasNext());
+        for (value = 101; descendingIterator.hasNext(); value++) {
+            assertEquals(new Integer(value).toString(), descendingIterator
+                    .next());
+        }
+        assertEquals(109, value);
+        try {
+            descendingIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        descendingSet = descendingSet
+                .headSet(new Integer(105).toString(), true);
+        descendingIterator = descendingSet.descendingIterator();
+        for (value = 105; descendingIterator.hasNext(); value++) {
+            assertEquals(new Integer(value).toString(), descendingIterator
+                    .next());
+        }
+
+        descendingSet = keySet.descendingSet();
+        descendingSet = descendingSet
+                .tailSet(new Integer(105).toString(), true);
+        descendingIterator = descendingSet.descendingIterator();
+        for (value = 101; descendingIterator.hasNext(); value++) {
+            assertEquals(new Integer(value).toString(), descendingIterator
+                    .next());
+        }
+
+        keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+        descendingSet = keySet.descendingSet();
+        descendingIterator = descendingSet.descendingIterator();
+        assertTrue(descendingIterator.hasNext());
+        for (value = 101; descendingIterator.hasNext(); value++) {
+            assertEquals(new Integer(value).toString(), descendingIterator
+                    .next());
+        }
+        assertEquals(110, value);
+        try {
+            descendingIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        descendingSet = descendingSet
+                .headSet(new Integer(105).toString(), true);
+        descendingIterator = descendingSet.descendingIterator();
+        for (value = 105; descendingIterator.hasNext(); value++) {
+            assertEquals(new Integer(value).toString(), descendingIterator
+                    .next());
+        }
+
+        descendingSet = keySet.descendingSet();
+        descendingSet = descendingSet
+                .tailSet(new Integer(105).toString(), true);
+        descendingIterator = descendingSet.descendingIterator();
+        for (value = 101; descendingIterator.hasNext(); value++) {
+            assertEquals(new Integer(value).toString(), descendingIterator
+                    .next());
+        }
+
+        keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+        descendingSet = keySet.descendingSet();
+        descendingIterator = descendingSet.descendingIterator();
+        assertTrue(descendingIterator.hasNext());
+        for (value = 100; descendingIterator.hasNext(); value++) {
+            assertEquals(new Integer(value).toString(), descendingIterator
+                    .next());
+        }
+        assertEquals(109, value);
+        try {
+            descendingIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+        descendingSet = keySet.descendingSet();
+        descendingIterator = descendingSet.descendingIterator();
+        assertTrue(descendingIterator.hasNext());
+        for (value = 100; descendingIterator.hasNext(); value++) {
+            assertEquals(new Integer(value).toString(), descendingIterator
+                    .next());
+        }
+        assertEquals(110, value);
+        try {
+            descendingIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        String endKey = new Integer(2).toString();
+        keySet = tm.headMap(endKey, true).navigableKeySet();
+        iterator = keySet.iterator();
+
+        descendingSet = keySet.descendingSet();
+        descendingIterator = descendingSet.descendingIterator();
+
+        while (iterator.hasNext()) {
+            assertEquals(iterator.next(), descendingIterator.next());
+        }
+
+        String startKey = new Integer(2).toString();
+        keySet = tm.tailMap(startKey, true).navigableKeySet();
+        iterator = keySet.iterator();
+        descendingSet = keySet.descendingSet();
+        descendingIterator = descendingSet.descendingIterator();
+
+        while (iterator.hasNext()) {
+            assertEquals(iterator.next(), descendingIterator.next());
+        }
+    }
+
+    public void test_DescendingSubMapKeySet_lower() {
+        NavigableSet keySet, descendingKeySet;
+        Iterator iterator;
+        String key, lowerKey;
+        int value, lowerValue;
+
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            lowerKey = (String) descendingKeySet.lower(key);
+            if (value < 108) {
+                lowerValue = Integer.valueOf(lowerKey);
+                assertEquals(value + 1, lowerValue);
+            } else {
+                assertNull(lowerKey);
+            }
+        }
+
+        key = new Integer(0).toString();
+        lowerKey = (String) descendingKeySet.lower(key);
+        assertEquals(101, Integer.parseInt(lowerKey));
+
+        key = new Integer(2).toString();
+        lowerKey = (String) descendingKeySet.lower(key);
+        assertNull(lowerKey);
+
+        keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            lowerKey = (String) descendingKeySet.lower(key);
+            if (value < 109) {
+                lowerValue = Integer.valueOf(lowerKey);
+                assertEquals(value + 1, lowerValue);
+            } else {
+                assertNull(lowerKey);
+            }
+        }
+
+        key = new Integer(0).toString();
+        lowerKey = (String) descendingKeySet.lower(key);
+        assertEquals(101, Integer.parseInt(lowerKey));
+
+        key = new Integer(2).toString();
+        lowerKey = (String) descendingKeySet.lower(key);
+        assertNull(lowerKey);
+
+        keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            lowerKey = (String) descendingKeySet.lower(key);
+            if (value < 108) {
+                lowerValue = Integer.valueOf(lowerKey);
+                assertEquals(value + 1, lowerValue);
+            } else {
+                assertNull(lowerKey);
+            }
+        }
+
+        key = new Integer(0).toString();
+        lowerKey = (String) descendingKeySet.lower(key);
+        assertEquals(100, Integer.parseInt(lowerKey));
+
+        key = new Integer(2).toString();
+        lowerKey = (String) descendingKeySet.lower(key);
+        assertNull(lowerKey);
+
+        keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            lowerKey = (String) descendingKeySet.lower(key);
+            if (value < 109) {
+                lowerValue = Integer.valueOf(lowerKey);
+                assertEquals(value + 1, lowerValue);
+            } else {
+                assertNull(lowerKey);
+            }
+        }
+
+        key = new Integer(0).toString();
+        lowerKey = (String) descendingKeySet.lower(key);
+        assertEquals(100, Integer.parseInt(lowerKey));
+
+        key = new Integer(2).toString();
+        lowerKey = (String) descendingKeySet.lower(key);
+        assertNull(lowerKey);
+
+        key = new Integer(2).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        iterator.next();
+        iterator.next();
+        key = (String) iterator.next();
+        lowerKey = (String) descendingKeySet.lower(key);
+        assertEquals(new Integer(199).toString(), lowerKey);
+        try {
+            descendingKeySet.lower(null);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        key = new Integer(0).toString();
+        String endKey = key;
+
+        keySet = tm.headMap(endKey, true).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        assertNull(descendingKeySet.lower(endKey));
+
+        key = new Integer(0).toString();
+        keySet = tm.headMap(endKey, false).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        assertNull(descendingKeySet.lower(endKey));
+
+        endKey = new Integer(999).toString();
+        keySet = tm.headMap(endKey, true).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        assertNull(descendingKeySet.lower(endKey));
+        assertEquals(new Integer(1).toString(), descendingKeySet.lower(key));
+
+        endKey = new Integer(999).toString();
+        keySet = tm.headMap(endKey, false).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        assertNull(descendingKeySet.lower(endKey));
+        assertEquals(new Integer(1).toString(), descendingKeySet.lower(key));
+
+        // With Comparator
+        keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+                .navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            lowerKey = (String) descendingKeySet.lower(key);
+            if (value < 108) {
+                lowerValue = Integer.valueOf(lowerKey);
+                assertEquals(value + 1, lowerValue);
+            } else {
+                assertNull(lowerKey);
+            }
+        }
+
+        key = new Integer(0).toString();
+        lowerKey = (String) descendingKeySet.lower(key);
+        assertEquals(101, Integer.parseInt(lowerKey));
+
+        key = new Integer(2).toString();
+        lowerKey = (String) descendingKeySet.lower(key);
+        assertNull(lowerKey);
+
+        keySet = ((NavigableMap) subMap_startExcluded_endIncluded_comparator)
+                .navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            lowerKey = (String) descendingKeySet.lower(key);
+            if (value < 109) {
+                lowerValue = Integer.valueOf(lowerKey);
+                assertEquals(value + 1, lowerValue);
+            } else {
+                assertNull(lowerKey);
+            }
+        }
+
+        key = new Integer(0).toString();
+        lowerKey = (String) descendingKeySet.lower(key);
+        assertEquals(101, Integer.parseInt(lowerKey));
+
+        key = new Integer(2).toString();
+        lowerKey = (String) descendingKeySet.lower(key);
+        assertNull(lowerKey);
+
+        keySet = ((NavigableMap) subMap_startIncluded_endExcluded_comparator)
+                .navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            lowerKey = (String) descendingKeySet.lower(key);
+            if (value < 108) {
+                lowerValue = Integer.valueOf(lowerKey);
+                assertEquals(value + 1, lowerValue);
+            } else {
+                assertNull(lowerKey);
+            }
+        }
+
+        key = new Integer(0).toString();
+        lowerKey = (String) descendingKeySet.lower(key);
+        assertEquals(100, Integer.parseInt(lowerKey));
+
+        key = new Integer(2).toString();
+        lowerKey = (String) descendingKeySet.lower(key);
+        assertNull(lowerKey);
+
+        keySet = ((NavigableMap) subMap_startIncluded_endIncluded_comparator)
+                .navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            lowerKey = (String) descendingKeySet.lower(key);
+            if (value < 109) {
+                lowerValue = Integer.valueOf(lowerKey);
+                assertEquals(value + 1, lowerValue);
+            } else {
+                assertNull(lowerKey);
+            }
+        }
+    }
+
+    public void test_DescendingSubMapKeySet_higher() {
+        NavigableSet keySet, descendingKeySet;
+        Iterator iterator;
+        String key, higherKey;
+        int value, higherValue;
+
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            higherKey = (String) descendingKeySet.higher(key);
+            if (value > 101) {
+                higherValue = Integer.valueOf(higherKey);
+                assertEquals(value - 1, higherValue);
+            } else {
+                assertNull(higherKey);
+            }
+        }
+
+        key = new Integer(99999).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertEquals("108", higherKey);
+
+        key = new Integer(-1).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertNull(higherKey);
+
+        key = new Integer(100).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertNull(higherKey);
+
+        key = new Integer(0).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertNull(higherKey);
+
+        key = new Integer(2).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertEquals(108, Integer.parseInt(higherKey));
+
+        keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            higherKey = (String) descendingKeySet.higher(key);
+            if (value > 101) {
+                higherValue = Integer.valueOf(higherKey);
+                assertEquals(value - 1, higherValue);
+            } else {
+                assertNull(higherKey);
+            }
+        }
+
+        key = new Integer(99999).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertEquals("109", higherKey);
+
+        key = new Integer(-1).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertNull(higherKey);
+
+        key = new Integer(100).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertNull(higherKey);
+
+        key = new Integer(2).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertEquals(109, Integer.parseInt(higherKey));
+
+        keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            higherKey = (String) descendingKeySet.higher(key);
+            if (value > 100) {
+                higherValue = Integer.valueOf(higherKey);
+                assertEquals(value - 1, higherValue);
+            } else {
+                assertNull(higherKey);
+            }
+        }
+
+        key = new Integer(99999).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertEquals("108", higherKey);
+
+        key = new Integer(-1).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertNull(higherKey);
+
+        key = new Integer(100).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertNull(higherKey);
+
+        key = new Integer(2).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertEquals(108, Integer.parseInt(higherKey));
+
+        keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            higherKey = (String) descendingKeySet.higher(key);
+            if (value > 100) {
+                higherValue = Integer.valueOf(higherKey);
+                assertEquals(value - 1, higherValue);
+            } else {
+                assertNull(higherKey);
+            }
+        }
+
+        key = new Integer(99999).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertEquals("109", higherKey);
+
+        key = new Integer(-1).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertNull(higherKey);
+
+        key = new Integer(100).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertNull(higherKey);
+
+        key = new Integer(2).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertEquals(109, Integer.parseInt(higherKey));
+
+        key = new Integer(2).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        key = (String) iterator.next();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertEquals(new Integer(199).toString(), higherKey);
+        try {
+            descendingKeySet.higher(null);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        key = new Integer(0).toString();
+        String endKey = key;
+
+        keySet = tm.headMap(endKey, true).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        assertNull(descendingKeySet.higher(endKey));
+
+        key = new Integer(0).toString();
+        keySet = tm.headMap(endKey, false).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        assertNull(descendingKeySet.higher(endKey));
+
+        endKey = new Integer(999).toString();
+        keySet = tm.headMap(endKey, true).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        assertEquals(new Integer(998).toString(), descendingKeySet
+                .higher(endKey));
+        assertNull(descendingKeySet.higher(key));
+
+        endKey = new Integer(999).toString();
+        keySet = tm.headMap(endKey, false).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        assertEquals(new Integer(998).toString(), descendingKeySet
+                .higher(endKey));
+        assertNull(descendingKeySet.higher(key));
+
+        // With Comparator
+        keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+                .navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            higherKey = (String) descendingKeySet.higher(key);
+            if (value > 101) {
+                higherValue = Integer.valueOf(higherKey);
+                assertEquals(value - 1, higherValue);
+            } else {
+                assertNull(higherKey);
+            }
+        }
+
+        key = new Integer(99999).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertEquals("108", higherKey);
+
+        key = new Integer(-1).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertNull(higherKey);
+
+        key = new Integer(100).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertNull(higherKey);
+
+        key = new Integer(0).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertNull(higherKey);
+
+        key = new Integer(2).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertEquals(108, Integer.parseInt(higherKey));
+
+        keySet = ((NavigableMap) subMap_startExcluded_endIncluded_comparator)
+                .navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            higherKey = (String) descendingKeySet.higher(key);
+            if (value > 101) {
+                higherValue = Integer.valueOf(higherKey);
+                assertEquals(value - 1, higherValue);
+            } else {
+                assertNull(higherKey);
+            }
+        }
+
+        key = new Integer(99999).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertEquals("109", higherKey);
+
+        key = new Integer(-1).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertNull(higherKey);
+
+        key = new Integer(100).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertNull(higherKey);
+
+        key = new Integer(2).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertEquals(109, Integer.parseInt(higherKey));
+
+        keySet = ((NavigableMap) subMap_startIncluded_endExcluded_comparator)
+                .navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            higherKey = (String) descendingKeySet.higher(key);
+            if (value > 100) {
+                higherValue = Integer.valueOf(higherKey);
+                assertEquals(value - 1, higherValue);
+            } else {
+                assertNull(higherKey);
+            }
+        }
+
+        key = new Integer(99999).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertEquals("108", higherKey);
+
+        key = new Integer(-1).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertNull(higherKey);
+
+        key = new Integer(100).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertNull(higherKey);
+
+        key = new Integer(2).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertEquals(108, Integer.parseInt(higherKey));
+
+        keySet = ((NavigableMap) subMap_startIncluded_endIncluded_comparator)
+                .navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            higherKey = (String) descendingKeySet.higher(key);
+            if (value > 100) {
+                higherValue = Integer.valueOf(higherKey);
+                assertEquals(value - 1, higherValue);
+            } else {
+                assertNull(higherKey);
+            }
+        }
+
+        key = new Integer(99999).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertEquals("109", higherKey);
+
+        key = new Integer(-1).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertNull(higherKey);
+
+        key = new Integer(100).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertNull(higherKey);
+
+        key = new Integer(2).toString();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertEquals(109, Integer.parseInt(higherKey));
+
+        key = new Integer(2).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        iterator = descendingKeySet.iterator();
+        key = (String) iterator.next();
+        higherKey = (String) descendingKeySet.higher(key);
+        assertEquals(new Integer(199).toString(), higherKey);
+        try {
+            descendingKeySet.higher(null);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        key = new Integer(0).toString();
+        endKey = key;
+
+        keySet = tm.headMap(endKey, true).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        assertNull(descendingKeySet.higher(endKey));
+
+        key = new Integer(0).toString();
+        keySet = tm.headMap(endKey, false).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        assertNull(descendingKeySet.higher(endKey));
+
+        endKey = new Integer(999).toString();
+        keySet = tm.headMap(endKey, true).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        assertEquals(new Integer(998).toString(), descendingKeySet
+                .higher(endKey));
+        assertNull(descendingKeySet.higher(key));
+
+        endKey = new Integer(999).toString();
+        keySet = tm.headMap(endKey, false).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        assertEquals(new Integer(998).toString(), descendingKeySet
+                .higher(endKey));
+        assertNull(descendingKeySet.higher(key));
+    }
+
+    public void test_DescendingSubMapKeySet_ceiling() {
+        NavigableSet keySet, descendingKeySet;
+        String[] keyArray;
+        String key, ceilingKey;
+
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        keyArray = (String[]) descendingKeySet
+                .toArray(new String[descendingKeySet.size()]);
+        for (int i = 0, j = 108; i < keyArray.length; i++) {
+            ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]);
+            assertEquals(new Integer(j - i).toString(), ceilingKey);
+        }
+
+        key = new Integer(2).toString();
+        ceilingKey = (String) descendingKeySet.ceiling(key);
+        assertEquals(108, Integer.parseInt(ceilingKey));
+
+        key = new Integer(0).toString();
+        ceilingKey = (String) descendingKeySet.ceiling(key);
+        assertNull(ceilingKey);
+
+        key = new Integer(-1).toString();
+        ceilingKey = (String) descendingKeySet.ceiling(key);
+        assertNull(ceilingKey);
+
+        key = new Integer(99999).toString();
+        ceilingKey = (String) descendingKeySet.ceiling(key);
+        assertEquals(108, Integer.parseInt(ceilingKey));
+
+        keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        keyArray = (String[]) descendingKeySet
+                .toArray(new String[descendingKeySet.size()]);
+        for (int i = 0, j = 109; i < keyArray.length; i++) {
+            ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]);
+            assertEquals(new Integer(j - i).toString(), ceilingKey);
+        }
+
+        keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        keyArray = (String[]) descendingKeySet
+                .toArray(new String[descendingKeySet.size()]);
+        for (int i = 0, j = 108; i < keyArray.length; i++) {
+            ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]);
+            assertEquals(new Integer(j - i).toString(), ceilingKey);
+        }
+
+        keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        keyArray = (String[]) descendingKeySet
+                .toArray(new String[descendingKeySet.size()]);
+        for (int i = 0, j = 109; i < keyArray.length; i++) {
+            ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]);
+            assertEquals(new Integer(j - i).toString(), ceilingKey);
+        }
+
+        key = new Integer(2).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        Iterator iterator = descendingKeySet.iterator();
+        assertEquals(key, descendingKeySet.ceiling(iterator.next()));
+        try {
+            descendingKeySet.ceiling(null);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        key = new Integer(0).toString();
+        String endKey = key;
+
+        keySet = tm.headMap(endKey, true).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        assertEquals(key, descendingKeySet.ceiling(endKey));
+
+        key = new Integer(0).toString();
+        keySet = tm.headMap(endKey, false).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        assertNull(descendingKeySet.ceiling(endKey));
+
+        endKey = new Integer(999).toString();
+        keySet = tm.headMap(endKey, true).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        assertEquals(new Integer(999).toString(), descendingKeySet
+                .ceiling(endKey));
+        assertEquals(key, descendingKeySet.ceiling(key));
+
+        endKey = new Integer(999).toString();
+        keySet = tm.headMap(endKey, false).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        assertEquals(new Integer(998).toString(), descendingKeySet
+                .ceiling(endKey));
+        assertEquals(key, descendingKeySet.ceiling(key));
+
+        // With Comparator
+        keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+                .navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        keyArray = (String[]) descendingKeySet
+                .toArray(new String[descendingKeySet.size()]);
+        for (int i = 0, j = 108; i < keyArray.length; i++) {
+            ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]);
+            assertEquals(new Integer(j - i).toString(), ceilingKey);
+        }
+
+        key = new Integer(2).toString();
+        ceilingKey = (String) descendingKeySet.ceiling(key);
+        assertEquals(108, Integer.parseInt(ceilingKey));
+
+        key = new Integer(0).toString();
+        ceilingKey = (String) descendingKeySet.ceiling(key);
+        assertNull(ceilingKey);
+
+        keySet = ((NavigableMap) subMap_startExcluded_endIncluded_comparator)
+                .navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        keyArray = (String[]) descendingKeySet
+                .toArray(new String[descendingKeySet.size()]);
+        for (int i = 0, j = 109; i < keyArray.length; i++) {
+            ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]);
+            assertEquals(new Integer(j - i).toString(), ceilingKey);
+        }
+
+        keySet = ((NavigableMap) subMap_startIncluded_endExcluded_comparator)
+                .navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        keyArray = (String[]) descendingKeySet
+                .toArray(new String[descendingKeySet.size()]);
+        for (int i = 0, j = 108; i < keyArray.length; i++) {
+            ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]);
+            assertEquals(new Integer(j - i).toString(), ceilingKey);
+        }
+
+        keySet = ((NavigableMap) subMap_startIncluded_endIncluded_comparator)
+                .navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        keyArray = (String[]) descendingKeySet
+                .toArray(new String[descendingKeySet.size()]);
+        for (int i = 0, j = 109; i < keyArray.length; i++) {
+            ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]);
+            assertEquals(new Integer(j - i).toString(), ceilingKey);
+        }
+    }
+
+    public void test_DescendingSubMapKeySet_floor() {
+        NavigableSet keySet, descendingKeySet;
+        String[] keyArray;
+        String floorKey;
+
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        keyArray = (String[]) descendingKeySet
+                .toArray(new String[descendingKeySet.size()]);
+        for (int i = 0, j = 108; i < keyArray.length; i++) {
+            floorKey = (String) descendingKeySet.floor(keyArray[i]);
+            assertEquals(new Integer(j - i).toString(), floorKey);
+        }
+
+        String key = new Integer(0).toString();
+        floorKey = (String) descendingKeySet.floor(key);
+        assertEquals(101, Integer.parseInt(floorKey));
+
+        key = new Integer(2).toString();
+        floorKey = (String) descendingKeySet.floor(key);
+        assertNull(floorKey);
+
+        keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        keyArray = (String[]) descendingKeySet
+                .toArray(new String[descendingKeySet.size()]);
+        for (int i = 0, j = 109; i < keyArray.length; i++) {
+            floorKey = (String) descendingKeySet.floor(keyArray[i]);
+            assertEquals(new Integer(j - i).toString(), floorKey);
+        }
+
+        key = new Integer(0).toString();
+        floorKey = (String) descendingKeySet.floor(key);
+        assertEquals(101, Integer.parseInt(floorKey));
+
+        key = new Integer(2).toString();
+        floorKey = (String) descendingKeySet.floor(key);
+        assertNull(floorKey);
+
+        keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        keyArray = (String[]) descendingKeySet
+                .toArray(new String[descendingKeySet.size()]);
+        for (int i = 0, j = 108; i < keyArray.length; i++) {
+            floorKey = (String) descendingKeySet.floor(keyArray[i]);
+            assertEquals(new Integer(j - i).toString(), floorKey);
+        }
+
+        key = new Integer(0).toString();
+        floorKey = (String) descendingKeySet.floor(key);
+        assertEquals(100, Integer.parseInt(floorKey));
+
+        key = new Integer(2).toString();
+        floorKey = (String) descendingKeySet.floor(key);
+        assertNull(floorKey);
+
+        keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        keyArray = (String[]) descendingKeySet
+                .toArray(new String[descendingKeySet.size()]);
+        for (int i = 0, j = 109; i < keyArray.length; i++) {
+            floorKey = (String) descendingKeySet.floor(keyArray[i]);
+            assertEquals(new Integer(j - i).toString(), floorKey);
+        }
+
+        key = new Integer(0).toString();
+        floorKey = (String) descendingKeySet.floor(key);
+        assertEquals(100, Integer.parseInt(floorKey));
+
+        key = new Integer(2).toString();
+        floorKey = (String) descendingKeySet.floor(key);
+        assertNull(floorKey);
+
+        key = new Integer(2).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        Iterator iterator = descendingKeySet.iterator();
+        assertEquals(key, descendingKeySet.floor(iterator.next()));
+        try {
+            descendingKeySet.floor(null);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        key = new Integer(0).toString();
+        String endKey = key;
+
+        keySet = tm.headMap(endKey, true).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        assertEquals(key, descendingKeySet.floor(endKey));
+
+        key = new Integer(0).toString();
+        keySet = tm.headMap(endKey, false).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        assertNull(descendingKeySet.floor(endKey));
+
+        endKey = new Integer(999).toString();
+        keySet = tm.headMap(endKey, true).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        assertEquals(new Integer(999).toString(), descendingKeySet
+                .floor(endKey));
+        assertEquals(key, descendingKeySet.floor(key));
+
+        endKey = new Integer(999).toString();
+        keySet = tm.headMap(endKey, false).navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        assertNull(descendingKeySet.floor(endKey));
+        assertEquals(key, descendingKeySet.floor(key));
+
+        // With Comparator
+        keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+                .navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        keyArray = (String[]) descendingKeySet
+                .toArray(new String[descendingKeySet.size()]);
+        for (int i = 0, j = 108; i < keyArray.length; i++) {
+            floorKey = (String) descendingKeySet.floor(keyArray[i]);
+            assertEquals(new Integer(j - i).toString(), floorKey);
+        }
+
+        key = new Integer(0).toString();
+        floorKey = (String) descendingKeySet.floor(key);
+        assertEquals(101, Integer.parseInt(floorKey));
+
+        key = new Integer(2).toString();
+        floorKey = (String) descendingKeySet.floor(key);
+        assertNull(floorKey);
+
+        keySet = ((NavigableMap) subMap_startExcluded_endIncluded_comparator)
+                .navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        keyArray = (String[]) descendingKeySet
+                .toArray(new String[descendingKeySet.size()]);
+        for (int i = 0, j = 109; i < keyArray.length; i++) {
+            floorKey = (String) descendingKeySet.floor(keyArray[i]);
+            assertEquals(new Integer(j - i).toString(), floorKey);
+        }
+
+        key = new Integer(0).toString();
+        floorKey = (String) descendingKeySet.floor(key);
+        assertEquals(101, Integer.parseInt(floorKey));
+
+        key = new Integer(2).toString();
+        floorKey = (String) descendingKeySet.floor(key);
+        assertNull(floorKey);
+
+        keySet = ((NavigableMap) subMap_startIncluded_endExcluded_comparator)
+                .navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        keyArray = (String[]) descendingKeySet
+                .toArray(new String[descendingKeySet.size()]);
+        for (int i = 0, j = 108; i < keyArray.length; i++) {
+            floorKey = (String) descendingKeySet.floor(keyArray[i]);
+            assertEquals(new Integer(j - i).toString(), floorKey);
+        }
+
+        key = new Integer(0).toString();
+        floorKey = (String) descendingKeySet.floor(key);
+        assertEquals(100, Integer.parseInt(floorKey));
+
+        key = new Integer(2).toString();
+        floorKey = (String) descendingKeySet.floor(key);
+        assertNull(floorKey);
+
+        keySet = ((NavigableMap) subMap_startIncluded_endIncluded)
+                .navigableKeySet();
+        descendingKeySet = keySet.descendingSet();
+        keyArray = (String[]) descendingKeySet
+                .toArray(new String[descendingKeySet.size()]);
+        for (int i = 0, j = 109; i < keyArray.length; i++) {
+            floorKey = (String) descendingKeySet.floor(keyArray[i]);
+            assertEquals(new Integer(j - i).toString(), floorKey);
+        }
+
+        key = new Integer(0).toString();
+        floorKey = (String) descendingKeySet.floor(key);
+        assertEquals(100, Integer.parseInt(floorKey));
+
+        key = new Integer(2).toString();
+        floorKey = (String) descendingKeySet.floor(key);
+        assertNull(floorKey);
+    }
+
+    public void test_AscendingSubMapKeySet_last() {
+        NavigableSet keySet;
+        String firstKey1 = new Integer(108).toString();
+        String firstKey2 = new Integer(109).toString();
+
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+        assertEquals(firstKey1, keySet.last());
+
+        keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+        assertEquals(firstKey2, keySet.last());
+
+        keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+        assertEquals(firstKey1, keySet.last());
+
+        keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+        assertEquals(firstKey2, keySet.last());
+    }
+
+    public void test_AscendingSubMapKeySet_comparator() {
+        NavigableSet keySet;
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+        assertNull(keySet.comparator());
+
+        keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+        assertNull(keySet.comparator());
+
+        keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+        assertNull(keySet.comparator());
+
+        keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+        assertNull(keySet.comparator());
+
+        String endKey = new Integer(2).toString();
+        keySet = tm.headMap(endKey, true).navigableKeySet();
+        assertNull(keySet.comparator());
+    }
+
+    public void test_AscendingSubMapKeySet_pollFirst_startExcluded_endExcluded() {
+        NavigableSet keySet = navigableMap_startExcluded_endExcluded
+                .navigableKeySet();
+        Iterator iterator = keySet.iterator();
+        assertEquals(8, keySet.size());
+        for (int value = 101; value < 109; value++) {
+            assertEquals(new Integer(value).toString(), keySet.pollFirst());
+        }
+        assertEquals(0, keySet.size());
+        assertNull(keySet.pollFirst());
+    }
+
+    public void test_AscendingSubMapKeySet_pollFirst_startExcluded_endIncluded() {
+        NavigableSet keySet = navigableMap_startExcluded_endIncluded
+                .navigableKeySet();
+        Iterator iterator = keySet.iterator();
+        assertEquals(9, keySet.size());
+        for (int value = 101; value < 110; value++) {
+            assertEquals(new Integer(value).toString(), keySet.pollFirst());
+        }
+        assertEquals(0, keySet.size());
+        assertNull(keySet.pollFirst());
+    }
+
+    public void test_AscendingSubMapKeySet_pollFirst_startIncluded_endExcluded() {
+        NavigableSet keySet = navigableMap_startIncluded_endExcluded
+                .navigableKeySet();
+        Iterator iterator = keySet.iterator();
+        assertEquals(9, keySet.size());
+        for (int value = 100; value < 109; value++) {
+            assertEquals(new Integer(value).toString(), keySet.pollFirst());
+        }
+        assertEquals(0, keySet.size());
+        assertNull(keySet.pollFirst());
+    }
+
+    public void test_AscendingSubMapKeySet_pollFirst_startIncluded_endIncluded() {
+        NavigableSet keySet = navigableMap_startIncluded_endIncluded
+                .navigableKeySet();
+        Iterator iterator = keySet.iterator();
+        assertEquals(10, keySet.size());
+        for (int value = 100; value < 110; value++) {
+            assertEquals(new Integer(value).toString(), keySet.pollFirst());
+        }
+        assertEquals(0, keySet.size());
+        assertNull(keySet.pollFirst());
+    }
+
+    public void test_AscendingSubMapKeySet_pollFirst() {
+        String endKey = new Integer(2).toString();
+        NavigableSet keySet = tm.headMap(endKey, true).navigableKeySet();
+        assertEquals(new Integer(0).toString(), keySet.pollFirst());
+
+        keySet = tm.tailMap(endKey, true).navigableKeySet();
+        assertEquals(new Integer(2).toString(), keySet.pollFirst());
+    }
+
+    public void test_AscendingSubMapKeySet_pollLast_startExcluded_endExcluded() {
+        NavigableSet keySet = navigableMap_startExcluded_endExcluded
+                .navigableKeySet();
+        Iterator iterator = keySet.iterator();
+        assertEquals(8, keySet.size());
+        for (int value = 108; value > 100; value--) {
+            assertEquals(new Integer(value).toString(), keySet.pollLast());
+        }
+        assertEquals(0, keySet.size());
+        assertNull(keySet.pollLast());
+    }
+
+    public void test_AscendingSubMapKeySet_pollLast_startExcluded_endIncluded() {
+        NavigableSet keySet = navigableMap_startExcluded_endIncluded
+                .navigableKeySet();
+        Iterator iterator = keySet.iterator();
+        assertEquals(9, keySet.size());
+        for (int value = 109; value > 100; value--) {
+            assertEquals(new Integer(value).toString(), keySet.pollLast());
+        }
+        assertEquals(0, keySet.size());
+        assertNull(keySet.pollLast());
+    }
+
+    public void test_AscendingSubMapKeySet_pollLast_startIncluded_endExcluded() {
+        NavigableSet keySet = navigableMap_startIncluded_endExcluded
+                .navigableKeySet();
+        Iterator iterator = keySet.iterator();
+        assertEquals(9, keySet.size());
+        for (int value = 108; value > 99; value--) {
+            assertEquals(new Integer(value).toString(), keySet.pollLast());
+        }
+        assertEquals(0, keySet.size());
+        assertNull(keySet.pollLast());
+    }
+
+    public void test_AscendingSubMapKeySet_pollLast_startIncluded_endIncluded() {
+        NavigableSet keySet = navigableMap_startIncluded_endIncluded
+                .navigableKeySet();
+        Iterator iterator = keySet.iterator();
+        assertEquals(10, keySet.size());
+        for (int value = 109; value > 99; value--) {
+            assertEquals(new Integer(value).toString(), keySet.pollLast());
+        }
+        assertEquals(0, keySet.size());
+        assertNull(keySet.pollLast());
+    }
+
+    public void test_AscendingSubMapKeySet_pollLast() {
+        String endKey = new Integer(2).toString();
+        NavigableSet keySet = tm.headMap(endKey, true).navigableKeySet();
+        assertEquals(new Integer(2).toString(), keySet.pollLast());
+
+        keySet = tm.tailMap(endKey, true).navigableKeySet();
+        assertEquals(new Integer(999).toString(), keySet.pollLast());
+    }
+
+    public void test_AscendingSubMapKeySet_descendingIterator() {
+        NavigableSet keySet;
+        Iterator iterator;
+
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+        iterator = keySet.descendingIterator();
+        for (int value = 108; value > 100; value--) {
+            assertTrue(iterator.hasNext());
+            assertEquals(new Integer(value).toString(), iterator.next());
+        }
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+        iterator = keySet.descendingIterator();
+        for (int value = 109; value > 100; value--) {
+            assertTrue(iterator.hasNext());
+            assertEquals(new Integer(value).toString(), iterator.next());
+        }
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+        iterator = keySet.descendingIterator();
+        for (int value = 108; value > 99; value--) {
+            assertTrue(iterator.hasNext());
+            assertEquals(new Integer(value).toString(), iterator.next());
+        }
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+        iterator = keySet.descendingIterator();
+        for (int value = 109; value > 99; value--) {
+            assertTrue(iterator.hasNext());
+            assertEquals(new Integer(value).toString(), iterator.next());
+        }
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        String endKey = new Integer(2).toString();
+        keySet = tm.headMap(endKey, true).navigableKeySet();
+        iterator = keySet.descendingIterator();
+        assertEquals(new Integer(2).toString(), iterator.next());
+        assertEquals(new Integer(199).toString(), iterator.next());
+    }
+
+    public void test_AscendingSubMapKeySet_descendingSet() {
+        NavigableSet keySet, descendingSet;
+        Iterator iterator;
+
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet()
+                .descendingSet();
+        descendingSet = keySet.descendingSet();
+        iterator = descendingSet.iterator();
+        for (int value = 101; value < 109; value++) {
+            assertTrue(iterator.hasNext());
+            assertEquals(new Integer(value).toString(), iterator.next());
+        }
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startExcluded_endIncluded.navigableKeySet()
+                .descendingSet();
+        descendingSet = keySet.descendingSet();
+        iterator = descendingSet.iterator();
+        for (int value = 101; value < 110; value++) {
+            assertTrue(iterator.hasNext());
+            assertEquals(new Integer(value).toString(), iterator.next());
+        }
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startIncluded_endExcluded.navigableKeySet()
+                .descendingSet();
+        descendingSet = keySet.descendingSet();
+        iterator = descendingSet.iterator();
+        for (int value = 100; value < 109; value++) {
+            assertTrue(iterator.hasNext());
+            assertEquals(new Integer(value).toString(), iterator.next());
+        }
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startIncluded_endIncluded.navigableKeySet()
+                .descendingSet();
+        descendingSet = keySet.descendingSet();
+        iterator = descendingSet.iterator();
+        for (int value = 100; value < 110; value++) {
+            assertTrue(iterator.hasNext());
+            assertEquals(new Integer(value).toString(), iterator.next());
+        }
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        String endKey = new Integer(1).toString();
+        keySet = tm.headMap(endKey, true).navigableKeySet();
+        descendingSet = keySet.descendingSet();
+        iterator = descendingSet.iterator();
+        assertEquals(new Integer(1).toString(), iterator.next());
+        assertEquals(new Integer(0).toString(), iterator.next());
+    }
+
+    public void test_AscendingSubMapKeySet_headSet() {
+        NavigableSet keySet;
+        SortedSet headSet;
+        String endKey, key;
+        Iterator iterator;
+
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+        endKey = new Integer(99).toString();
+        try {
+            keySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(100).toString();
+        assertEquals(0, keySet.headSet(endKey).size());
+        assertEquals(0, keySet.headSet(endKey, false).size());
+        try {
+            keySet.headSet(endKey, true).size();
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(101).toString();
+        assertEquals(0, keySet.headSet(endKey).size());
+        assertEquals(0, keySet.headSet(endKey, false).size());
+        assertEquals(1, keySet.headSet(endKey, true).size());
+
+        for (int i = 102; i < 109; i++) {
+            endKey = new Integer(i).toString();
+            headSet = keySet.headSet(endKey);
+            iterator = headSet.iterator();
+            int j;
+            for (j = 101; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = keySet.headSet(endKey, false);
+            iterator = headSet.iterator();
+            for (j = 101; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = keySet.headSet(endKey, true);
+            iterator = headSet.iterator();
+            for (j = 101; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i + 1, j);
+        }
+
+        endKey = new Integer(109).toString();
+        headSet = keySet.headSet(endKey);
+        iterator = headSet.iterator();
+        int index;
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        headSet = keySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(110).toString();
+        try {
+            keySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+        endKey = new Integer(99).toString();
+        try {
+            keySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(100).toString();
+        assertEquals(0, keySet.headSet(endKey).size());
+        assertEquals(0, keySet.headSet(endKey, false).size());
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(101).toString();
+        assertEquals(0, keySet.headSet(endKey).size());
+        assertEquals(0, keySet.headSet(endKey).size());
+        assertEquals(1, keySet.headSet(endKey, true).size());
+
+        for (int i = 102; i < 109; i++) {
+            endKey = new Integer(i).toString();
+
+            headSet = keySet.headSet(endKey);
+            iterator = headSet.iterator();
+            int j;
+            for (j = 101; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = keySet.headSet(endKey, false);
+            iterator = headSet.iterator();
+            for (j = 101; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = keySet.headSet(endKey, true);
+            iterator = headSet.iterator();
+            for (j = 101; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i + 1, j);
+        }
+
+        endKey = new Integer(109).toString();
+        headSet = keySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        headSet = keySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        headSet = keySet.headSet(endKey, true);
+        iterator = headSet.iterator();
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(110, index);
+
+        endKey = new Integer(110).toString();
+        try {
+            keySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+        endKey = new Integer(99).toString();
+        try {
+            keySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(100).toString();
+        assertEquals(0, keySet.headSet(endKey).size());
+        assertEquals(0, keySet.headSet(endKey, false).size());
+        assertEquals(1, keySet.headSet(endKey, true).size());
+
+        endKey = new Integer(101).toString();
+        headSet = keySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(101, index);
+
+        headSet = keySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(101, index);
+
+        headSet = keySet.headSet(endKey, true);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(102, index);
+
+        for (int i = 102; i < 109; i++) {
+            endKey = new Integer(i).toString();
+
+            headSet = keySet.headSet(endKey);
+            iterator = headSet.iterator();
+            int j;
+            for (j = 100; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = keySet.headSet(endKey, false);
+            iterator = headSet.iterator();
+            for (j = 100; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = keySet.headSet(endKey, true);
+            iterator = headSet.iterator();
+            for (j = 100; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i + 1, j);
+        }
+
+        endKey = new Integer(109).toString();
+        headSet = keySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        headSet = keySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(110).toString();
+        try {
+            keySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            keySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+        endKey = new Integer(99).toString();
+        try {
+            keySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(100).toString();
+        assertEquals(0, keySet.headSet(endKey).size());
+        assertEquals(0, keySet.headSet(endKey, false).size());
+        assertEquals(1, keySet.headSet(endKey, true).size());
+
+        endKey = new Integer(101).toString();
+        headSet = keySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(101, index);
+
+        headSet = keySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(101, index);
+
+        headSet = keySet.headSet(endKey, true);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(102, index);
+
+        for (int i = 102; i < 109; i++) {
+            endKey = new Integer(i).toString();
+
+            headSet = keySet.headSet(endKey);
+            iterator = headSet.iterator();
+            int j;
+            for (j = 100; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = keySet.headSet(endKey, false);
+            iterator = headSet.iterator();
+            for (j = 100; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = keySet.headSet(endKey, true);
+            iterator = headSet.iterator();
+            for (j = 100; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i + 1, j);
+        }
+
+        endKey = new Integer(109).toString();
+        headSet = keySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        headSet = keySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        headSet = keySet.headSet(endKey, true);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(110, index);
+
+        endKey = new Integer(110).toString();
+        try {
+            keySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        key = new Integer(1).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        iterator = keySet.iterator();
+        iterator.next();
+        endKey = (String) iterator.next();
+        headSet = keySet.headSet(endKey, false);
+        assertEquals(1, headSet.size());
+        Iterator headSetIterator = headSet.iterator();
+        assertEquals(new Integer(0).toString(), headSetIterator.next());
+        assertFalse(headSetIterator.hasNext());
+        try {
+            headSetIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(null, false);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        headSet = keySet.headSet(endKey, true);
+        assertEquals(2, headSet.size());
+        headSetIterator = headSet.iterator();
+        assertEquals(new Integer(0).toString(), headSetIterator.next());
+        assertEquals(new Integer(1).toString(), headSetIterator.next());
+        assertFalse(headSetIterator.hasNext());
+        try {
+            headSetIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(null, false);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        // With Comparator
+        keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+                .navigableKeySet();
+        endKey = new Integer(99).toString();
+        try {
+            keySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(100).toString();
+        assertEquals(0, keySet.headSet(endKey).size());
+        assertEquals(0, keySet.headSet(endKey, false).size());
+        try {
+            keySet.headSet(endKey, true).size();
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(101).toString();
+        assertEquals(0, keySet.headSet(endKey).size());
+        assertEquals(0, keySet.headSet(endKey, false).size());
+        assertEquals(1, keySet.headSet(endKey, true).size());
+
+        for (int i = 102; i < 109; i++) {
+            endKey = new Integer(i).toString();
+            headSet = keySet.headSet(endKey);
+            iterator = headSet.iterator();
+            int j;
+            for (j = 101; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = keySet.headSet(endKey, false);
+            iterator = headSet.iterator();
+            for (j = 101; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = keySet.headSet(endKey, true);
+            iterator = headSet.iterator();
+            for (j = 101; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i + 1, j);
+        }
+
+        endKey = new Integer(109).toString();
+        headSet = keySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        headSet = keySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(110).toString();
+        try {
+            keySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        keySet = ((NavigableMap) subMap_startExcluded_endIncluded_comparator)
+                .navigableKeySet();
+        endKey = new Integer(99).toString();
+        try {
+            keySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(100).toString();
+        assertEquals(0, keySet.headSet(endKey).size());
+        assertEquals(0, keySet.headSet(endKey, false).size());
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(101).toString();
+        assertEquals(0, keySet.headSet(endKey).size());
+        assertEquals(0, keySet.headSet(endKey).size());
+        assertEquals(1, keySet.headSet(endKey, true).size());
+
+        for (int i = 102; i < 109; i++) {
+            endKey = new Integer(i).toString();
+
+            headSet = keySet.headSet(endKey);
+            iterator = headSet.iterator();
+            int j;
+            for (j = 101; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = keySet.headSet(endKey, false);
+            iterator = headSet.iterator();
+            for (j = 101; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = keySet.headSet(endKey, true);
+            iterator = headSet.iterator();
+            for (j = 101; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i + 1, j);
+        }
+
+        endKey = new Integer(109).toString();
+        headSet = keySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        headSet = keySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        headSet = keySet.headSet(endKey, true);
+        iterator = headSet.iterator();
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(110, index);
+
+        endKey = new Integer(110).toString();
+        try {
+            keySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        keySet = ((NavigableMap) subMap_startIncluded_endExcluded_comparator)
+                .navigableKeySet();
+        endKey = new Integer(99).toString();
+        try {
+            keySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(100).toString();
+        assertEquals(0, keySet.headSet(endKey).size());
+        assertEquals(0, keySet.headSet(endKey, false).size());
+        assertEquals(1, keySet.headSet(endKey, true).size());
+
+        endKey = new Integer(101).toString();
+        headSet = keySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(101, index);
+
+        headSet = keySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(101, index);
+
+        headSet = keySet.headSet(endKey, true);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(102, index);
+
+        for (int i = 102; i < 109; i++) {
+            endKey = new Integer(i).toString();
+
+            headSet = keySet.headSet(endKey);
+            iterator = headSet.iterator();
+            int j;
+            for (j = 100; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = keySet.headSet(endKey, false);
+            iterator = headSet.iterator();
+            for (j = 100; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = keySet.headSet(endKey, true);
+            iterator = headSet.iterator();
+            for (j = 100; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i + 1, j);
+        }
+
+        endKey = new Integer(109).toString();
+        headSet = keySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        headSet = keySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(110).toString();
+        try {
+            keySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            keySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        keySet = ((NavigableMap) subMap_startIncluded_endIncluded_comparator)
+                .navigableKeySet();
+        endKey = new Integer(99).toString();
+        try {
+            keySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        endKey = new Integer(100).toString();
+        assertEquals(0, keySet.headSet(endKey).size());
+        assertEquals(0, keySet.headSet(endKey, false).size());
+        assertEquals(1, keySet.headSet(endKey, true).size());
+
+        endKey = new Integer(101).toString();
+        headSet = keySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(101, index);
+
+        headSet = keySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(101, index);
+
+        headSet = keySet.headSet(endKey, true);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(102, index);
+
+        for (int i = 102; i < 109; i++) {
+            endKey = new Integer(i).toString();
+
+            headSet = keySet.headSet(endKey);
+            iterator = headSet.iterator();
+            int j;
+            for (j = 100; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = keySet.headSet(endKey, false);
+            iterator = headSet.iterator();
+            for (j = 100; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i, j);
+
+            headSet = keySet.headSet(endKey, true);
+            iterator = headSet.iterator();
+            for (j = 100; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(i + 1, j);
+        }
+
+        endKey = new Integer(109).toString();
+        headSet = keySet.headSet(endKey);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        headSet = keySet.headSet(endKey, false);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        headSet = keySet.headSet(endKey, true);
+        iterator = headSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(110, index);
+
+        endKey = new Integer(110).toString();
+        try {
+            keySet.headSet(endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(endKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        key = new Integer(1).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        iterator = keySet.iterator();
+        iterator.next();
+        endKey = (String) iterator.next();
+        headSet = keySet.headSet(endKey, false);
+        assertEquals(1, headSet.size());
+        headSetIterator = headSet.iterator();
+        assertEquals(new Integer(0).toString(), headSetIterator.next());
+        assertFalse(headSetIterator.hasNext());
+        try {
+            headSetIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(null, false);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        headSet = keySet.headSet(endKey, true);
+        assertEquals(2, headSet.size());
+        headSetIterator = headSet.iterator();
+        assertEquals(new Integer(0).toString(), headSetIterator.next());
+        assertEquals(new Integer(1).toString(), headSetIterator.next());
+        assertFalse(headSetIterator.hasNext());
+        try {
+            headSetIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+        try {
+            keySet.headSet(null, false);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+    }
+
+    public void test_AscendingSubMapKeySet_remove() {
+        TreeMap tm_rm = new TreeMap(tm);
+        SortedMap subMap_startExcluded_endExcluded_rm = tm_rm.subMap(
+                objArray[100].toString(), false, objArray[109].toString(),
+                false);
+        assertNull(subMap_startExcluded_endExcluded_rm.remove("0"));
+        try {
+            subMap_startExcluded_endExcluded_rm.remove(null);
+            fail("should throw NPE");
+        } catch (Exception e) {
+            // Expected
+        }
+        for (int i = 101; i < 108; i++) {
+            assertNotNull(subMap_startExcluded_endExcluded_rm
+                    .remove(new Integer(i).toString()));
+        }
+    }
+
+    public void test_AscendingSubMapKeySet_tailSet() {
+        NavigableSet keySet;
+        SortedSet tailSet;
+        String startKey, key;
+        Iterator iterator;
+
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+        startKey = new Integer(99).toString();
+        try {
+            keySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            keySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            keySet.tailSet(startKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        startKey = new Integer(100).toString();
+        try {
+            keySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        int index;
+        tailSet = keySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 101; index < 109; index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+
+        startKey = new Integer(101).toString();
+        tailSet = keySet.tailSet(startKey);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        tailSet = keySet.tailSet(startKey, true);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        tailSet = keySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index + 1).toString(), key);
+        }
+        assertEquals(108, index);
+
+        for (int i = 102; i < 109; i++) {
+            startKey = new Integer(i).toString();
+
+            tailSet = keySet.tailSet(startKey);
+            iterator = tailSet.iterator();
+            int j;
+            for (j = i; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(109, j);
+
+            tailSet = keySet.tailSet(startKey, true);
+            iterator = tailSet.iterator();
+            for (j = i; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(109, j);
+
+            tailSet = keySet.tailSet(startKey, false);
+            iterator = tailSet.iterator();
+            for (j = i; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j + 1).toString(), key);
+            }
+            assertEquals(108, j);
+        }
+
+        startKey = new Integer(109).toString();
+        try {
+            keySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        tailSet = keySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 109; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index + 1).toString(), key);
+        }
+        assertEquals(109, index);
+
+        startKey = new Integer(110).toString();
+        try {
+            keySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+        startKey = new Integer(99).toString();
+        try {
+            keySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        startKey = new Integer(100).toString();
+        try {
+            keySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        tailSet = keySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index + 1).toString(), key);
+        }
+        assertEquals(109, index);
+
+        for (int i = 102; i < 109; i++) {
+            startKey = new Integer(i).toString();
+
+            tailSet = keySet.tailSet(startKey);
+            iterator = tailSet.iterator();
+            int j;
+            for (j = i; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(110, j);
+
+            tailSet = keySet.tailSet(startKey, true);
+            iterator = tailSet.iterator();
+            for (j = i; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(110, j);
+
+            tailSet = keySet.tailSet(startKey, false);
+            iterator = tailSet.iterator();
+            for (j = i; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j + 1).toString(), key);
+            }
+            assertEquals(109, j);
+        }
+
+        startKey = new Integer(109).toString();
+        tailSet = keySet.tailSet(startKey);
+        iterator = tailSet.iterator();
+        for (index = 109; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(110, index);
+
+        tailSet = keySet.tailSet(startKey, true);
+        iterator = tailSet.iterator();
+        for (index = 109; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(110, index);
+
+        tailSet = keySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 109; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index + 1).toString(), key);
+        }
+        assertEquals(109, index);
+
+        startKey = new Integer(110).toString();
+        try {
+            keySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+        startKey = new Integer(99).toString();
+        try {
+            keySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        startKey = new Integer(100).toString();
+        tailSet = keySet.tailSet(startKey);
+        iterator = tailSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        tailSet = keySet.tailSet(startKey, true);
+        iterator = tailSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        tailSet = keySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index + 1).toString(), key);
+        }
+        assertEquals(108, index);
+
+        startKey = new Integer(101).toString();
+        tailSet = keySet.tailSet(startKey);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        tailSet = keySet.tailSet(startKey, true);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        tailSet = keySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index + 1).toString(), key);
+        }
+        assertEquals(108, index);
+
+        for (int i = 102; i < 109; i++) {
+            startKey = new Integer(i).toString();
+
+            tailSet = keySet.tailSet(startKey);
+            iterator = tailSet.iterator();
+            int j;
+            for (j = i; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(109, j);
+
+            tailSet = keySet.tailSet(startKey, true);
+            iterator = tailSet.iterator();
+            for (j = i; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(109, j);
+
+            tailSet = keySet.tailSet(startKey, false);
+            iterator = tailSet.iterator();
+            for (j = i; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j + 1).toString(), key);
+            }
+            assertEquals(108, j);
+        }
+
+        startKey = new Integer(109).toString();
+        try {
+            keySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        tailSet = keySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 109; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index + 1).toString(), key);
+        }
+        assertEquals(109, index);
+
+        startKey = new Integer(110).toString();
+        try {
+            keySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+        startKey = new Integer(99).toString();
+        try {
+            keySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        startKey = new Integer(100).toString();
+        tailSet = keySet.tailSet(startKey);
+        iterator = tailSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(110, index);
+
+        tailSet = keySet.tailSet(startKey, true);
+        iterator = tailSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(110, index);
+
+        tailSet = keySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index + 1).toString(), key);
+        }
+        assertEquals(109, index);
+
+        startKey = new Integer(101).toString();
+        tailSet = keySet.tailSet(startKey);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(110, index);
+
+        tailSet = keySet.tailSet(startKey, true);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(110, index);
+
+        tailSet = keySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index + 1).toString(), key);
+        }
+        assertEquals(109, index);
+
+        for (int i = 102; i < 109; i++) {
+            startKey = new Integer(i).toString();
+
+            tailSet = keySet.tailSet(startKey);
+            iterator = tailSet.iterator();
+            int j;
+            for (j = i; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(110, j);
+
+            tailSet = keySet.tailSet(startKey, true);
+            iterator = tailSet.iterator();
+            for (j = i; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(110, j);
+
+            tailSet = keySet.tailSet(startKey, false);
+            iterator = tailSet.iterator();
+            for (j = i; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j + 1).toString(), key);
+            }
+            assertEquals(109, j);
+        }
+
+        startKey = new Integer(109).toString();
+        tailSet = keySet.tailSet(startKey);
+        iterator = tailSet.iterator();
+        for (index = 109; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(110, index);
+
+        tailSet = keySet.tailSet(startKey, true);
+        iterator = tailSet.iterator();
+        for (index = 109; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(110, index);
+
+        tailSet = keySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 109; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index + 1).toString(), key);
+        }
+        assertEquals(109, index);
+
+        startKey = new Integer(110).toString();
+        try {
+            keySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        String endKey = new Integer(1).toString();
+        keySet = tm.headMap(endKey, true).navigableKeySet();
+        iterator = keySet.iterator();
+        iterator.next();
+        startKey = (String) iterator.next();
+        tailSet = keySet.tailSet(startKey);
+        assertEquals(1, tailSet.size());
+        Iterator tailSetIterator = tailSet.iterator();
+        assertEquals(endKey, tailSetIterator.next());
+        try {
+            tailSetIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(null);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        tailSet = keySet.tailSet(startKey, true);
+        assertEquals(1, tailSet.size());
+        tailSetIterator = tailSet.iterator();
+        assertEquals(endKey, tailSetIterator.next());
+
+        tailSet = keySet.tailSet(startKey, false);
+        assertEquals(0, tailSet.size());
+        tailSetIterator = tailSet.iterator();
+        try {
+            tailSetIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(null, false);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(null, true);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        // With Comparator
+        keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+                .navigableKeySet();
+        startKey = new Integer(99).toString();
+        try {
+            keySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            keySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            keySet.tailSet(startKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        startKey = new Integer(100).toString();
+        try {
+            keySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        tailSet = keySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 101; index < 109; index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+
+        startKey = new Integer(101).toString();
+        tailSet = keySet.tailSet(startKey);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        tailSet = keySet.tailSet(startKey, true);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(109, index);
+
+        tailSet = keySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 101; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index + 1).toString(), key);
+        }
+        assertEquals(108, index);
+
+        for (int i = 102; i < 109; i++) {
+            startKey = new Integer(i).toString();
+
+            tailSet = keySet.tailSet(startKey);
+            iterator = tailSet.iterator();
+            int j;
+            for (j = i; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(109, j);
+
+            tailSet = keySet.tailSet(startKey, true);
+            iterator = tailSet.iterator();
+            for (j = i; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(109, j);
+
+            tailSet = keySet.tailSet(startKey, false);
+            iterator = tailSet.iterator();
+            for (j = i; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j + 1).toString(), key);
+            }
+            assertEquals(108, j);
+        }
+
+        startKey = new Integer(109).toString();
+        try {
+            keySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        tailSet = keySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 109; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index + 1).toString(), key);
+        }
+        assertEquals(109, index);
+
+        startKey = new Integer(110).toString();
+        try {
+            keySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+        startKey = new Integer(99).toString();
+        try {
+            keySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        startKey = new Integer(100).toString();
+        try {
+            keySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        tailSet = keySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 100; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index + 1).toString(), key);
+        }
+        assertEquals(109, index);
+
+        for (int i = 102; i < 109; i++) {
+            startKey = new Integer(i).toString();
+
+            tailSet = keySet.tailSet(startKey);
+            iterator = tailSet.iterator();
+            int j;
+            for (j = i; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(110, j);
+
+            tailSet = keySet.tailSet(startKey, true);
+            iterator = tailSet.iterator();
+            for (j = i; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j).toString(), key);
+            }
+            assertEquals(110, j);
+
+            tailSet = keySet.tailSet(startKey, false);
+            iterator = tailSet.iterator();
+            for (j = i; iterator.hasNext(); j++) {
+                key = (String) iterator.next();
+                assertEquals(new Integer(j + 1).toString(), key);
+            }
+            assertEquals(109, j);
+        }
+
+        startKey = new Integer(109).toString();
+        tailSet = keySet.tailSet(startKey);
+        iterator = tailSet.iterator();
+        for (index = 109; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(110, index);
+
+        tailSet = keySet.tailSet(startKey, true);
+        iterator = tailSet.iterator();
+        for (index = 109; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index).toString(), key);
+        }
+        assertEquals(110, index);
+
+        tailSet = keySet.tailSet(startKey, false);
+        iterator = tailSet.iterator();
+        for (index = 109; iterator.hasNext(); index++) {
+            key = (String) iterator.next();
+            assertEquals(new Integer(index + 1).toString(), key);
+        }
+        assertEquals(109, index);
+
+        startKey = new Integer(110).toString();
+        try {
+            keySet.tailSet(startKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+        try {
+            keySet.tailSet(startKey, false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+    }
+
+    public void test_AscendingSubMapKeySet_subSet() {
+        NavigableSet keySet;
+        SortedSet subSet;
+        String startKey, endKey, key;
+        Iterator startIterator, endIterator, subSetIterator;
+
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+        startIterator = keySet.iterator();
+        while (startIterator.hasNext()) {
+            startKey = (String) startIterator.next();
+            endIterator = keySet.iterator();
+            while (endIterator.hasNext()) {
+                endKey = (String) endIterator.next();
+                int startIndex = Integer.valueOf(startKey);
+                int endIndex = Integer.valueOf(endKey);
+                if (startIndex > endIndex) {
+                    try {
+                        keySet.subSet(startKey, endKey);
+                        fail("should throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+
+                    try {
+                        keySet.subSet(startKey, false, endKey, false);
+                        fail("shoudl throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+
+                    try {
+                        keySet.subSet(startKey, false, endKey, true);
+                        fail("shoudl throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+
+                    try {
+                        keySet.subSet(startKey, true, endKey, false);
+                        fail("shoudl throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+
+                    try {
+                        keySet.subSet(startKey, true, endKey, true);
+                        fail("shoudl throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+                } else {
+                    subSet = keySet.subSet(startKey, endKey);
+                    subSetIterator = subSet.iterator();
+                    for (int index = startIndex; subSetIterator.hasNext(); index++) {
+                        assertEquals(new Integer(index).toString(),
+                                subSetIterator.next());
+                    }
+
+                    subSet = keySet.subSet(startKey, false, endKey, false);
+                    subSetIterator = subSet.iterator();
+                    for (int index = startIndex + 1; subSetIterator.hasNext(); index++) {
+                        assertEquals(new Integer(index).toString(),
+                                subSetIterator.next());
+                    }
+
+                    subSet = keySet.subSet(startKey, false, endKey, true);
+                    subSetIterator = subSet.iterator();
+                    for (int index = startIndex + 1; subSetIterator.hasNext(); index++) {
+                        assertEquals(new Integer(index).toString(),
+                                subSetIterator.next());
+                    }
+
+                    subSet = keySet.subSet(startKey, true, endKey, false);
+                    subSetIterator = subSet.iterator();
+                    for (int index = startIndex; subSetIterator.hasNext(); index++) {
+                        assertEquals(new Integer(index).toString(),
+                                subSetIterator.next());
+                    }
+
+                    subSet = keySet.subSet(startKey, true, endKey, true);
+                    subSetIterator = subSet.iterator();
+                    for (int index = startIndex; subSetIterator.hasNext(); index++) {
+                        assertEquals(new Integer(index).toString(),
+                                subSetIterator.next());
+                    }
+                }
+            }
+        }
+
+        key = new Integer(1).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        Iterator iterator = keySet.iterator();
+        startKey = (String) iterator.next();
+        endKey = (String) iterator.next();
+
+        subSet = keySet.subSet(startKey, endKey);
+        assertEquals(1, subSet.size());
+        subSetIterator = subSet.iterator();
+        assertEquals(new Integer(0).toString(), subSetIterator.next());
+        try {
+            subSetIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        subSet = keySet.subSet(startKey, false, endKey, false);
+        assertEquals(0, subSet.size());
+
+        subSet = keySet.subSet(startKey, false, endKey, true);
+        assertEquals(1, subSet.size());
+        subSetIterator = subSet.iterator();
+        assertEquals(new Integer(1).toString(), subSetIterator.next());
+        try {
+            subSetIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        subSet = keySet.subSet(startKey, true, endKey, false);
+        assertEquals(1, subSet.size());
+        subSetIterator = subSet.iterator();
+        assertEquals(new Integer(0).toString(), subSetIterator.next());
+        try {
+            subSetIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        subSet = keySet.subSet(startKey, true, endKey, true);
+        assertEquals(2, subSet.size());
+        subSetIterator = subSet.iterator();
+        assertEquals(new Integer(0).toString(), subSetIterator.next());
+        assertEquals(new Integer(1).toString(), subSetIterator.next());
+        try {
+            subSetIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(null, null);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(null, false, null, false);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(null, false, null, true);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(null, true, null, false);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(null, true, null, true);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(null, endKey);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(null, false, endKey, false);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(null, false, endKey, true);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(null, true, endKey, false);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(null, true, endKey, true);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(startKey, null);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(startKey, false, null, false);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(startKey, false, null, true);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(startKey, true, null, false);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(startKey, true, null, true);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        // With Comparator
+        keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator)
+                .navigableKeySet();
+        startIterator = keySet.iterator();
+        while (startIterator.hasNext()) {
+            startKey = (String) startIterator.next();
+            endIterator = keySet.iterator();
+            while (endIterator.hasNext()) {
+                endKey = (String) endIterator.next();
+                int startIndex = Integer.valueOf(startKey);
+                int endIndex = Integer.valueOf(endKey);
+                if (startIndex > endIndex) {
+                    try {
+                        keySet.subSet(startKey, endKey);
+                        fail("should throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+
+                    try {
+                        keySet.subSet(startKey, false, endKey, false);
+                        fail("shoudl throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+
+                    try {
+                        keySet.subSet(startKey, false, endKey, true);
+                        fail("shoudl throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+
+                    try {
+                        keySet.subSet(startKey, true, endKey, false);
+                        fail("shoudl throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+
+                    try {
+                        keySet.subSet(startKey, true, endKey, true);
+                        fail("shoudl throw IllegalArgumentException");
+                    } catch (IllegalArgumentException e) {
+                        // Expected
+                    }
+                } else {
+                    subSet = keySet.subSet(startKey, endKey);
+                    subSetIterator = subSet.iterator();
+                    for (int index = startIndex; subSetIterator.hasNext(); index++) {
+                        assertEquals(new Integer(index).toString(),
+                                subSetIterator.next());
+                    }
+
+                    subSet = keySet.subSet(startKey, false, endKey, false);
+                    subSetIterator = subSet.iterator();
+                    for (int index = startIndex + 1; subSetIterator.hasNext(); index++) {
+                        assertEquals(new Integer(index).toString(),
+                                subSetIterator.next());
+                    }
+
+                    subSet = keySet.subSet(startKey, false, endKey, true);
+                    subSetIterator = subSet.iterator();
+                    for (int index = startIndex + 1; subSetIterator.hasNext(); index++) {
+                        assertEquals(new Integer(index).toString(),
+                                subSetIterator.next());
+                    }
+
+                    subSet = keySet.subSet(startKey, true, endKey, false);
+                    subSetIterator = subSet.iterator();
+                    for (int index = startIndex; subSetIterator.hasNext(); index++) {
+                        assertEquals(new Integer(index).toString(),
+                                subSetIterator.next());
+                    }
+
+                    subSet = keySet.subSet(startKey, true, endKey, true);
+                    subSetIterator = subSet.iterator();
+                    for (int index = startIndex; subSetIterator.hasNext(); index++) {
+                        assertEquals(new Integer(index).toString(),
+                                subSetIterator.next());
+                    }
+                }
+            }
+        }
+
+        key = new Integer(1).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        iterator = keySet.iterator();
+        startKey = (String) iterator.next();
+        endKey = (String) iterator.next();
+
+        subSet = keySet.subSet(startKey, endKey);
+        assertEquals(1, subSet.size());
+        subSetIterator = subSet.iterator();
+        assertEquals(new Integer(0).toString(), subSetIterator.next());
+        try {
+            subSetIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        subSet = keySet.subSet(startKey, false, endKey, false);
+        assertEquals(0, subSet.size());
+
+        subSet = keySet.subSet(startKey, false, endKey, true);
+        assertEquals(1, subSet.size());
+        subSetIterator = subSet.iterator();
+        assertEquals(new Integer(1).toString(), subSetIterator.next());
+        try {
+            subSetIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        subSet = keySet.subSet(startKey, true, endKey, false);
+        assertEquals(1, subSet.size());
+        subSetIterator = subSet.iterator();
+        assertEquals(new Integer(0).toString(), subSetIterator.next());
+        try {
+            subSetIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        subSet = keySet.subSet(startKey, true, endKey, true);
+        assertEquals(2, subSet.size());
+        subSetIterator = subSet.iterator();
+        assertEquals(new Integer(0).toString(), subSetIterator.next());
+        assertEquals(new Integer(1).toString(), subSetIterator.next());
+        try {
+            subSetIterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(null, null);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(null, false, null, false);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(null, false, null, true);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(null, true, null, false);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(null, true, null, true);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(null, endKey);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(null, false, endKey, false);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(null, false, endKey, true);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(null, true, endKey, false);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(null, true, endKey, true);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(startKey, null);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(startKey, false, null, false);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(startKey, false, null, true);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(startKey, true, null, false);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            keySet.subSet(startKey, true, null, true);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+    }
+
+    public void test_AscendingSubMapKeySet_lower() {
+        NavigableSet keySet;
+        Iterator iterator;
+        String key, lowerKey;
+        int value, lowerValue;
+
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+        iterator = keySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            lowerKey = (String) keySet.lower(key);
+            if (value > 101) {
+                lowerValue = Integer.valueOf(lowerKey);
+                assertEquals(value - 1, lowerValue);
+            } else {
+                assertNull(lowerKey);
+            }
+        }
+
+        keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+        iterator = keySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            lowerKey = (String) keySet.lower(key);
+            if (value > 101) {
+                lowerValue = Integer.valueOf(lowerKey);
+                assertEquals(value - 1, lowerValue);
+            } else {
+                assertNull(lowerKey);
+            }
+        }
+
+        keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+        iterator = keySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            lowerKey = (String) keySet.lower(key);
+            if (value > 100) {
+                lowerValue = Integer.valueOf(lowerKey);
+                assertEquals(value - 1, lowerValue);
+            } else {
+                assertNull(lowerKey);
+            }
+        }
+
+        keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+        iterator = keySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            lowerKey = (String) keySet.lower(key);
+            if (value > 100) {
+                lowerValue = Integer.valueOf(lowerKey);
+                assertEquals(value - 1, lowerValue);
+            } else {
+                assertNull(lowerKey);
+            }
+        }
+
+        key = new Integer(2).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        iterator = keySet.iterator();
+        iterator.next();// 0
+        String expectedLowerKey = (String) iterator.next();// 1
+        assertEquals(expectedLowerKey, keySet.lower(iterator.next()));
+
+        try {
+            keySet.lower(null);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        key = new Integer(0).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        assertNull(keySet.lower(key));
+
+        key = new Integer(0).toString();
+        keySet = tm.headMap(key, false).navigableKeySet();
+        assertNull(keySet.lower(key));
+
+        key = new Integer(999).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        assertNotNull(keySet.lower(key));
+
+        key = new Integer(999).toString();
+        keySet = tm.headMap(key, false).navigableKeySet();
+        assertNotNull(keySet.lower(key));
+    }
+
+    public void test_AscendingSubMapKeySet_higher() {
+        NavigableSet keySet;
+        Iterator iterator;
+        String key, lowerKey;
+        int value, lowerValue;
+
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+        iterator = keySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            lowerKey = (String) keySet.higher(key);
+            if (value < 108) {
+                lowerValue = Integer.valueOf(lowerKey);
+                assertEquals(value + 1, lowerValue);
+            } else {
+                assertNull(lowerKey);
+            }
+        }
+
+        keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+        iterator = keySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            lowerKey = (String) keySet.higher(key);
+            if (value < 109) {
+                lowerValue = Integer.valueOf(lowerKey);
+                assertEquals(value + 1, lowerValue);
+            } else {
+                assertNull(lowerKey);
+            }
+        }
+
+        keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+        iterator = keySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            lowerKey = (String) keySet.higher(key);
+            if (value < 108) {
+                lowerValue = Integer.valueOf(lowerKey);
+                assertEquals(value + 1, lowerValue);
+            } else {
+                assertNull(lowerKey);
+            }
+        }
+
+        keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+        iterator = keySet.iterator();
+        while (iterator.hasNext()) {
+            key = (String) iterator.next();
+            value = Integer.valueOf(key);
+            lowerKey = (String) keySet.higher(key);
+            if (value < 109) {
+                lowerValue = Integer.valueOf(lowerKey);
+                assertEquals(value + 1, lowerValue);
+            } else {
+                assertNull(lowerKey);
+            }
+        }
+
+        key = new Integer(2).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        iterator = keySet.iterator();
+        iterator.next();// 0
+        iterator.next();// 1
+        lowerKey = (String) keySet.higher(iterator.next());
+        String expectedLowerKey = (String) iterator.next();
+        assertEquals(expectedLowerKey, lowerKey);
+
+        try {
+            keySet.higher(null);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        key = new Integer(0).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        assertNull(keySet.higher(key));
+
+        key = new Integer(0).toString();
+        keySet = tm.headMap(key, false).navigableKeySet();
+        assertNull(keySet.higher(key));
+
+        key = new Integer(999).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        assertNull(keySet.higher(key));
+
+        key = new Integer(999).toString();
+        keySet = tm.headMap(key, false).navigableKeySet();
+        assertNull(keySet.higher(key));
+    }
+
+    public void test_AscendingSubMapKeySet_ceiling() {
+        NavigableSet keySet;
+        String key;
+        String[] keyArray;
+
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+        keyArray = (String[]) keySet.toArray(new String[keySet.size()]);
+        for (int i = 0, j = 101; i < keyArray.length; i++) {
+            key = (String) keySet.ceiling(keyArray[i]);
+            assertEquals(new Integer(i + j).toString(), key);
+        }
+
+        keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+        keyArray = (String[]) keySet.toArray(new String[keySet.size()]);
+        for (int i = 0, j = 101; i < keyArray.length; i++) {
+            key = (String) keySet.ceiling(keyArray[i]);
+            assertEquals(new Integer(i + j).toString(), key);
+        }
+
+        keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+        keyArray = (String[]) keySet.toArray(new String[keySet.size()]);
+        for (int i = 0, j = 100; i < keyArray.length; i++) {
+            key = (String) keySet.ceiling(keyArray[i]);
+            assertEquals(new Integer(i + j).toString(), key);
+        }
+
+        keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+        keyArray = (String[]) keySet.toArray(new String[keySet.size()]);
+        for (int i = 0, j = 100; i < keyArray.length; i++) {
+            key = (String) keySet.ceiling(keyArray[i]);
+            assertEquals(new Integer(i + j).toString(), key);
+        }
+
+        key = new Integer(2).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        Iterator iterator = keySet.iterator();
+        iterator.next();
+        assertEquals(new Integer(1).toString(), keySet.ceiling(iterator.next()));
+
+        try {
+            keySet.ceiling(null);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        key = new Integer(0).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        assertEquals(key, keySet.ceiling(key));
+
+        key = new Integer(0).toString();
+        keySet = tm.headMap(key, false).navigableKeySet();
+        assertNull(keySet.higher(key));
+
+        key = new Integer(999).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        assertNull(keySet.higher(key));
+
+        key = new Integer(999).toString();
+        keySet = tm.headMap(key, false).navigableKeySet();
+        assertNull(keySet.higher(key));
+    }
+
+    public void test_AscendingSubMapKeySet_floor() {
+        NavigableSet keySet;
+        String key;
+        String[] keyArray;
+
+        keySet = navigableMap_startExcluded_endExcluded.navigableKeySet();
+        keyArray = (String[]) keySet.toArray(new String[keySet.size()]);
+        for (int i = 0, j = 101; i < keyArray.length; i++) {
+            key = (String) keySet.floor(keyArray[i]);
+            assertEquals(new Integer(i + j).toString(), key);
+        }
+
+        keySet = navigableMap_startExcluded_endIncluded.navigableKeySet();
+        keyArray = (String[]) keySet.toArray(new String[keySet.size()]);
+        for (int i = 0, j = 101; i < keyArray.length; i++) {
+            key = (String) keySet.floor(keyArray[i]);
+            assertEquals(new Integer(i + j).toString(), key);
+        }
+
+        keySet = navigableMap_startIncluded_endExcluded.navigableKeySet();
+        keyArray = (String[]) keySet.toArray(new String[keySet.size()]);
+        for (int i = 0, j = 100; i < keyArray.length; i++) {
+            key = (String) keySet.floor(keyArray[i]);
+            assertEquals(new Integer(i + j).toString(), key);
+        }
+
+        keySet = navigableMap_startIncluded_endIncluded.navigableKeySet();
+        keyArray = (String[]) keySet.toArray(new String[keySet.size()]);
+        for (int i = 0, j = 100; i < keyArray.length; i++) {
+            key = (String) keySet.floor(keyArray[i]);
+            assertEquals(new Integer(i + j).toString(), key);
+        }
+
+        key = new Integer(2).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        Iterator iterator = keySet.iterator();
+        iterator.next();
+        assertEquals(new Integer(1).toString(), keySet.floor(iterator.next()));
+
+        try {
+            keySet.floor(null);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        key = new Integer(0).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        assertEquals(key, keySet.floor(key));
+
+        key = new Integer(0).toString();
+        keySet = tm.headMap(key, false).navigableKeySet();
+        assertNull(keySet.floor(key));
+
+        key = new Integer(999).toString();
+        keySet = tm.headMap(key, true).navigableKeySet();
+        assertEquals(key, keySet.floor(key));
+
+        key = new Integer(999).toString();
+        keySet = tm.headMap(key, false).navigableKeySet();
+        assertEquals(new Integer(998).toString(), keySet.floor(key));
+    }
+
+    public void test_BoundedEntryIterator_next() {
+        Iterator iterator = subMap_default.entrySet().iterator();
+        assertTrue(iterator.hasNext());
+        for (int i = 100; iterator.hasNext(); i++) {
+            assertEquals(i, ((Entry) iterator.next()).getValue());
+        }
+
+        try {
+            iterator.next();
+            fail("should throw java.util.NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+    }
+
+    public void test_BoundedKeyIterator_next() {
+        Iterator iterator = subMap_default.keySet().iterator();
+        assertTrue(iterator.hasNext());
+        for (int i = 100; iterator.hasNext(); i++) {
+            assertEquals(new Integer(i).toString(), iterator.next());
+        }
+
+        try {
+            iterator.next();
+            fail("should throw java.util.NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+    }
+
+    public void test_BoundedValueIterator_next() {
+        String startKey = new Integer(101).toString();
+        String endKey = new Integer(108).toString();
+
+        Collection values = tm.subMap(startKey, endKey).values();
+        Iterator iter = values.iterator();
+        for (int i = 101; i < 108; i++) {
+            assertEquals(i, iter.next());
+        }
+        try {
+            iter.next();
+            fail("should throw java.util.NoSuchElementException");
+        } catch (Exception e) {
+            // Expected
+        }
+    }
+
+    /*
+     * SubMapEntrySet
+     */
+    public void test_SubMapEntrySet_Constructor() {
+    }
+
+    public void test_SubMapEntrySet_contains() {
+        // covered in test_SubMapEntrySet_remove
+    }
+
+    public void test_SubMapEntrySet_iterator() {
+        Set entrySet = subMap_default.entrySet();
+        Iterator iterator;
+        Entry entry;
+        Integer value = new Integer(100);
+        for (iterator = entrySet.iterator(); iterator.hasNext(); value++) {
+            entry = (Entry) iterator.next();
+            assertEquals(value.toString(), entry.getKey());
+            assertEquals(value, entry.getValue());
+        }
+        assertEquals(109, value.intValue());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        entrySet = subMap_startExcluded_endExcluded.entrySet();
+        value = new Integer(101);
+        for (iterator = entrySet.iterator(); iterator.hasNext(); value++) {
+            entry = (Entry) iterator.next();
+            assertEquals(value.toString(), entry.getKey());
+            assertEquals(value, entry.getValue());
+        }
+        assertEquals(109, value.intValue());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        entrySet = subMap_startExcluded_endIncluded.entrySet();
+        value = new Integer(101);
+        for (iterator = entrySet.iterator(); iterator.hasNext(); value++) {
+            entry = (Entry) iterator.next();
+            assertEquals(value.toString(), entry.getKey());
+            assertEquals(value, entry.getValue());
+        }
+        assertEquals(110, value.intValue());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        entrySet = subMap_startIncluded_endExcluded.entrySet();
+        value = new Integer(100);
+        for (iterator = entrySet.iterator(); iterator.hasNext(); value++) {
+            entry = (Entry) iterator.next();
+            assertEquals(value.toString(), entry.getKey());
+            assertEquals(value, entry.getValue());
+        }
+        assertEquals(109, value.intValue());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        entrySet = subMap_startIncluded_endIncluded.entrySet();
+        value = new Integer(100);
+        for (iterator = entrySet.iterator(); iterator.hasNext(); value++) {
+            entry = (Entry) iterator.next();
+            assertEquals(value.toString(), entry.getKey());
+            assertEquals(value, entry.getValue());
+        }
+        assertEquals(110, value.intValue());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        String startKey = new Integer(-1).toString();
+        String endKey = new Integer(0).toString();
+        SortedMap subMap = tm.subMap(startKey, endKey);
+        entrySet = subMap.entrySet();
+        iterator = entrySet.iterator();
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        endKey = new Integer(1).toString();
+        subMap = tm.subMap(startKey, endKey);
+        entrySet = subMap.entrySet();
+        iterator = entrySet.iterator();
+        assertEquals(0, ((Entry) iterator.next()).getValue());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        endKey = new Integer(2000).toString();
+        subMap = tm.subMap(startKey, endKey);
+        entrySet = subMap.entrySet();
+        iterator = entrySet.iterator();
+        for (int i = 0; i < subMap.size(); i++) {
+            iterator.next();
+        }
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        startKey = new Integer(9).toString();
+        endKey = new Integer(100).toString();
+        try {
+            tm.subMap(startKey, endKey);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        // With Comparator
+        entrySet = subMap_default_comparator.entrySet();
+        value = new Integer(100);
+        for (iterator = entrySet.iterator(); iterator.hasNext(); value++) {
+            entry = (Entry) iterator.next();
+            assertEquals(value.toString(), entry.getKey());
+            assertEquals(value, entry.getValue());
+        }
+        assertEquals(109, value.intValue());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        entrySet = subMap_startExcluded_endExcluded_comparator.entrySet();
+        value = new Integer(101);
+        for (iterator = entrySet.iterator(); iterator.hasNext(); value++) {
+            entry = (Entry) iterator.next();
+            assertEquals(value.toString(), entry.getKey());
+            assertEquals(value, entry.getValue());
+        }
+        assertEquals(109, value.intValue());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        entrySet = subMap_startExcluded_endIncluded_comparator.entrySet();
+        value = new Integer(101);
+        for (iterator = entrySet.iterator(); iterator.hasNext(); value++) {
+            entry = (Entry) iterator.next();
+            assertEquals(value.toString(), entry.getKey());
+            assertEquals(value, entry.getValue());
+        }
+        assertEquals(110, value.intValue());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        entrySet = subMap_startIncluded_endExcluded_comparator.entrySet();
+        value = new Integer(100);
+        for (iterator = entrySet.iterator(); iterator.hasNext(); value++) {
+            entry = (Entry) iterator.next();
+            assertEquals(value.toString(), entry.getKey());
+            assertEquals(value, entry.getValue());
+        }
+        assertEquals(109, value.intValue());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        entrySet = subMap_startIncluded_endIncluded_comparator.entrySet();
+        value = new Integer(100);
+        for (iterator = entrySet.iterator(); iterator.hasNext(); value++) {
+            entry = (Entry) iterator.next();
+            assertEquals(value.toString(), entry.getKey());
+            assertEquals(value, entry.getValue());
+        }
+        assertEquals(110, value.intValue());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+    }
+
+    public void test_SubMapEntrySet_remove() {
+        Set entrySet = subMap_default.entrySet();
+        assertFalse(entrySet.remove(null));
+        int size = entrySet.size();
+        for (int i = 0; i < size; i++) {
+            Iterator iterator = entrySet.iterator();
+            assertTrue(entrySet.remove(iterator.next()));
+        }
+
+        entrySet = subMap_startExcluded_endExcluded.entrySet();
+        assertFalse(entrySet.remove(null));
+        size = entrySet.size();
+        for (int i = 0; i < size; i++) {
+            Iterator iterator = entrySet.iterator();
+            assertTrue(entrySet.remove(iterator.next()));
+        }
+
+        entrySet = subMap_startExcluded_endIncluded.entrySet();
+        assertFalse(entrySet.remove(null));
+        size = entrySet.size();
+        for (int i = 0; i < size; i++) {
+            Iterator iterator = entrySet.iterator();
+            assertTrue(entrySet.remove(iterator.next()));
+        }
+
+        entrySet = subMap_startIncluded_endExcluded.entrySet();
+        assertFalse(entrySet.remove(null));
+        size = entrySet.size();
+        for (int i = 0; i < size; i++) {
+            Iterator iterator = entrySet.iterator();
+            assertTrue(entrySet.remove(iterator.next()));
+        }
+
+        entrySet = subMap_startIncluded_endIncluded.entrySet();
+        assertFalse(entrySet.remove(null));
+        size = entrySet.size();
+        for (int i = 0; i < size; i++) {
+            Iterator iterator = entrySet.iterator();
+            assertTrue(entrySet.remove(iterator.next()));
+        }
+    }
+
+    public void test_SubMapEntrySet_isEmpty() {
+        assertFalse(subMap_default.entrySet().isEmpty());
+        assertFalse(subMap_startExcluded_endExcluded.entrySet().isEmpty());
+        assertFalse(subMap_startExcluded_endIncluded.entrySet().isEmpty());
+        assertFalse(subMap_startIncluded_endExcluded.entrySet().isEmpty());
+        assertFalse(subMap_startIncluded_endIncluded.entrySet().isEmpty());
+
+        String startKey = new Integer(0).toString();
+        String endKey = startKey;
+        SortedMap subMap = tm.subMap(startKey, endKey);
+        assertTrue(subMap.entrySet().isEmpty());
+
+        startKey = new Integer(-1).toString();
+        subMap = tm.subMap(startKey, endKey);
+        assertTrue(subMap.entrySet().isEmpty());
+
+        endKey = new Integer(1).toString();
+        subMap = tm.subMap(startKey, endKey);
+        assertFalse(subMap.entrySet().isEmpty());
+    }
+
+    public void test_SubMapEntrySet_size() {
+        assertEquals(9, subMap_default.entrySet().size());
+        assertEquals(8, subMap_startExcluded_endExcluded.entrySet().size());
+        assertEquals(9, subMap_startExcluded_endIncluded.entrySet().size());
+        assertEquals(9, subMap_startIncluded_endExcluded.entrySet().size());
+        assertEquals(10, subMap_startIncluded_endIncluded.entrySet().size());
+
+        String startKey = new Integer(0).toString();
+        String endKey = new Integer(2).toString();
+        SortedMap subMap = tm.subMap(startKey, endKey);
+        assertEquals(112, subMap.entrySet().size());
+
+        startKey = new Integer(0).toString();
+        endKey = startKey;
+        subMap = tm.subMap(startKey, endKey);
+        assertEquals(0, subMap.entrySet().size());
+
+        startKey = new Integer(-1).toString();
+        endKey = startKey;
+        subMap = tm.subMap(startKey, endKey);
+        assertEquals(0, subMap.entrySet().size());
+
+        endKey = new Integer(1).toString();
+        subMap = tm.subMap(startKey, endKey);
+        assertEquals(1, subMap.entrySet().size());
+
+        startKey = new Integer(999).toString();
+        endKey = startKey;
+        subMap = tm.subMap(startKey, endKey);
+        assertEquals(0, subMap.entrySet().size());
+    }
+
+    /*
+     * SubMapKeySet
+     */
+    public void test_SubMapKeySet_Constructor() {
+        // covered in other test
+    }
+
+    public void test_SubMapKeySet_iterator() {
+        Set keySet = subMap_default.keySet();
+        Iterator iterator = keySet.iterator();
+        for (int i = 0; i < keySet.size(); i++) {
+            assertEquals(new Integer(100 + i).toString(), iterator.next());
+        }
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        keySet = subMap_startExcluded_endExcluded.keySet();
+        iterator = keySet.iterator();
+        for (int i = 0; i < keySet.size(); i++) {
+            assertEquals(new Integer(101 + i).toString(), iterator.next());
+        }
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        keySet = subMap_startExcluded_endIncluded.keySet();
+        iterator = keySet.iterator();
+        for (int i = 0; i < keySet.size(); i++) {
+            assertEquals(new Integer(101 + i).toString(), iterator.next());
+        }
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        keySet = subMap_startIncluded_endExcluded.keySet();
+        iterator = keySet.iterator();
+        for (int i = 0; i < keySet.size(); i++) {
+            assertEquals(new Integer(100 + i).toString(), iterator.next());
+        }
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        keySet = subMap_startIncluded_endIncluded.keySet();
+        iterator = keySet.iterator();
+        for (int i = 0; i < keySet.size(); i++) {
+            assertEquals(new Integer(100 + i).toString(), iterator.next());
+        }
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        // With Comparator
+        keySet = subMap_default_comparator.keySet();
+        iterator = keySet.iterator();
+        for (int i = 0; i < keySet.size(); i++) {
+            assertEquals(new Integer(100 + i).toString(), iterator.next());
+        }
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        keySet = subMap_startExcluded_endExcluded_comparator.keySet();
+        iterator = keySet.iterator();
+        for (int i = 0; i < keySet.size(); i++) {
+            assertEquals(new Integer(101 + i).toString(), iterator.next());
+        }
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        keySet = subMap_startExcluded_endIncluded_comparator.keySet();
+        iterator = keySet.iterator();
+        for (int i = 0; i < keySet.size(); i++) {
+            assertEquals(new Integer(101 + i).toString(), iterator.next());
+        }
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        keySet = subMap_startIncluded_endExcluded_comparator.keySet();
+        iterator = keySet.iterator();
+        for (int i = 0; i < keySet.size(); i++) {
+            assertEquals(new Integer(100 + i).toString(), iterator.next());
+        }
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        keySet = subMap_startIncluded_endIncluded_comparator.keySet();
+        iterator = keySet.iterator();
+        for (int i = 0; i < keySet.size(); i++) {
+            assertEquals(new Integer(100 + i).toString(), iterator.next());
+        }
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+    }
+
+    public void test_SubMapKeySet_isEmpty() {
+        assertFalse(subMap_default.keySet().isEmpty());
+        assertFalse(subMap_startExcluded_endExcluded.keySet().isEmpty());
+        assertFalse(subMap_startExcluded_endIncluded.keySet().isEmpty());
+        assertFalse(subMap_startIncluded_endExcluded.keySet().isEmpty());
+        assertFalse(subMap_startIncluded_endIncluded.keySet().isEmpty());
+
+        String startKey = new Integer(0).toString();
+        String endKey = startKey;
+        SortedMap subMap = tm.subMap(startKey, endKey);
+        assertTrue(subMap.keySet().isEmpty());
+
+        startKey = new Integer(999).toString();
+        endKey = startKey;
+        subMap = tm.subMap(startKey, endKey);
+        assertTrue(subMap.keySet().isEmpty());
+
+        startKey = new Integer(-1).toString();
+        endKey = new Integer(1).toString();
+        subMap = tm.subMap(startKey, endKey);
+        assertFalse(subMap.keySet().isEmpty());
+
+        endKey = new Integer(0).toString();
+        subMap = tm.subMap(startKey, endKey);
+        assertTrue(subMap.keySet().isEmpty());
+    }
+
+    public void test_SubMapKeySet_contains() {
+        Set keySet = subMap_default.keySet();
+        try {
+            keySet.contains(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        String key = new Integer(-1).toString();
+        assertFalse(keySet.contains(key));
+        key = new Integer(99).toString();
+        assertFalse(keySet.contains(key));
+        key = new Integer(100).toString();
+        assertTrue(keySet.contains(key));
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertTrue(keySet.contains(key));
+        }
+        key = new Integer(109).toString();
+        assertFalse(keySet.contains(key));
+        key = new Integer(110).toString();
+        assertFalse(keySet.contains(key));
+        key = new Integer(1001).toString();
+        assertFalse(keySet.contains(key));
+
+        keySet = subMap_startExcluded_endExcluded.keySet();
+        try {
+            keySet.contains(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        key = new Integer(-1).toString();
+        assertFalse(keySet.contains(key));
+        key = new Integer(99).toString();
+        assertFalse(keySet.contains(key));
+        key = new Integer(100).toString();
+        assertFalse(keySet.contains(key));
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertTrue(keySet.contains(key));
+        }
+        key = new Integer(109).toString();
+        assertFalse(keySet.contains(key));
+        key = new Integer(110).toString();
+        assertFalse(keySet.contains(key));
+        key = new Integer(1001).toString();
+        assertFalse(keySet.contains(key));
+
+        keySet = subMap_startExcluded_endIncluded.keySet();
+        try {
+            keySet.contains(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        key = new Integer(-1).toString();
+        assertFalse(keySet.contains(key));
+        key = new Integer(99).toString();
+        assertFalse(keySet.contains(key));
+        key = new Integer(100).toString();
+        assertFalse(keySet.contains(key));
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertTrue(keySet.contains(key));
+        }
+        key = new Integer(109).toString();
+        assertTrue(keySet.contains(key));
+        key = new Integer(110).toString();
+        assertFalse(keySet.contains(key));
+        key = new Integer(1001).toString();
+        assertFalse(keySet.contains(key));
+
+        keySet = subMap_startIncluded_endExcluded.keySet();
+        try {
+            keySet.contains(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        key = new Integer(-1).toString();
+        assertFalse(keySet.contains(key));
+        key = new Integer(99).toString();
+        assertFalse(keySet.contains(key));
+        key = new Integer(100).toString();
+        assertTrue(keySet.contains(key));
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertTrue(keySet.contains(key));
+        }
+        key = new Integer(109).toString();
+        assertFalse(keySet.contains(key));
+        key = new Integer(110).toString();
+        assertFalse(keySet.contains(key));
+        key = new Integer(1001).toString();
+        assertFalse(keySet.contains(key));
+
+        keySet = subMap_startIncluded_endIncluded.keySet();
+        try {
+            keySet.contains(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        key = new Integer(-1).toString();
+        assertFalse(keySet.contains(key));
+        key = new Integer(99).toString();
+        assertFalse(keySet.contains(key));
+        key = new Integer(100).toString();
+        assertTrue(keySet.contains(key));
+        for (int i = 101; i < 109; i++) {
+            key = new Integer(i).toString();
+            assertTrue(keySet.contains(key));
+        }
+        key = new Integer(109).toString();
+        assertTrue(keySet.contains(key));
+        key = new Integer(110).toString();
+        assertFalse(keySet.contains(key));
+        key = new Integer(1001).toString();
+        assertFalse(keySet.contains(key));
+    }
+
+    public void test_SubMapKeySet_size() {
+        assertEquals(9, subMap_default.keySet().size());
+        assertEquals(8, subMap_startExcluded_endExcluded.keySet().size());
+        assertEquals(9, subMap_startExcluded_endIncluded.keySet().size());
+        assertEquals(9, subMap_startIncluded_endExcluded.keySet().size());
+        assertEquals(10, subMap_startIncluded_endIncluded.keySet().size());
+
+        String startKey = new Integer(0).toString();
+        String endKey = new Integer(2).toString();
+        SortedMap subMap = tm.subMap(startKey, endKey);
+        assertEquals(112, subMap.keySet().size());
+
+        startKey = new Integer(0).toString();
+        endKey = startKey;
+        subMap = tm.subMap(startKey, endKey);
+        assertEquals(0, subMap.keySet().size());
+
+        startKey = new Integer(-1).toString();
+        endKey = startKey;
+        subMap = tm.subMap(startKey, endKey);
+        assertEquals(0, subMap.keySet().size());
+
+        endKey = new Integer(1).toString();
+        subMap = tm.subMap(startKey, endKey);
+        assertEquals(1, subMap.keySet().size());
+
+        startKey = new Integer(999).toString();
+        endKey = startKey;
+        subMap = tm.subMap(startKey, endKey);
+        assertEquals(0, subMap.keySet().size());
+    }
+
+    public void test_SubMapKeySet_remove() {
+        Set keySet = subMap_default.keySet();
+        try {
+            keySet.remove(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        int size = keySet.size();
+        for (int i = 0; i < size; i++) {
+            Iterator iterator = keySet.iterator();
+            assertTrue(keySet.remove(iterator.next()));
+        }
+
+        keySet = subMap_startExcluded_endExcluded.keySet();
+        try {
+            keySet.remove(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        size = keySet.size();
+        for (int i = 0; i < size; i++) {
+            Iterator iterator = keySet.iterator();
+            assertTrue(keySet.remove(iterator.next()));
+        }
+
+        keySet = subMap_startExcluded_endIncluded.keySet();
+        try {
+            keySet.remove(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        size = keySet.size();
+        for (int i = 0; i < size; i++) {
+            Iterator iterator = keySet.iterator();
+            assertTrue(keySet.remove(iterator.next()));
+        }
+
+        keySet = subMap_startIncluded_endExcluded.keySet();
+        try {
+            keySet.remove(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        size = keySet.size();
+        for (int i = 0; i < size; i++) {
+            Iterator iterator = keySet.iterator();
+            assertTrue(keySet.remove(iterator.next()));
+        }
+
+        keySet = subMap_startIncluded_endIncluded.keySet();
+        try {
+            keySet.remove(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        size = keySet.size();
+        for (int i = 0; i < size; i++) {
+            Iterator iterator = keySet.iterator();
+            assertTrue(keySet.remove(iterator.next()));
+        }
+    }
+
+    /*
+     * AscendingSubMapEntrySet
+     */
+
+    public void test_AscendingSubMapEntrySet_comparator() {
+        Set entrySet;
+        NavigableSet ascendingSubMapEntrySet;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            assertNull(ascendingSubMapEntrySet.comparator());
+        }
+
+        entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            assertNull(ascendingSubMapEntrySet.comparator());
+        }
+
+        entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            assertNull(ascendingSubMapEntrySet.comparator());
+        }
+
+        entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            assertNull(ascendingSubMapEntrySet.comparator());
+        }
+    }
+
+    public void test_AscendingSubMapEntrySet_descendingSet() {
+        Set entrySet;
+        NavigableSet ascendingSubMapEntrySet, descendingSet;
+        Entry entry;
+        int value;
+        Iterator iterator;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            iterator = descendingSet.iterator();
+            assertTrue(iterator.hasNext());
+            for (value = 108; iterator.hasNext(); value--) {
+                entry = (Entry) iterator.next();
+                assertEquals(value, entry.getValue());
+            }
+            assertEquals(100, value);
+        }
+
+        entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            iterator = descendingSet.iterator();
+            assertTrue(iterator.hasNext());
+            for (value = 109; iterator.hasNext(); value--) {
+                entry = (Entry) iterator.next();
+                assertEquals(value, entry.getValue());
+            }
+            assertEquals(100, value);
+        }
+
+        entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            iterator = descendingSet.iterator();
+            assertTrue(iterator.hasNext());
+            for (value = 108; iterator.hasNext(); value--) {
+                entry = (Entry) iterator.next();
+                assertEquals(value, entry.getValue());
+            }
+            assertEquals(99, value);
+        }
+
+        entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            descendingSet = ascendingSubMapEntrySet.descendingSet();
+            iterator = descendingSet.iterator();
+            assertTrue(iterator.hasNext());
+            for (value = 109; iterator.hasNext(); value--) {
+                entry = (Entry) iterator.next();
+                assertEquals(value, entry.getValue());
+            }
+            assertEquals(99, value);
+        }
+    }
+
+    public void test_AscendingSubMapEntrySet_descendingIterator() {
+        Set entrySet;
+        NavigableSet ascendingSubMapEntrySet;
+        Iterator iterator;
+        Entry entry;
+        int value;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.descendingIterator();
+            assertTrue(iterator.hasNext());
+            for (value = 108; iterator.hasNext(); value--) {
+                entry = (Entry) iterator.next();
+                assertEquals(value, entry.getValue());
+            }
+            assertEquals(100, value);
+        }
+
+        entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.descendingIterator();
+            assertTrue(iterator.hasNext());
+            for (value = 109; iterator.hasNext(); value--) {
+                entry = (Entry) iterator.next();
+                assertEquals(value, entry.getValue());
+            }
+            assertEquals(100, value);
+        }
+
+        entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.descendingIterator();
+            assertTrue(iterator.hasNext());
+            for (value = 108; iterator.hasNext(); value--) {
+                entry = (Entry) iterator.next();
+                assertEquals(value, entry.getValue());
+            }
+            assertEquals(99, value);
+        }
+
+        entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.descendingIterator();
+            assertTrue(iterator.hasNext());
+            for (value = 109; iterator.hasNext(); value--) {
+                entry = (Entry) iterator.next();
+                assertEquals(value, entry.getValue());
+            }
+            assertEquals(99, value);
+        }
+
+        String startKey = new Integer(2).toString();
+        entrySet = tm.headMap(startKey, true).entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.descendingIterator();
+            assertTrue(iterator.hasNext());
+            assertEquals(2, ((Entry) iterator.next()).getValue());
+        }
+    }
+
+    public void test_AscendingSubMapEntrySet_pollFirst_startExcluded_endExcluded() {
+        Set entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            for (int value = 101; value < 109; value++) {
+                Entry entry = (Entry) ascendingSubMapEntrySet.pollFirst();
+                assertEquals(value, entry.getValue());
+            }
+            assertTrue(ascendingSubMapEntrySet.isEmpty());
+            // should return null if the set is empty.
+            assertNull(ascendingSubMapEntrySet.pollFirst());
+        }
+    }
+
+    public void test_AscendingSubMapEntrySet_pollFirst_startExcluded_endIncluded() {
+        Set entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            for (int value = 101; value < 110; value++) {
+                Entry entry = (Entry) ascendingSubMapEntrySet.pollFirst();
+                assertEquals(value, entry.getValue());
+            }
+            assertTrue(ascendingSubMapEntrySet.isEmpty());
+            // should return null if the set is empty.
+            assertNull(ascendingSubMapEntrySet.pollFirst());
+        }
+    }
+
+    public void test_AscendingSubMapEntrySet_pollFirst_startIncluded_endExcluded() {
+        Set entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            for (int value = 100; value < 109; value++) {
+                Entry entry = (Entry) ascendingSubMapEntrySet.pollFirst();
+                assertEquals(value, entry.getValue());
+            }
+            assertTrue(ascendingSubMapEntrySet.isEmpty());
+            // should return null if the set is empty.
+            assertNull(ascendingSubMapEntrySet.pollFirst());
+        }
+    }
+
+    public void test_AscendingSubMapEntrySet_pollFirst_startIncluded_endIncluded() {
+        Set entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            for (int value = 100; value < 110; value++) {
+                Entry entry = (Entry) ascendingSubMapEntrySet.pollFirst();
+                assertEquals(value, entry.getValue());
+            }
+            assertTrue(ascendingSubMapEntrySet.isEmpty());
+            // should return null if the set is empty.
+            assertNull(ascendingSubMapEntrySet.pollFirst());
+        }
+    }
+
+    public void test_AscendingSubMapEntrySet_pollLast_startExcluded_endExcluded() {
+        Set entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            for (int value = 108; value > 100; value--) {
+                Entry entry = (Entry) ascendingSubMapEntrySet.pollLast();
+                assertEquals(value, entry.getValue());
+            }
+            assertTrue(ascendingSubMapEntrySet.isEmpty());
+            // should return null if the set is empty
+            assertNull(ascendingSubMapEntrySet.pollLast());
+        }
+
+        // NavigableMap ascendingSubMap = tm.headMap("2", true);
+        // Set entrySet = ascendingSubMap.entrySet();
+        // Object last;
+        // if (entrySet instanceof NavigableSet) {
+        // last = ((NavigableSet) entrySet).pollLast();
+        // assertEquals("2=2", last.toString());
+        // }
+        //
+        // ascendingSubMap = tm.tailMap("2", true);
+        // entrySet = ascendingSubMap.entrySet();
+        // if (entrySet instanceof NavigableSet) {
+        // last = ((NavigableSet) entrySet).pollLast();
+        // assertEquals("999=999", last.toString());
+        // }
+    }
+
+    public void test_AscendingSubMapEntrySet_pollLast_startExcluded_endIncluded() {
+        Set entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            for (int value = 109; value > 100; value--) {
+                Entry entry = (Entry) ascendingSubMapEntrySet.pollLast();
+                assertEquals(value, entry.getValue());
+            }
+            assertTrue(ascendingSubMapEntrySet.isEmpty());
+            // should return null if the set is empty
+            assertNull(ascendingSubMapEntrySet.pollLast());
+        }
+    }
+
+    public void test_AscendingSubMapEntrySet_pollLast_startIncluded_endExcluded() {
+        Set entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            for (int value = 108; value > 99; value--) {
+                Entry entry = (Entry) ascendingSubMapEntrySet.pollLast();
+                assertEquals(value, entry.getValue());
+            }
+            assertTrue(ascendingSubMapEntrySet.isEmpty());
+            // should return null if the set is empty
+            assertNull(ascendingSubMapEntrySet.pollLast());
+        }
+    }
+
+    public void test_AscendingSubMapEntrySet_pollLast_startIncluded_endIncluded() {
+        Set entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            for (int value = 109; value > 99; value--) {
+                Entry entry = (Entry) ascendingSubMapEntrySet.pollLast();
+                assertEquals(value, entry.getValue());
+            }
+            assertTrue(ascendingSubMapEntrySet.isEmpty());
+            // should return null if the set is empty
+            assertNull(ascendingSubMapEntrySet.pollLast());
+        }
+    }
+
+    public void test_AscendingSubMapEntrySet_headSet() {
+        Set entrySet, headSet;
+        NavigableSet ascendingSubMapEntrySet;
+        Iterator iterator, headSetIterator;
+        Entry entry;
+        int value;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                headSet = ascendingSubMapEntrySet.headSet(entry);
+                headSetIterator = headSet.iterator();
+                for (value = 101; headSetIterator.hasNext(); value++) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(entry.getValue(), value);
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                headSet = ascendingSubMapEntrySet.headSet(entry, false);
+                headSetIterator = headSet.iterator();
+                for (value = 101; headSetIterator.hasNext(); value++) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(entry.getValue(), value);
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                headSet = ascendingSubMapEntrySet.headSet(entry, true);
+                headSetIterator = headSet.iterator();
+                for (value = 101; headSetIterator.hasNext(); value++) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(entry.getValue(), value - 1);
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+            }
+        }
+
+        entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                headSet = ascendingSubMapEntrySet.headSet(entry);
+                headSetIterator = headSet.iterator();
+                for (value = 101; headSetIterator.hasNext(); value++) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(entry.getValue(), value);
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                headSet = ascendingSubMapEntrySet.headSet(entry, false);
+                headSetIterator = headSet.iterator();
+                for (value = 101; headSetIterator.hasNext(); value++) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(entry.getValue(), value);
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                headSet = ascendingSubMapEntrySet.headSet(entry, true);
+                headSetIterator = headSet.iterator();
+                for (value = 101; headSetIterator.hasNext(); value++) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(entry.getValue(), value - 1);
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                headSet = ascendingSubMapEntrySet.headSet(entry);
+                headSetIterator = headSet.iterator();
+                for (value = 100; headSetIterator.hasNext(); value++) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(entry.getValue(), value);
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                headSet = ascendingSubMapEntrySet.headSet(entry, false);
+                headSetIterator = headSet.iterator();
+                for (value = 100; headSetIterator.hasNext(); value++) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(entry.getValue(), value);
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                headSet = ascendingSubMapEntrySet.headSet(entry, true);
+                headSetIterator = headSet.iterator();
+                for (value = 100; headSetIterator.hasNext(); value++) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(entry.getValue(), value - 1);
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                headSet = ascendingSubMapEntrySet.headSet(entry);
+                headSetIterator = headSet.iterator();
+                for (value = 100; headSetIterator.hasNext(); value++) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(entry.getValue(), value);
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                headSet = ascendingSubMapEntrySet.headSet(entry, false);
+                headSetIterator = headSet.iterator();
+                for (value = 100; headSetIterator.hasNext(); value++) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(entry.getValue(), value);
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                headSet = ascendingSubMapEntrySet.headSet(entry, true);
+                headSetIterator = headSet.iterator();
+                for (value = 100; headSetIterator.hasNext(); value++) {
+                    assertEquals(value, ((Entry) headSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(entry.getValue(), value - 1);
+                try {
+                    headSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+            }
+        }
+
+        // NavigableMap ascendingSubMap = tm.headMap("1", true);
+        // entrySet = ascendingSubMap.entrySet();
+        // if (entrySet instanceof SortedSet) {
+        // Iterator it = entrySet.iterator();
+        // it.next();
+        // Object end = it.next();// 1=1
+        // Set headSet = ((NavigableSet) entrySet).headSet(end);// inclusive
+        // // false
+        // assertEquals(1, headSet.size());
+        // }
+    }
+
+    public void test_AscendingSubMapEntrySet_tailSet() {
+        Set entrySet, tailSet;
+        NavigableSet ascendingSubMapEntrySet;
+        Iterator iterator, tailSetIterator;
+        Entry entry;
+        int value;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = entrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                tailSet = ascendingSubMapEntrySet.tailSet(entry);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue() + 1; tailSetIterator
+                        .hasNext(); value++) {
+                    assertEquals(value, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(109, value);
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                tailSet = ascendingSubMapEntrySet.tailSet(entry, false);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue() + 1; tailSetIterator
+                        .hasNext(); value++) {
+                    assertEquals(value, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(109, value);
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                tailSet = ascendingSubMapEntrySet.tailSet(entry, true);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue(); tailSetIterator
+                        .hasNext(); value++) {
+                    assertEquals(value, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(109, value);
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+            }
+        }
+
+        entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = entrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                tailSet = ascendingSubMapEntrySet.tailSet(entry);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue() + 1; tailSetIterator
+                        .hasNext(); value++) {
+                    assertEquals(value, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(110, value);
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                tailSet = ascendingSubMapEntrySet.tailSet(entry, false);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue() + 1; tailSetIterator
+                        .hasNext(); value++) {
+                    assertEquals(value, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(110, value);
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                tailSet = ascendingSubMapEntrySet.tailSet(entry, true);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue(); tailSetIterator
+                        .hasNext(); value++) {
+                    assertEquals(value, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(110, value);
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = entrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                tailSet = ascendingSubMapEntrySet.tailSet(entry);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue() + 1; tailSetIterator
+                        .hasNext(); value++) {
+                    assertEquals(value, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(109, value);
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                tailSet = ascendingSubMapEntrySet.tailSet(entry, false);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue() + 1; tailSetIterator
+                        .hasNext(); value++) {
+                    assertEquals(value, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(109, value);
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                tailSet = ascendingSubMapEntrySet.tailSet(entry, true);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue(); tailSetIterator
+                        .hasNext(); value++) {
+                    assertEquals(value, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(109, value);
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = entrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                tailSet = ascendingSubMapEntrySet.tailSet(entry);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue() + 1; tailSetIterator
+                        .hasNext(); value++) {
+                    assertEquals(value, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(110, value);
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                tailSet = ascendingSubMapEntrySet.tailSet(entry, false);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue() + 1; tailSetIterator
+                        .hasNext(); value++) {
+                    assertEquals(value, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(110, value);
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+
+                tailSet = ascendingSubMapEntrySet.tailSet(entry, true);
+                tailSetIterator = tailSet.iterator();
+                for (value = (Integer) entry.getValue(); tailSetIterator
+                        .hasNext(); value++) {
+                    assertEquals(value, ((Entry) tailSetIterator.next())
+                            .getValue());
+                }
+                assertEquals(110, value);
+                try {
+                    tailSetIterator.next();
+                    fail("should throw NoSuchElementException");
+                } catch (NoSuchElementException e) {
+                    // Expected
+                }
+            }
+        }
+
+        // NavigableMap ascendingSubMap = tm.headMap("1", true);
+        // Set entrySet = ascendingSubMap.entrySet();
+        // if (entrySet instanceof NavigableSet) {
+        // Iterator it = entrySet.iterator();
+        // Object start = it.next();// 0=0
+        // Set tailSet = ((NavigableSet) entrySet).tailSet(start);// default
+        // // inclusive
+        // // false
+        // assertEquals(1, tailSet.size());
+        // }
+    }
+
+    public void test_AscendingSubMapEntrySet_subSet() {
+        Set entrySet, subSet;
+        NavigableSet ascendingSubMapEntrySet;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            Iterator iteratorStart = ascendingSubMapEntrySet.iterator();
+            while (iteratorStart.hasNext()) {
+                Entry startEntry = (Entry) iteratorStart.next();
+                Iterator iteratorEnd = ascendingSubMapEntrySet.iterator();
+                while (iteratorEnd.hasNext()) {
+                    Entry endEntry = (Entry) iteratorEnd.next();
+                    int startIndex = (Integer) startEntry.getValue();
+                    int endIndex = (Integer) endEntry.getValue();
+                    if (startIndex > endIndex) {
+                        try {
+                            ascendingSubMapEntrySet
+                                    .subSet(startEntry, endEntry);
+                            fail("should throw IllegalArgumentException");
+                        } catch (IllegalArgumentException e) {
+                            // Expected
+                        }
+
+                        try {
+                            ascendingSubMapEntrySet.subSet(startEntry, false,
+                                    endEntry, false);
+                            fail("should throw IllegalArgumentException");
+                        } catch (IllegalArgumentException e) {
+                            // Expected
+                        }
+
+                        try {
+                            ascendingSubMapEntrySet.subSet(startEntry, false,
+                                    endEntry, true);
+                            fail("should throw IllegalArgumentException");
+                        } catch (IllegalArgumentException e) {
+                            // Expected
+                        }
+
+                        try {
+                            ascendingSubMapEntrySet.subSet(startEntry, true,
+                                    endEntry, false);
+                            fail("should throw IllegalArgumentException");
+                        } catch (IllegalArgumentException e) {
+                            // Expected
+                        }
+
+                        try {
+                            ascendingSubMapEntrySet.subSet(startEntry, true,
+                                    endEntry, true);
+                            fail("should throw IllegalArgumentException");
+                        } catch (IllegalArgumentException e) {
+                            // Expected
+                        }
+                    } else {
+                        subSet = ascendingSubMapEntrySet.subSet(startEntry,
+                                endEntry);
+                        Iterator subSetIterator = subSet.iterator();
+                        for (int index = startIndex + 1; subSetIterator
+                                .hasNext(); index++) {
+                            assertEquals(index, ((Entry) subSetIterator.next())
+                                    .getValue());
+                        }
+
+                        subSet = ascendingSubMapEntrySet.subSet(startEntry,
+                                false, endEntry, false);
+                        subSetIterator = subSet.iterator();
+                        for (int index = startIndex + 1; subSetIterator
+                                .hasNext(); index++) {
+                            assertEquals(index, ((Entry) subSetIterator.next())
+                                    .getValue());
+                        }
+
+                        subSet = ascendingSubMapEntrySet.subSet(startEntry,
+                                false, endEntry, true);
+                        subSetIterator = subSet.iterator();
+                        for (int index = startIndex + 1; subSetIterator
+                                .hasNext(); index++) {
+                            assertEquals(index, ((Entry) subSetIterator.next())
+                                    .getValue());
+                        }
+
+                        subSet = ascendingSubMapEntrySet.subSet(startEntry,
+                                true, endEntry, false);
+                        subSetIterator = subSet.iterator();
+                        for (int index = startIndex; subSetIterator.hasNext(); index++) {
+                            assertEquals(index, ((Entry) subSetIterator.next())
+                                    .getValue());
+                        }
+
+                        subSet = ascendingSubMapEntrySet.subSet(startEntry,
+                                true, endEntry, true);
+                        subSetIterator = subSet.iterator();
+                        for (int index = startIndex; subSetIterator.hasNext(); index++) {
+                            assertEquals(index, ((Entry) subSetIterator.next())
+                                    .getValue());
+                        }
+                    }
+                }
+            }
+        }
+
+        String endKey = new Integer(2).toString();
+        entrySet = tm.headMap(endKey, true).entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            Iterator iterator = entrySet.iterator();
+            Object startEntry = iterator.next();
+            iterator.next();
+            Object endEntry = iterator.next();
+            subSet = ascendingSubMapEntrySet.subSet(startEntry, endEntry);
+            assertEquals(1, subSet.size());
+
+            subSet = ascendingSubMapEntrySet.subSet(startEntry, false,
+                    endEntry, false);
+            assertEquals(1, subSet.size());
+
+            subSet = ascendingSubMapEntrySet.subSet(startEntry, false,
+                    endEntry, true);
+            assertEquals(2, subSet.size());
+
+            subSet = ascendingSubMapEntrySet.subSet(startEntry, true, endEntry,
+                    false);
+            assertEquals(2, subSet.size());
+
+            subSet = ascendingSubMapEntrySet.subSet(startEntry, true, endEntry,
+                    true);
+            assertEquals(3, subSet.size());
+        }
+    }
+
+    public void test_AscendingSubMapEntrySet_lower() {
+        Set entrySet;
+        NavigableSet ascendingSubMapEntrySet;
+        Iterator iterator;
+        Entry entry, lowerEntry;
+        int value;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry);
+                value = (Integer) entry.getValue();
+                if (value > 101) {
+                    assertEquals(value - 1, lowerEntry.getValue());
+                } else {
+                    assertNull(lowerEntry);
+                }
+            }
+        }
+
+        entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry);
+                value = (Integer) entry.getValue();
+                if (value > 101) {
+                    assertEquals(value - 1, lowerEntry.getValue());
+                } else {
+                    assertNull(lowerEntry);
+                }
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry);
+                value = (Integer) entry.getValue();
+                if (value > 100) {
+                    assertEquals(value - 1, lowerEntry.getValue());
+                } else {
+                    assertNull(lowerEntry);
+                }
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry);
+                value = (Integer) entry.getValue();
+                if (value > 100) {
+                    assertEquals(value - 1, lowerEntry.getValue());
+                } else {
+                    assertNull(lowerEntry);
+                }
+            }
+        }
+
+        String endKey = new Integer(2).toString();
+        entrySet = tm.headMap(endKey, true).entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = entrySet.iterator();
+            Entry expectedEntry = (Entry) iterator.next();
+            entry = (Entry) iterator.next();
+            assertEquals(expectedEntry, ascendingSubMapEntrySet.lower(entry));
+        }
+
+        // With Comparator
+
+        entrySet = subMap_startExcluded_endExcluded_comparator.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry);
+                value = (Integer) entry.getValue();
+                if (value > 101) {
+                    assertEquals(value - 1, lowerEntry.getValue());
+                } else {
+                    assertNull(lowerEntry);
+                }
+            }
+        }
+
+        entrySet = subMap_startExcluded_endIncluded_comparator.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry);
+                value = (Integer) entry.getValue();
+                if (value > 101) {
+                    assertEquals(value - 1, lowerEntry.getValue());
+                } else {
+                    assertNull(lowerEntry);
+                }
+            }
+        }
+
+        entrySet = subMap_startIncluded_endExcluded_comparator.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry);
+                value = (Integer) entry.getValue();
+                if (value > 100) {
+                    assertEquals(value - 1, lowerEntry.getValue());
+                } else {
+                    assertNull(lowerEntry);
+                }
+            }
+        }
+
+        entrySet = subMap_startIncluded_endIncluded_comparator.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry);
+                value = (Integer) entry.getValue();
+                if (value > 100) {
+                    assertEquals(value - 1, lowerEntry.getValue());
+                } else {
+                    assertNull(lowerEntry);
+                }
+            }
+        }
+    }
+
+    public void test_AscendingSubMapEntrySet_higher() {
+        Set entrySet;
+        NavigableSet ascendingSubMapEntrySet;
+        Iterator iterator;
+        Entry entry, lowerEntry;
+        int value;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry);
+                value = (Integer) entry.getValue();
+                if (value < 108) {
+                    assertEquals(value + 1, lowerEntry.getValue());
+                } else {
+                    assertNull(lowerEntry);
+                }
+            }
+        }
+
+        entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry);
+                value = (Integer) entry.getValue();
+                if (value < 109) {
+                    assertEquals(value + 1, lowerEntry.getValue());
+                } else {
+                    assertNull(lowerEntry);
+                }
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry);
+                value = (Integer) entry.getValue();
+                if (value < 108) {
+                    assertEquals(value + 1, lowerEntry.getValue());
+                } else {
+                    assertNull(lowerEntry);
+                }
+            }
+        }
+
+        entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry);
+                value = (Integer) entry.getValue();
+                if (value < 109) {
+                    assertEquals(value + 1, lowerEntry.getValue());
+                } else {
+                    assertNull(lowerEntry);
+                }
+            }
+        }
+
+        String endKey = new Integer(2).toString();
+        entrySet = tm.headMap(endKey, true).entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = entrySet.iterator();
+            entry = (Entry) iterator.next();
+            Entry expectedEntry = (Entry) iterator.next();
+            assertEquals(expectedEntry, ascendingSubMapEntrySet.higher(entry));
+        }
+
+        // With Comparator
+        entrySet = subMap_startExcluded_endExcluded_comparator.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry);
+                value = (Integer) entry.getValue();
+                if (value < 108) {
+                    assertEquals(value + 1, lowerEntry.getValue());
+                } else {
+                    assertNull(lowerEntry);
+                }
+            }
+        }
+
+        entrySet = subMap_startExcluded_endIncluded_comparator.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry);
+                value = (Integer) entry.getValue();
+                if (value < 109) {
+                    assertEquals(value + 1, lowerEntry.getValue());
+                } else {
+                    assertNull(lowerEntry);
+                }
+            }
+        }
+
+        entrySet = subMap_startIncluded_endExcluded_comparator.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry);
+                value = (Integer) entry.getValue();
+                if (value < 108) {
+                    assertEquals(value + 1, lowerEntry.getValue());
+                } else {
+                    assertNull(lowerEntry);
+                }
+            }
+        }
+
+        entrySet = subMap_startIncluded_endIncluded_comparator.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry);
+                value = (Integer) entry.getValue();
+                if (value < 109) {
+                    assertEquals(value + 1, lowerEntry.getValue());
+                } else {
+                    assertNull(lowerEntry);
+                }
+            }
+        }
+    }
+
+    public void test_AscendingSubMapEntrySet_ceiling() {
+        Set entrySet;
+        NavigableSet ascendingSubMapEntrySet;
+        Iterator iterator;
+
+        Set entrySet_beyondBound;
+        Iterator iterator_beyondBound;
+        Entry beyondBoundEntry;
+
+        Entry entry, lowerEntry;
+        int value = 0;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            try {
+                ascendingSubMapEntrySet.ceiling(null);
+                fail("should throw NullPointerException");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry);
+                value = (Integer) entry.getValue();
+                assertEquals(value, lowerEntry.getValue());
+            }
+            assertEquals(108, value);
+
+        }
+
+        entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            try {
+                ascendingSubMapEntrySet.ceiling(null);
+                fail("should throw NullPointerException");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry);
+                value = (Integer) entry.getValue();
+                assertEquals(value, lowerEntry.getValue());
+            }
+            assertEquals(109, value);
+        }
+
+        entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            try {
+                ascendingSubMapEntrySet.ceiling(null);
+                fail("should throw NullPointerException");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry);
+                value = (Integer) entry.getValue();
+                assertEquals(value, lowerEntry.getValue());
+            }
+            assertEquals(108, value);
+        }
+
+        entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            try {
+                ascendingSubMapEntrySet.ceiling(null);
+                fail("should throw NullPointerException");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry);
+                value = (Integer) entry.getValue();
+                assertEquals(value, lowerEntry.getValue());
+            }
+            assertEquals(109, value);
+        }
+
+        // With Comparator
+        entrySet = subMap_startIncluded_endIncluded_comparator.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            try {
+                ascendingSubMapEntrySet.ceiling(null);
+                fail("should throw NullPointerException");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry);
+                value = (Integer) entry.getValue();
+                assertEquals(value, lowerEntry.getValue());
+            }
+            assertEquals(109, value);
+        }
+
+        entrySet = subMap_startIncluded_endExcluded_comparator.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            try {
+                ascendingSubMapEntrySet.ceiling(null);
+                fail("should throw NullPointerException");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry);
+                value = (Integer) entry.getValue();
+                assertEquals(value, lowerEntry.getValue());
+            }
+            assertEquals(108, value);
+        }
+
+        entrySet = subMap_startExcluded_endIncluded_comparator.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            try {
+                ascendingSubMapEntrySet.ceiling(null);
+                fail("should throw NullPointerException");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry);
+                value = (Integer) entry.getValue();
+                assertEquals(value, lowerEntry.getValue());
+            }
+            assertEquals(109, value);
+        }
+
+        entrySet = subMap_startExcluded_endExcluded_comparator.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            try {
+                ascendingSubMapEntrySet.ceiling(null);
+                fail("should throw NullPointerException");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            iterator = ascendingSubMapEntrySet.iterator();
+            while (iterator.hasNext()) {
+                entry = (Entry) iterator.next();
+                lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry);
+                value = (Integer) entry.getValue();
+                assertEquals(value, lowerEntry.getValue());
+            }
+            assertEquals(108, value);
+        }
+    }
+
+    public void test_AscendingSubMapEntrySet_floor() {
+        Set entrySet;
+        NavigableSet ascendingSubMapEntrySet;
+        Iterator iterator;
+        Entry entry, floorEntry;
+        int value;
+
+        entrySet = navigableMap_startExcluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            try {
+                ascendingSubMapEntrySet.floor(null);
+                fail("should throw NullPointerException");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            iterator = ascendingSubMapEntrySet.iterator();
+            for (int i = 101; i < 109; i++) {
+                entry = (Entry) iterator.next();
+                floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry);
+                assertEquals(entry.getValue(), floorEntry.getValue());
+            }
+            assertFalse(iterator.hasNext());
+        }
+
+        entrySet = navigableMap_startExcluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            try {
+                ascendingSubMapEntrySet.floor(null);
+                fail("should throw NullPointerException");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            iterator = ascendingSubMapEntrySet.iterator();
+            for (int i = 101; i < 110; i++) {
+                entry = (Entry) iterator.next();
+                floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry);
+                assertEquals(entry.getValue(), floorEntry.getValue());
+            }
+            assertFalse(iterator.hasNext());
+        }
+
+        entrySet = navigableMap_startIncluded_endExcluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            try {
+                ascendingSubMapEntrySet.floor(null);
+                fail("should throw NullPointerException");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            iterator = ascendingSubMapEntrySet.iterator();
+            for (int i = 100; i < 109; i++) {
+                entry = (Entry) iterator.next();
+                floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry);
+                assertEquals(entry.getValue(), floorEntry.getValue());
+            }
+            assertFalse(iterator.hasNext());
+        }
+
+        entrySet = navigableMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            try {
+                ascendingSubMapEntrySet.floor(null);
+                fail("should throw NullPointerException");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            iterator = ascendingSubMapEntrySet.iterator();
+            for (int i = 100; i < 110; i++) {
+                entry = (Entry) iterator.next();
+                floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry);
+                assertEquals(entry.getValue(), floorEntry.getValue());
+            }
+            assertFalse(iterator.hasNext());
+        }
+
+        // With Comparator
+        entrySet = subMap_startExcluded_endExcluded_comparator.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            try {
+                ascendingSubMapEntrySet.floor(null);
+                fail("should throw NullPointerException");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            iterator = ascendingSubMapEntrySet.iterator();
+            for (int i = 101; i < 109; i++) {
+                entry = (Entry) iterator.next();
+                floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry);
+                assertEquals(entry.getValue(), floorEntry.getValue());
+            }
+            assertFalse(iterator.hasNext());
+        }
+
+        entrySet = subMap_startExcluded_endIncluded_comparator.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            try {
+                ascendingSubMapEntrySet.floor(null);
+                fail("should throw NullPointerException");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            iterator = ascendingSubMapEntrySet.iterator();
+            for (int i = 101; i < 110; i++) {
+                entry = (Entry) iterator.next();
+                floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry);
+                assertEquals(entry.getValue(), floorEntry.getValue());
+            }
+            assertFalse(iterator.hasNext());
+        }
+
+        entrySet = subMap_startIncluded_endExcluded_comparator.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            try {
+                ascendingSubMapEntrySet.floor(null);
+                fail("should throw NullPointerException");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            iterator = ascendingSubMapEntrySet.iterator();
+            for (int i = 100; i < 109; i++) {
+                entry = (Entry) iterator.next();
+                floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry);
+                assertEquals(entry.getValue(), floorEntry.getValue());
+            }
+            assertFalse(iterator.hasNext());
+        }
+
+        entrySet = subMap_startIncluded_endIncluded.entrySet();
+        if (entrySet instanceof NavigableSet) {
+            ascendingSubMapEntrySet = (NavigableSet) entrySet;
+            try {
+                ascendingSubMapEntrySet.floor(null);
+                fail("should throw NullPointerException");
+            } catch (NullPointerException e) {
+                // Expected
+            }
+
+            iterator = ascendingSubMapEntrySet.iterator();
+            for (int i = 100; i < 110; i++) {
+                entry = (Entry) iterator.next();
+                floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry);
+                assertEquals(entry.getValue(), floorEntry.getValue());
+            }
+            assertFalse(iterator.hasNext());
+        }
+    }
+
+    @Override
+    protected void setUp() {
+        tm = new TreeMap();
+        tm_comparator = new TreeMap(new MockComparator());
+        for (int i = 0; i < objArray.length; i++) {
+            Object x = objArray[i] = new Integer(i);
+            tm.put(x.toString(), x);
+            tm_comparator.put(x.toString(), x);
+        }
+
+        subMap_default = tm.subMap(objArray[100].toString(), objArray[109]
+                .toString());
+        subMap_startExcluded_endExcluded = tm.subMap(objArray[100].toString(),
+                false, objArray[109].toString(), false);
+        subMap_startExcluded_endIncluded = tm.subMap(objArray[100].toString(),
+                false, objArray[109].toString(), true);
+        subMap_startIncluded_endExcluded = tm.subMap(objArray[100].toString(),
+                true, objArray[109].toString(), false);
+        subMap_startIncluded_endIncluded = tm.subMap(objArray[100].toString(),
+                true, objArray[109].toString(), true);
+
+        subMap_default_beforeStart_100 = tm.subMap(objArray[0].toString(),
+                objArray[1].toString());
+
+        subMap_default_afterEnd_109 = tm.subMap(objArray[110].toString(),
+                objArray[119].toString());
+
+        assertTrue(subMap_startExcluded_endExcluded instanceof NavigableMap);
+        assertTrue(subMap_startExcluded_endIncluded instanceof NavigableMap);
+        assertTrue(subMap_startIncluded_endExcluded instanceof NavigableMap);
+        assertTrue(subMap_startIncluded_endIncluded instanceof NavigableMap);
+
+        navigableMap_startExcluded_endExcluded = (NavigableMap) subMap_startExcluded_endExcluded;
+        navigableMap_startExcluded_endIncluded = (NavigableMap) subMap_startExcluded_endIncluded;
+        navigableMap_startIncluded_endExcluded = (NavigableMap) subMap_startIncluded_endExcluded;
+        navigableMap_startIncluded_endIncluded = (NavigableMap) subMap_startIncluded_endIncluded;
+
+        subMap_default_comparator = tm_comparator.subMap(objArray[100]
+                .toString(), objArray[109].toString());
+        subMap_startExcluded_endExcluded_comparator = tm_comparator.subMap(
+                objArray[100].toString(), false, objArray[109].toString(),
+                false);
+
+        subMap_startExcluded_endIncluded_comparator = tm_comparator
+                .subMap(objArray[100].toString(), false, objArray[109]
+                        .toString(), true);
+        subMap_startIncluded_endExcluded_comparator = tm_comparator
+                .subMap(objArray[100].toString(), true, objArray[109]
+                        .toString(), false);
+        subMap_startIncluded_endIncluded_comparator = tm_comparator.subMap(
+                objArray[100].toString(), true, objArray[109].toString(), true);
+    }
+
+    @Override
+    protected void tearDown() {
+        tm = null;
+        tm_comparator = null;
+
+        subMap_default = null;
+        subMap_startExcluded_endExcluded = null;
+        subMap_startExcluded_endIncluded = null;
+        subMap_startIncluded_endExcluded = null;
+        subMap_startIncluded_endIncluded = null;
+
+        subMap_default_beforeStart_100 = null;
+        subMap_default_afterEnd_109 = null;
+
+        subMap_default_comparator = null;
+        subMap_startExcluded_endExcluded_comparator = null;
+        subMap_startExcluded_endIncluded_comparator = null;
+        subMap_startIncluded_endExcluded_comparator = null;
+        subMap_startIncluded_endIncluded_comparator = null;
+    }
+
+    public void test_lower_null() throws Exception {
+        NavigableMap map = tm.subMap(objArray[100].toString(), true,
+                objArray[100].toString(), false);
+        assertNull(map.ceilingKey(objArray[100].toString()));
+        assertNull(map.floorKey(objArray[100].toString()));
+        assertNull(map.lowerKey(objArray[100].toString()));
+        assertNull(map.higherKey(objArray[100].toString()));
+        assertNull(map.ceilingKey(objArray[111].toString()));
+        assertNull(map.floorKey(objArray[111].toString()));
+        assertNull(map.lowerKey(objArray[111].toString()));
+        assertNull(map.higherKey(objArray[111].toString()));
+        assertNull(map.ceilingKey(objArray[1].toString()));
+        assertNull(map.floorKey(objArray[1].toString()));
+        assertNull(map.lowerKey(objArray[1].toString()));
+        assertNull(map.higherKey(objArray[1].toString()));
+        map = map.descendingMap();
+        assertNull(map.ceilingKey(objArray[100].toString()));
+        assertNull(map.floorKey(objArray[100].toString()));
+        assertNull(map.lowerKey(objArray[100].toString()));
+        assertNull(map.higherKey(objArray[100].toString()));
+        assertNull(map.ceilingKey(objArray[111].toString()));
+        assertNull(map.floorKey(objArray[111].toString()));
+        assertNull(map.lowerKey(objArray[111].toString()));
+        assertNull(map.higherKey(objArray[111].toString()));
+        assertNull(map.ceilingKey(objArray[1].toString()));
+        assertNull(map.floorKey(objArray[1].toString()));
+        assertNull(map.lowerKey(objArray[1].toString()));
+        assertNull(map.higherKey(objArray[1].toString()));
+    }
+
+    public void test_lower_tail() throws Exception {
+        NavigableMap map = tm.subMap(objArray[102].toString(), true,
+                objArray[103].toString(), false);
+        assertTrue(map.containsKey(objArray[102].toString()));
+        assertFalse(map.containsKey(objArray[101].toString()));
+        assertFalse(map.containsKey(objArray[103].toString()));
+        assertFalse(map.containsKey(objArray[104].toString()));
+        map = map.descendingMap();
+        assertTrue(map.containsKey(objArray[102].toString()));
+        assertFalse(map.containsKey(objArray[101].toString()));
+        assertFalse(map.containsKey(objArray[103].toString()));
+        assertFalse(map.containsKey(objArray[104].toString()));
+        map = tm.subMap(objArray[102].toString(), true, objArray[102]
+                .toString(), false);
+        assertFalse(map.containsKey(objArray[102].toString()));
+        assertFalse(map.containsKey(objArray[101].toString()));
+        assertFalse(map.containsKey(objArray[103].toString()));
+        assertFalse(map.containsKey(objArray[104].toString()));
+        map = map.descendingMap();
+        assertFalse(map.containsKey(objArray[102].toString()));
+        assertFalse(map.containsKey(objArray[101].toString()));
+        assertFalse(map.containsKey(objArray[103].toString()));
+        assertFalse(map.containsKey(objArray[104].toString()));
+    }
+
+    public void test_contains_null() throws Exception {
+        NavigableMap map = tm.subMap(objArray[100].toString(), true,
+                objArray[100].toString(), false);
+        assertFalse(map.containsKey(objArray[100].toString()));
+        assertFalse(map.containsKey(objArray[10].toString()));
+        assertFalse(map.containsKey(objArray[101].toString()));
+        assertFalse(map.containsKey(objArray[102].toString()));
+        assertFalse(map.containsKey(objArray[1].toString()));
+        map = map.descendingMap();
+        assertFalse(map.containsKey(objArray[100].toString()));
+        assertFalse(map.containsKey(objArray[10].toString()));
+        assertFalse(map.containsKey(objArray[101].toString()));
+        assertFalse(map.containsKey(objArray[102].toString()));
+        assertFalse(map.containsKey(objArray[1].toString()));
+    }
+
+    public void test_contains() throws Exception {
+        NavigableMap map = tm.subMap(objArray[102].toString(), true,
+                objArray[103].toString(), false);
+        assertFalse(map.containsKey(objArray[100].toString()));
+        assertFalse(map.containsKey(objArray[104].toString()));
+        assertFalse(map.containsKey(objArray[101].toString()));
+        assertTrue(map.containsKey(objArray[102].toString()));
+        map = map.descendingMap();
+        assertFalse(map.containsKey(objArray[100].toString()));
+        assertFalse(map.containsKey(objArray[104].toString()));
+        assertFalse(map.containsKey(objArray[101].toString()));
+        assertTrue(map.containsKey(objArray[102].toString()));
+    }
+
+    public void test_size() throws Exception {
+        NavigableMap map = tm.subMap(objArray[102].toString(), true,
+                objArray[103].toString(), false);
+        assertEquals(0, map.headMap(objArray[102].toString(), false).size());
+        assertEquals(1, map.headMap(objArray[102].toString(), true).size());
+        try {
+            assertEquals(1, map.headMap(objArray[103].toString(), true).size());
+            fail("should throw IAE");
+        } catch (IllegalArgumentException e) {
+        }
+        assertEquals(1, map.headMap(objArray[103].toString(), false).size());
+        assertEquals(1, map.tailMap(objArray[102].toString(), true).size());
+        assertEquals(0, map.tailMap(objArray[102].toString(), false).size());
+        assertTrue(map.headMap(objArray[103].toString(), false).containsKey(
+                objArray[102].toString()));
+        try {
+            assertTrue(map.headMap(objArray[103].toString(), true).containsKey(
+                    objArray[102].toString()));
+            fail("should throw IAE");
+        } catch (IllegalArgumentException e) {
+        }
+        assertFalse(map.headMap(objArray[102].toString(), false).containsKey(
+                objArray[102].toString()));
+        assertTrue(map.headMap(objArray[102].toString(), true).containsKey(
+                objArray[102].toString()));
+        assertTrue(map.tailMap(objArray[102].toString(), true).containsKey(
+                objArray[102].toString()));
+        assertFalse(map.tailMap(objArray[102].toString(), true).containsKey(
+                objArray[103].toString()));
+        try {
+            assertEquals(0, map.tailMap(objArray[101].toString()).size());
+            fail("should throw IAE");
+        } catch (IllegalArgumentException e) {
+        }
+        map = map.descendingMap();
+        try {
+            map = map.subMap(objArray[103].toString(), true, objArray[102]
+                    .toString(), true);
+            fail("should throw IAE");
+        } catch (IllegalArgumentException e) {
+        }
+        map = map.subMap(objArray[102].toString(), true, objArray[102]
+                .toString(), true);
+        assertEquals(1, map.headMap(objArray[102].toString(), true).size());
+        assertEquals(0, map.headMap(objArray[102].toString(), false).size());
+        try {
+            assertEquals(0, map.headMap(objArray[103].toString(), true).size());
+            fail("should throw IAE");
+        } catch (IllegalArgumentException e) {
+        }
+
+        assertEquals(1, map.tailMap(objArray[102].toString(), true).size());
+        try {
+            assertFalse(map.headMap(objArray[103].toString(), true)
+                    .containsKey(objArray[102].toString()));
+            fail("should throw IAE");
+        } catch (IllegalArgumentException e) {
+        }
+        assertTrue(map.headMap(objArray[102].toString(), true).containsKey(
+                objArray[102].toString()));
+        assertFalse(map.headMap(objArray[102].toString(), false).containsKey(
+                objArray[102].toString()));
+        assertTrue(map.tailMap(objArray[102].toString(), true).containsKey(
+                objArray[102].toString()));
+        assertFalse(map.tailMap(objArray[102].toString(), true).containsKey(
+                objArray[103].toString()));
+        try {
+            assertEquals(0, map.tailMap(objArray[101].toString()).size());
+            fail("should throw IAE");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public void test_lower() throws Exception {
+        NavigableMap map = tm.subMap(objArray[102].toString(), true,
+                objArray[103].toString(), false);
+        assertEquals(objArray[102].toString(), map.higherKey(objArray[101]
+                .toString()));
+        assertEquals(null, map.higherKey(objArray[102].toString()));
+        assertEquals(null, map.higherKey(objArray[103].toString()));
+        assertEquals(null, map.higherKey(objArray[104].toString()));
+        assertEquals(objArray[102].toString(), map.ceilingKey(objArray[101]
+                .toString()));
+        assertEquals(objArray[102].toString(), map.ceilingKey(objArray[102]
+                .toString()));
+        assertEquals(null, map.ceilingKey(objArray[103].toString()));
+        assertEquals(null, map.ceilingKey(objArray[104].toString()));
+        assertEquals(null, map.lowerKey(objArray[101].toString()));
+        assertEquals(null, map.lowerKey(objArray[102].toString()));
+        assertEquals(objArray[102].toString(), map.lowerKey(objArray[103]
+                .toString()));
+        assertEquals(objArray[102].toString(), map.lowerKey(objArray[104]
+                .toString()));
+        assertEquals(null, map.floorKey(objArray[101].toString()));
+        assertEquals(objArray[102].toString(), map.floorKey(objArray[102]
+                .toString()));
+        assertEquals(objArray[102].toString(), map.floorKey(objArray[103]
+                .toString()));
+        assertEquals(objArray[102].toString(), map.floorKey(objArray[104]
+                .toString()));
+        map = map.descendingMap();
+        assertEquals(null, map.higherKey(objArray[101].toString()));
+        assertEquals(null, map.higherKey(objArray[102].toString()));
+        assertEquals(objArray[102].toString(), map.higherKey(objArray[103]
+                .toString()));
+        assertEquals(objArray[102].toString(), map.higherKey(objArray[104]
+                .toString()));
+        assertEquals(null, map.ceilingKey(objArray[101].toString()));
+        assertEquals(objArray[102].toString(), map.ceilingKey(objArray[102]
+                .toString()));
+        assertEquals(objArray[102].toString(), map.ceilingKey(objArray[103]
+                .toString()));
+        assertEquals(objArray[102].toString(), map.ceilingKey(objArray[104]
+                .toString()));
+        assertEquals(objArray[102].toString(), map.lowerKey(objArray[101]
+                .toString()));
+        assertEquals(null, map.lowerKey(objArray[102].toString()));
+        assertEquals(null, map.lowerKey(objArray[103].toString()));
+        assertEquals(null, map.lowerKey(objArray[104].toString()));
+        assertEquals(objArray[102].toString(), map.floorKey(objArray[101]
+                .toString()));
+        assertEquals(objArray[102].toString(), map.floorKey(objArray[102]
+                .toString()));
+        assertEquals(null, map.floorKey(objArray[103].toString()));
+        assertEquals(null, map.floorKey(objArray[104].toString()));
+    }
+
+    public void test_lowerkey() throws Exception {
+        try {
+            tm.subMap(objArray[100].toString(), true, objArray[100].toString(),
+                    false).descendingMap().firstKey();
+            fail("should throw NoSuchElementException");
+        } catch (Exception e) {
+            // expected
+        }
+        try {
+            tm.subMap(objArray[100].toString(), true, objArray[100].toString(),
+                    false).descendingMap().lastKey();
+            fail("should throw NoSuchElementException");
+        } catch (Exception e) {
+            // expected
+        }
+        try {
+            tm.subMap(objArray[100].toString(), true, objArray[100].toString(),
+                    false).firstKey();
+            fail("should throw NoSuchElementException");
+        } catch (Exception e) {
+            // expected
+        }
+        try {
+            tm.subMap(objArray[100].toString(), true, objArray[100].toString(),
+                    false).lastKey();
+            fail("should throw NoSuchElementException");
+        } catch (Exception e) {
+            // expected
+        }
+
+    }
+
+    public void test_headMap() throws Exception {
+        TreeMap tree = new TreeMap();
+        tree.put(new Integer(0), null);
+        tree.put(new Integer(1), null);
+        Map submap = tree.subMap(tree.firstKey(), tree.lastKey());
+        tree.remove(tree.lastKey());
+        assertEquals(submap, tree);
+    }
+
+    public void testname() throws Exception {
+        TreeMap nullTree = new TreeMap(new Comparator() {
+            public int compare(Object o1, Object o2) {
+                if (o1 == null) {
+                    return o2 == null ? 0 : -1;
+                }
+                return ((String) o1).compareTo((String) o2);
+            }
+        });
+        nullTree.put(new String("One"), 1);
+        nullTree.put(new String("Two"), 2);
+        nullTree.put(new String("Three"), 3);
+        nullTree.put(new String("Four"), 4);
+        nullTree.put(null, 0);
+        nullTree.subMap(null, "two").size();
+    }
+
+}
diff --git a/luni/src/test/java/tests/api/java/util/TreeMapRndTest.java b/luni/src/test/java/tests/api/java/util/TreeMapRndTest.java
new file mode 100644
index 0000000..7c57689
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/TreeMapRndTest.java
@@ -0,0 +1,28 @@
+/*
+ *  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.util;
+
+import java.util.TreeMap;
+
+public class TreeMapRndTest extends SortedMapTestBase {
+    protected void setUp() throws Exception {
+        ref = new RefSortedMap<Integer, Integer>();
+        super.setUp();
+        map = new TreeMap<Integer, Integer>(ref);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/TreeMapTest.java b/luni/src/test/java/tests/api/java/util/TreeMapTest.java
new file mode 100644
index 0000000..4e4ead4
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/TreeMapTest.java
@@ -0,0 +1,2043 @@
+/*
+ *  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.util;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.text.CollationKey;
+import java.text.Collator;
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.NavigableSet;
+import java.util.NoSuchElementException;
+import java.util.Random;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.Map.Entry;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+import tests.support.Support_MapTest2;
+import tests.support.Support_UnmodifiableCollectionTest;
+
+public class TreeMapTest extends junit.framework.TestCase {
+
+    public static class ReversedComparator implements Comparator {
+        public int compare(Object o1, Object o2) {
+            return -(((Comparable) o1).compareTo(o2));
+        }
+
+        public boolean equals(Object o1, Object o2) {
+            return (((Comparable) o1).compareTo(o2)) == 0;
+        }
+    }
+
+    // Regression for Harmony-1026
+    public static class MockComparator<T extends Comparable<T>> implements
+            Comparator<T>, Serializable {
+
+        public int compare(T o1, T o2) {
+            if (o1 == o2) {
+                return 0;
+            }
+            if (null == o1 || null == o2) {
+                return -1;
+            }
+            T c1 = o1;
+            T c2 = o2;
+            return c1.compareTo(c2);
+        }
+    }
+
+    // Regression for Harmony-1161
+    class MockComparatorNullTolerable implements Comparator<String> {
+
+        public int compare(String o1, String o2) {
+            if (o1 == o2) {
+                return 0;
+            }
+            if (null == o1) {
+                return -1;
+            }
+            if (null == o2) { // comparator should be symmetric
+                return 1;
+            }
+            return o1.compareTo(o2);
+        }
+    }
+
+    TreeMap tm;
+
+    Object objArray[] = new Object[1000];
+
+    /**
+     * java.util.TreeMap#TreeMap()
+     */
+    public void test_Constructor() {
+        // Test for method java.util.TreeMap()
+        new Support_MapTest2(new TreeMap()).runTest();
+
+        assertTrue("New treeMap non-empty", new TreeMap().isEmpty());
+    }
+
+    /**
+     * java.util.TreeMap#TreeMap(java.util.Comparator)
+     */
+    public void test_ConstructorLjava_util_Comparator() {
+        // Test for method java.util.TreeMap(java.util.Comparator)
+        Comparator comp = new ReversedComparator();
+        TreeMap reversedTreeMap = new TreeMap(comp);
+        assertTrue("TreeMap answered incorrect comparator", reversedTreeMap
+                .comparator() == comp);
+        reversedTreeMap.put(new Integer(1).toString(), new Integer(1));
+        reversedTreeMap.put(new Integer(2).toString(), new Integer(2));
+        assertTrue("TreeMap does not use comparator (firstKey was incorrect)",
+                reversedTreeMap.firstKey().equals(new Integer(2).toString()));
+        assertTrue("TreeMap does not use comparator (lastKey was incorrect)",
+                reversedTreeMap.lastKey().equals(new Integer(1).toString()));
+
+    }
+
+    /**
+     * java.util.TreeMap#TreeMap(java.util.Map)
+     */
+    public void test_ConstructorLjava_util_Map() {
+        // Test for method java.util.TreeMap(java.util.Map)
+        TreeMap myTreeMap = new TreeMap(new HashMap(tm));
+        assertTrue("Map is incorrect size", myTreeMap.size() == objArray.length);
+        for (Object element : objArray) {
+            assertTrue("Map has incorrect mappings", myTreeMap.get(
+                    element.toString()).equals(element));
+        }
+    }
+
+    /**
+     * java.util.TreeMap#TreeMap(java.util.SortedMap)
+     */
+    public void test_ConstructorLjava_util_SortedMap() {
+        // Test for method java.util.TreeMap(java.util.SortedMap)
+        Comparator comp = new ReversedComparator();
+        TreeMap reversedTreeMap = new TreeMap(comp);
+        reversedTreeMap.put(new Integer(1).toString(), new Integer(1));
+        reversedTreeMap.put(new Integer(2).toString(), new Integer(2));
+        TreeMap anotherTreeMap = new TreeMap(reversedTreeMap);
+        assertTrue("New tree map does not answer correct comparator",
+                anotherTreeMap.comparator() == comp);
+        assertTrue("TreeMap does not use comparator (firstKey was incorrect)",
+                anotherTreeMap.firstKey().equals(new Integer(2).toString()));
+        assertTrue("TreeMap does not use comparator (lastKey was incorrect)",
+                anotherTreeMap.lastKey().equals(new Integer(1).toString()));
+
+    }
+
+    /**
+     * java.util.TreeMap#clear()
+     */
+    public void test_clear() {
+        // Test for method void java.util.TreeMap.clear()
+        tm.clear();
+        assertEquals("Cleared map returned non-zero size", 0, tm.size());
+    }
+
+    /**
+     * java.util.TreeMap#clone()
+     */
+    public void test_clone() {
+        // Test for method java.lang.Object java.util.TreeMap.clone()
+        TreeMap clonedMap = (TreeMap) tm.clone();
+        assertTrue("Cloned map does not equal the original map", clonedMap
+                .equals(tm));
+        assertTrue("Cloned map is the same reference as the original map",
+                clonedMap != tm);
+        for (Object element : objArray) {
+            assertTrue("Cloned map contains incorrect elements", clonedMap
+                    .get(element.toString()) == tm.get(element.toString()));
+        }
+
+        TreeMap map = new TreeMap();
+        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());
+    }
+
+    /**
+     * java.util.TreeMap#comparator()
+     */
+    public void test_comparator() {
+        // Test for method java.util.Comparator java.util.TreeMap.comparator()\
+        Comparator comp = new ReversedComparator();
+        TreeMap reversedTreeMap = new TreeMap(comp);
+        assertTrue("TreeMap answered incorrect comparator", reversedTreeMap
+                .comparator() == comp);
+        reversedTreeMap.put(new Integer(1).toString(), new Integer(1));
+        reversedTreeMap.put(new Integer(2).toString(), new Integer(2));
+        assertTrue("TreeMap does not use comparator (firstKey was incorrect)",
+                reversedTreeMap.firstKey().equals(new Integer(2).toString()));
+        assertTrue("TreeMap does not use comparator (lastKey was incorrect)",
+                reversedTreeMap.lastKey().equals(new Integer(1).toString()));
+    }
+
+    /**
+     * java.util.TreeMap#containsKey(java.lang.Object)
+     */
+    public void test_containsKeyLjava_lang_Object() {
+        // Test for method boolean
+        // java.util.TreeMap.containsKey(java.lang.Object)
+        assertTrue("Returned false for valid key", tm.containsKey("95"));
+        assertTrue("Returned true for invalid key", !tm.containsKey("XXXXX"));
+    }
+
+    /**
+     * java.util.TreeMap#containsValue(java.lang.Object)
+     */
+    public void test_containsValueLjava_lang_Object() {
+        // Test for method boolean
+        // java.util.TreeMap.containsValue(java.lang.Object)
+        assertTrue("Returned false for valid value", tm
+                .containsValue(objArray[986]));
+        assertTrue("Returned true for invalid value", !tm
+                .containsValue(new Object()));
+    }
+
+    /**
+     * java.util.TreeMap#entrySet()
+     */
+    public void test_entrySet() {
+        // Test for method java.util.Set java.util.TreeMap.entrySet()
+        Set anEntrySet = tm.entrySet();
+        Iterator entrySetIterator = anEntrySet.iterator();
+        assertTrue("EntrySet is incorrect size",
+                anEntrySet.size() == objArray.length);
+        Map.Entry entry;
+        while (entrySetIterator.hasNext()) {
+            entry = (Map.Entry) entrySetIterator.next();
+            assertTrue("EntrySet does not contain correct mappings", tm
+                    .get(entry.getKey()) == entry.getValue());
+        }
+    }
+
+    /**
+     * java.util.TreeMap#firstKey()
+     */
+    public void test_firstKey() {
+        // Test for method java.lang.Object java.util.TreeMap.firstKey()
+        assertEquals("Returned incorrect first key", "0", tm.firstKey());
+    }
+
+    /**
+     * java.util.TreeMap#get(java.lang.Object)
+     */
+    public void test_getLjava_lang_Object() {
+        // Test for method java.lang.Object
+        // java.util.TreeMap.get(java.lang.Object)
+        Object o = new Object();
+        tm.put("Hello", o);
+        assertTrue("Failed to get mapping", tm.get("Hello") == o);
+
+        // Test for the same key & same value
+        tm = new TreeMap();
+        Object o2 = new Object();
+        Integer key1 = 1;
+        Integer key2 = 2;
+        assertNull(tm.put(key1, o));
+        assertNull(tm.put(key2, o));
+        assertEquals(2, tm.values().size());
+        assertEquals(2, tm.keySet().size());
+        assertSame(tm.get(key1), tm.get(key2));
+        assertSame(o, tm.put(key1, o2));
+        assertSame(o2, tm.get(key1));
+    }
+
+    /**
+     * java.util.TreeMap#headMap(java.lang.Object)
+     */
+    public void test_headMapLjava_lang_Object() {
+        // Test for method java.util.SortedMap
+        // java.util.TreeMap.headMap(java.lang.Object)
+        Map head = tm.headMap("100");
+        assertEquals("Returned map of incorrect size", 3, head.size());
+        assertTrue("Returned incorrect elements", head.containsKey("0")
+                && head.containsValue(new Integer("1"))
+                && head.containsKey("10"));
+
+        // Regression for Harmony-1026
+        TreeMap<Integer, Double> map = new TreeMap<Integer, Double>(
+                new MockComparator());
+        map.put(1, 2.1);
+        map.put(2, 3.1);
+        map.put(3, 4.5);
+        map.put(7, 21.3);
+        map.put(null, null);
+
+        SortedMap<Integer, Double> smap = map.headMap(null);
+        assertEquals(0, smap.size());
+
+        Set<Integer> keySet = smap.keySet();
+        assertEquals(0, keySet.size());
+
+        Set<Map.Entry<Integer, Double>> entrySet = smap.entrySet();
+        assertEquals(0, entrySet.size());
+
+        Collection<Double> valueCollection = smap.values();
+        assertEquals(0, valueCollection.size());
+
+        // Regression for Harmony-1066
+        assertTrue(head instanceof Serializable);
+
+        // Regression for ill-behaved collator
+        Collator c = new Collator() {
+            @Override
+            public int compare(String o1, String o2) {
+                if (o1 == null) {
+                    return 0;
+                }
+                return o1.compareTo(o2);
+            }
+
+            @Override
+            public CollationKey getCollationKey(String string) {
+                return null;
+            }
+
+            @Override
+            public int hashCode() {
+                return 0;
+            }
+        };
+
+        TreeMap<String, String> treemap = new TreeMap<String, String>(c);
+        assertEquals(0, treemap.headMap(null).size());
+
+        treemap = new TreeMap();
+        SortedMap<String, String> headMap = treemap.headMap("100");
+        headMap.headMap("100");
+
+        SortedMap<Integer, Integer> intMap, sub;
+        int size = 16;
+        intMap = new TreeMap<Integer, Integer>();
+        for (int i = 0; i < size; i++) {
+            intMap.put(i, i);
+        }
+        sub = intMap.headMap(-1);
+        assertEquals("size should be zero", sub.size(), 0);
+        assertTrue("submap should be empty", sub.isEmpty());
+        try {
+            sub.firstKey();
+            fail("java.util.NoSuchElementException should be thrown");
+        } catch (java.util.NoSuchElementException e) {
+        }
+
+        TreeMap t = new TreeMap();
+        try {
+            SortedMap th = t.headMap(null);
+            fail("Should throw a NullPointerException");
+        } catch (NullPointerException npe) {
+            // expected
+        }
+
+        try {
+            sub.lastKey();
+            fail("java.util.NoSuchElementException should be thrown");
+        } catch (java.util.NoSuchElementException e) {
+        }
+
+        size = 256;
+        intMap = new TreeMap<Integer, Integer>();
+        for (int i = 0; i < size; i++) {
+            intMap.put(i, i);
+        }
+        sub = intMap.headMap(-1);
+        assertEquals("size should be zero", sub.size(), 0);
+        assertTrue("submap should be empty", sub.isEmpty());
+        try {
+            sub.firstKey();
+            fail("java.util.NoSuchElementException should be thrown");
+        } catch (java.util.NoSuchElementException e) {
+        }
+
+        try {
+            sub.lastKey();
+            fail("java.util.NoSuchElementException should be thrown");
+        } catch (java.util.NoSuchElementException e) {
+        }
+
+    }
+
+    /**
+     * java.util.TreeMap#keySet()
+     */
+    public void test_keySet() {
+        // Test for method java.util.Set java.util.TreeMap.keySet()
+        Set ks = tm.keySet();
+        assertTrue("Returned set of incorrect size",
+                ks.size() == objArray.length);
+        for (int i = 0; i < tm.size(); i++) {
+            assertTrue("Returned set is missing keys", ks.contains(new Integer(
+                    i).toString()));
+        }
+    }
+
+    /**
+     * java.util.TreeMap#lastKey()
+     */
+    public void test_lastKey() {
+        // Test for method java.lang.Object java.util.TreeMap.lastKey()
+        assertTrue("Returned incorrect last key", tm.lastKey().equals(
+                objArray[objArray.length - 1].toString()));
+        assertNotSame(objArray[objArray.length - 1].toString(), tm.lastKey());
+        assertEquals(objArray[objArray.length - 2].toString(), tm
+                .headMap("999").lastKey());
+        assertEquals(objArray[objArray.length - 1].toString(), tm
+                .tailMap("123").lastKey());
+        assertEquals(objArray[objArray.length - 2].toString(), tm.subMap("99",
+                "999").lastKey());
+    }
+
+    public void test_lastKey_after_subMap() {
+        TreeMap<String, String> tm = new TreeMap<String, String>();
+        tm.put("001", "VAL001");
+        tm.put("003", "VAL003");
+        tm.put("002", "VAL002");
+        SortedMap<String, String> sm = tm;
+        String firstKey = (String) sm.firstKey();
+        String lastKey = "";
+        for (int i = 1; i <= tm.size(); i++) {
+            try {
+                lastKey = (String) sm.lastKey();
+            } catch (NoSuchElementException excep) {
+                fail("NoSuchElementException thrown when there are elements in the map");
+            }
+            sm = sm.subMap(firstKey, lastKey);
+        }
+    }
+
+    /**
+     * java.util.TreeMap#put(java.lang.Object, java.lang.Object)
+     */
+    public void test_putLjava_lang_ObjectLjava_lang_Object() {
+        // Test for method java.lang.Object
+        // java.util.TreeMap.put(java.lang.Object, java.lang.Object)
+        Object o = new Object();
+        tm.put("Hello", o);
+        assertTrue("Failed to put mapping", tm.get("Hello") == o);
+
+        // regression for Harmony-780
+        tm = new TreeMap();
+        assertNull(tm.put(new Object(), new Object()));
+        try {
+            tm.put(new Integer(1), new Object());
+            fail("should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+
+        tm = new TreeMap();
+        assertNull(tm.put(new Integer(1), new Object()));
+
+        try {
+            tm.put(new Object(), new Object());
+            fail("Should throw a ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+
+        // regression for Harmony-2474
+        // but RI6 changes its behavior
+        // so the test changes too
+        tm = new TreeMap();
+        try {
+            tm.remove(o);
+            fail("should throw ClassCastException");
+        } catch (ClassCastException e) {
+            //expected
+        }
+    }
+
+    /**
+     * java.util.TreeMap#putAll(java.util.Map)
+     */
+    public void test_putAllLjava_util_Map() {
+        // Test for method void java.util.TreeMap.putAll(java.util.Map)
+        TreeMap x = new TreeMap();
+        x.putAll(tm);
+        assertTrue("Map incorrect size after put", x.size() == tm.size());
+        for (Object element : objArray) {
+            assertTrue("Failed to put all elements", x.get(element.toString())
+                    .equals(element));
+        }
+    }
+
+    /**
+     * java.util.TreeMap#remove(java.lang.Object)
+     */
+    public void test_removeLjava_lang_Object() {
+        // Test for method java.lang.Object
+        // java.util.TreeMap.remove(java.lang.Object)
+        tm.remove("990");
+        assertTrue("Failed to remove mapping", !tm.containsKey("990"));
+
+    }
+
+    /**
+     * java.util.TreeMap#size()
+     */
+    public void test_size() {
+        // Test for method int java.util.TreeMap.size()
+        assertEquals("Returned incorrect size", 1000, tm.size());
+        assertEquals("Returned incorrect size", 447, tm.headMap("500").size());
+        assertEquals("Returned incorrect size", 1000, tm.headMap("null").size());
+        assertEquals("Returned incorrect size", 0, tm.headMap("").size());
+        assertEquals("Returned incorrect size", 448, tm.headMap("500a").size());
+        assertEquals("Returned incorrect size", 553, tm.tailMap("500").size());
+        assertEquals("Returned incorrect size", 0, tm.tailMap("null").size());
+        assertEquals("Returned incorrect size", 1000, tm.tailMap("").size());
+        assertEquals("Returned incorrect size", 552, tm.tailMap("500a").size());
+        assertEquals("Returned incorrect size", 111, tm.subMap("500", "600")
+                .size());
+        try {
+            tm.subMap("null", "600");
+            fail("Should throw an IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals("Returned incorrect size", 1000, tm.subMap("", "null")
+                .size());
+    }
+
+    /**
+     * java.util.TreeMap#subMap(java.lang.Object, java.lang.Object)
+     */
+    public void test_subMapLjava_lang_ObjectLjava_lang_Object() {
+        // Test for method java.util.SortedMap
+        // java.util.TreeMap.subMap(java.lang.Object, java.lang.Object)
+        SortedMap subMap = tm.subMap(objArray[100].toString(), objArray[109]
+                .toString());
+        assertEquals("subMap is of incorrect size", 9, subMap.size());
+        for (int counter = 100; counter < 109; counter++) {
+            assertTrue("SubMap contains incorrect elements", subMap.get(
+                    objArray[counter].toString()).equals(objArray[counter]));
+        }
+
+        try {
+            tm.subMap(objArray[9].toString(), objArray[1].toString());
+            fail("end key less than start key should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        // Regression for Harmony-1161
+        TreeMap<String, String> treeMapWithNull = new TreeMap<String, String>(
+                new MockComparatorNullTolerable());
+        treeMapWithNull.put("key1", "value1"); //$NON-NLS-1$ //$NON-NLS-2$
+        treeMapWithNull.put(null, "value2"); //$NON-NLS-1$
+        SortedMap<String, String> subMapWithNull = treeMapWithNull.subMap(null,
+                "key1"); //$NON-NLS-1$
+        assertEquals("Size of subMap should be 1:", 1, subMapWithNull.size()); //$NON-NLS-1$
+
+        // Regression test for typo in lastKey method
+        SortedMap<String, String> map = new TreeMap<String, String>();
+        map.put("1", "one"); //$NON-NLS-1$ //$NON-NLS-2$
+        map.put("2", "two"); //$NON-NLS-1$ //$NON-NLS-2$
+        map.put("3", "three"); //$NON-NLS-1$ //$NON-NLS-2$
+        assertEquals("3", map.lastKey());
+        SortedMap<String, String> sub = map.subMap("1", "3"); //$NON-NLS-1$ //$NON-NLS-2$
+        assertEquals("2", sub.lastKey()); //$NON-NLS-1$
+
+        TreeMap t = new TreeMap();
+        try {
+            SortedMap th = t.subMap(null, new Object());
+            fail("Should throw a NullPointerException");
+        } catch (NullPointerException npe) {
+            // expected
+        }
+    }
+
+
+    /**
+     * java.util.TreeMap#subMap(java.lang.Object, java.lang.Object)
+     */
+    public void test_subMap_Iterator() {
+        TreeMap<String, String> map = new TreeMap<String, String>();
+
+        String[] keys = { "1", "2", "3" };
+        String[] values = { "one", "two", "three" };
+        for (int i = 0; i < keys.length; i++) {
+            map.put(keys[i], values[i]);
+        }
+
+        assertEquals(3, map.size());
+
+        Map subMap = map.subMap("", "test");
+        assertEquals(3, subMap.size());
+
+        Set entrySet = subMap.entrySet();
+        Iterator iter = entrySet.iterator();
+        int size = 0;
+        while (iter.hasNext()) {
+            Map.Entry<String, String> entry = (Map.Entry<String, String>) iter
+                    .next();
+            assertTrue(map.containsKey(entry.getKey()));
+            assertTrue(map.containsValue(entry.getValue()));
+            size++;
+        }
+        assertEquals(map.size(), size);
+
+        Set<String> keySet = subMap.keySet();
+        iter = keySet.iterator();
+        size = 0;
+        while (iter.hasNext()) {
+            String key = (String) iter.next();
+            assertTrue(map.containsKey(key));
+            size++;
+        }
+        assertEquals(map.size(), size);
+    }
+
+
+    /**
+     * java.util.TreeMap#tailMap(java.lang.Object)
+     */
+    public void test_tailMapLjava_lang_Object() {
+        // Test for method java.util.SortedMap
+        // java.util.TreeMap.tailMap(java.lang.Object)
+        Map tail = tm.tailMap(objArray[900].toString());
+        assertTrue("Returned map of incorrect size : " + tail.size(), tail
+                .size() == (objArray.length - 900) + 9);
+        for (int i = 900; i < objArray.length; i++) {
+            assertTrue("Map contains incorrect entries", tail
+                    .containsValue(objArray[i]));
+        }
+
+        // Regression for Harmony-1066
+        assertTrue(tail instanceof Serializable);
+
+        SortedMap<Integer, Integer> intMap, sub;
+        int size = 16;
+        intMap = new TreeMap<Integer, Integer>();
+        for (int i = 0; i < size; i++) {
+            intMap.put(i, i);
+        }
+        sub = intMap.tailMap(size);
+        assertEquals("size should be zero", sub.size(), 0);
+        assertTrue("submap should be empty", sub.isEmpty());
+        try {
+            sub.firstKey();
+            fail("java.util.NoSuchElementException should be thrown");
+        } catch (java.util.NoSuchElementException e) {
+        }
+
+        TreeMap t = new TreeMap();
+        try {
+            SortedMap th = t.tailMap(null);
+            fail("Should throw a NullPointerException");
+        } catch (NullPointerException npe) {
+            // expected
+        }
+
+        try {
+            sub.lastKey();
+            fail("java.util.NoSuchElementException should be thrown");
+        } catch (java.util.NoSuchElementException e) {
+        }
+
+        size = 256;
+        intMap = new TreeMap<Integer, Integer>();
+        for (int i = 0; i < size; i++) {
+            intMap.put(i, i);
+        }
+        sub = intMap.tailMap(size);
+        assertEquals("size should be zero", sub.size(), 0);
+        assertTrue("submap should be empty", sub.isEmpty());
+        try {
+            sub.firstKey();
+            fail("java.util.NoSuchElementException should be thrown");
+        } catch (java.util.NoSuchElementException e) {
+        }
+
+        try {
+            sub.lastKey();
+            fail("java.util.NoSuchElementException should be thrown");
+        } catch (java.util.NoSuchElementException e) {
+        }
+
+    }
+
+    /**
+     * java.util.TreeMap#values()
+     */
+    public void test_values() {
+        // Test for method java.util.Collection java.util.TreeMap.values()
+        Collection vals = tm.values();
+        vals.iterator();
+        assertTrue("Returned collection of incorrect size",
+                vals.size() == objArray.length);
+        for (Object element : objArray) {
+            assertTrue("Collection contains incorrect elements", vals
+                    .contains(element));
+        }
+        assertEquals(1000, vals.size());
+        int j = 0;
+        for (Iterator iter = vals.iterator(); iter.hasNext(); ) {
+            Object element = (Object) iter.next();
+            j++;
+        }
+        assertEquals(1000, j);
+
+        vals = tm.descendingMap().values();
+        vals.iterator();
+        assertTrue("Returned collection of incorrect size",
+                vals.size() == objArray.length);
+        for (Object element : objArray) {
+            assertTrue("Collection contains incorrect elements", vals
+                    .contains(element));
+        }
+        assertEquals(1000, vals.size());
+        j = 0;
+        for (Iterator iter = vals.iterator(); iter.hasNext(); ) {
+            Object element = (Object) iter.next();
+            j++;
+        }
+        assertEquals(1000, j);
+
+        TreeMap myTreeMap = new TreeMap();
+        for (int i = 0; i < 100; i++) {
+            myTreeMap.put(objArray[i], objArray[i]);
+        }
+        Collection values = myTreeMap.values();
+        new Support_UnmodifiableCollectionTest(
+                "Test Returned Collection From TreeMap.values()", values)
+                .runTest();
+        values.remove(new Integer(0));
+        assertTrue(
+                "Removing from the values collection should remove from the original map",
+                !myTreeMap.containsValue(new Integer(0)));
+        assertEquals(99, values.size());
+        j = 0;
+        for (Iterator iter = values.iterator(); iter.hasNext(); ) {
+            Object element = (Object) iter.next();
+            j++;
+        }
+        assertEquals(99, j);
+
+    }
+
+    /**
+     * java.util.TreeMap the values() method in sub maps
+     */
+    public void test_subMap_values_size() {
+        TreeMap myTreeMap = new TreeMap();
+        for (int i = 0; i < 1000; i++) {
+            myTreeMap.put(i, objArray[i]);
+        }
+        // Test for method values() in subMaps
+        Collection vals = myTreeMap.subMap(200, 400).values();
+        assertTrue("Returned collection of incorrect size", vals.size() == 200);
+        for (int i = 200; i < 400; i++) {
+            assertTrue("Collection contains incorrect elements" + i, vals
+                    .contains(objArray[i]));
+        }
+        assertEquals(200, vals.toArray().length);
+        vals.remove(objArray[300]);
+        assertTrue(
+                "Removing from the values collection should remove from the original map",
+                !myTreeMap.containsValue(objArray[300]));
+        assertTrue("Returned collection of incorrect size", vals.size() == 199);
+        assertEquals(199, vals.toArray().length);
+
+        myTreeMap.put(300, objArray[300]);
+        // Test for method values() in subMaps
+        vals = myTreeMap.headMap(400).values();
+        assertEquals("Returned collection of incorrect size", vals.size(), 400);
+        for (int i = 0; i < 400; i++) {
+            assertTrue("Collection contains incorrect elements " + i, vals
+                    .contains(objArray[i]));
+        }
+        assertEquals(400, vals.toArray().length);
+        vals.remove(objArray[300]);
+        assertTrue(
+                "Removing from the values collection should remove from the original map",
+                !myTreeMap.containsValue(objArray[300]));
+        assertTrue("Returned collection of incorrect size", vals.size() == 399);
+        assertEquals(399, vals.toArray().length);
+
+        myTreeMap.put(300, objArray[300]);
+        // Test for method values() in subMaps
+        vals = myTreeMap.tailMap(400).values();
+        assertEquals("Returned collection of incorrect size", vals.size(), 600);
+        for (int i = 400; i < 1000; i++) {
+            assertTrue("Collection contains incorrect elements " + i, vals
+                    .contains(objArray[i]));
+        }
+        assertEquals(600, vals.toArray().length);
+        vals.remove(objArray[600]);
+        assertTrue(
+                "Removing from the values collection should remove from the original map",
+                !myTreeMap.containsValue(objArray[600]));
+        assertTrue("Returned collection of incorrect size", vals.size() == 599);
+        assertEquals(599, vals.toArray().length);
+
+
+        myTreeMap.put(600, objArray[600]);
+        // Test for method values() in subMaps
+        vals = myTreeMap.descendingMap().headMap(400).values();
+        assertEquals("Returned collection of incorrect size", vals.size(), 599);
+        for (int i = 401; i < 1000; i++) {
+            assertTrue("Collection contains incorrect elements " + i, vals
+                    .contains(objArray[i]));
+        }
+        assertEquals(599, vals.toArray().length);
+        vals.remove(objArray[600]);
+        assertTrue(
+                "Removing from the values collection should remove from the original map",
+                !myTreeMap.containsValue(objArray[600]));
+        assertTrue("Returned collection of incorrect size", vals.size() == 598);
+        assertEquals(598, vals.toArray().length);
+
+        myTreeMap.put(600, objArray[600]);
+        // Test for method values() in subMaps
+        vals = myTreeMap.descendingMap().tailMap(400).values();
+        assertEquals("Returned collection of incorrect size", vals.size(), 401);
+        for (int i = 0; i <= 400; i++) {
+            assertTrue("Collection contains incorrect elements " + i, vals
+                    .contains(objArray[i]));
+        }
+        assertEquals(401, vals.toArray().length);
+        vals.remove(objArray[300]);
+        assertTrue(
+                "Removing from the values collection should remove from the original map",
+                !myTreeMap.containsValue(objArray[300]));
+        assertTrue("Returned collection of incorrect size", vals.size() == 400);
+        assertEquals(400, vals.toArray().length);
+
+    }
+
+    /**
+     * java.util.TreeMap#subMap()
+     */
+    public void test_subMap_Iterator2() {
+        TreeMap<String, String> map = new TreeMap<String, String>();
+
+        String[] keys = { "1", "2", "3" };
+        String[] values = { "one", "two", "three" };
+        for (int i = 0; i < keys.length; i++) {
+            map.put(keys[i], values[i]);
+        }
+
+        assertEquals(3, map.size());
+
+        Map subMap = map.subMap("", "test");
+        assertEquals(3, subMap.size());
+
+        Set entrySet = subMap.entrySet();
+        Iterator iter = entrySet.iterator();
+        int size = 0;
+        while (iter.hasNext()) {
+            Map.Entry<String, String> entry = (Map.Entry<String, String>) iter
+                    .next();
+            assertTrue(map.containsKey(entry.getKey()));
+            assertTrue(map.containsValue(entry.getValue()));
+            size++;
+        }
+        assertEquals(map.size(), size);
+
+        Set<String> keySet = subMap.keySet();
+        iter = keySet.iterator();
+        size = 0;
+        while (iter.hasNext()) {
+            String key = (String) iter.next();
+            assertTrue(map.containsKey(key));
+            size++;
+        }
+        assertEquals(map.size(), size);
+    }
+
+    /**
+     * java.util.TreeMap#SerializationTest()
+     */
+    // Regression for Harmony-1066
+    public void test_SubMap_Serializable() throws Exception {
+        TreeMap<Integer, Double> map = new TreeMap<Integer, Double>();
+        map.put(1, 2.1);
+        map.put(2, 3.1);
+        map.put(3, 4.5);
+        map.put(7, 21.3);
+        SortedMap<Integer, Double> headMap = map.headMap(3);
+        assertTrue(headMap instanceof Serializable);
+        assertFalse(headMap instanceof TreeMap);
+        assertTrue(headMap instanceof SortedMap);
+
+        assertFalse(headMap.entrySet() instanceof Serializable);
+        assertFalse(headMap.keySet() instanceof Serializable);
+        assertFalse(headMap.values() instanceof Serializable);
+
+        // This assertion will fail on RI. This is a bug of RI.
+        SerializationTest.verifySelf(headMap);
+    }
+
+    /**
+     * {@link java.util.TreeMap#firstEntry()}
+     */
+    public void test_firstEntry() throws Exception {
+        Integer testint = new Integer(-1);
+        Integer testint10000 = new Integer(-10000);
+        Integer testint9999 = new Integer(-9999);
+        assertEquals(objArray[0].toString(), tm.firstEntry().getKey());
+        assertEquals(objArray[0], tm.firstEntry().getValue());
+        tm.put(testint.toString(), testint);
+        assertEquals(testint.toString(), tm.firstEntry().getKey());
+        assertEquals(testint, tm.firstEntry().getValue());
+        tm.put(testint10000.toString(), testint10000);
+        assertEquals(testint.toString(), tm.firstEntry().getKey());
+        assertEquals(testint, tm.firstEntry().getValue());
+        tm.put(testint9999.toString(), testint9999);
+        assertEquals(testint.toString(), tm.firstEntry().getKey());
+        Entry entry = tm.firstEntry();
+        assertEquals(testint, entry.getValue());
+        assertEntry(entry);
+        tm.clear();
+        assertNull(tm.firstEntry());
+    }
+
+    /**
+     * {@link java.util.TreeMap#lastEntry()
+     */
+    public void test_lastEntry() throws Exception {
+        Integer testint10000 = new Integer(10000);
+        Integer testint9999 = new Integer(9999);
+        assertEquals(objArray[999].toString(), tm.lastEntry().getKey());
+        assertEquals(objArray[999], tm.lastEntry().getValue());
+        tm.put(testint10000.toString(), testint10000);
+        assertEquals(objArray[999].toString(), tm.lastEntry().getKey());
+        assertEquals(objArray[999], tm.lastEntry().getValue());
+        tm.put(testint9999.toString(), testint9999);
+        assertEquals(testint9999.toString(), tm.lastEntry().getKey());
+        Entry entry = tm.lastEntry();
+        assertEquals(testint9999, entry.getValue());
+        assertEntry(entry);
+        tm.clear();
+        assertNull(tm.lastEntry());
+    }
+
+    /**
+     * {@link java.util.TreeMap#pollFirstEntry()
+     */
+    public void test_pollFirstEntry() throws Exception {
+        Integer testint = new Integer(-1);
+        Integer testint10000 = new Integer(-10000);
+        Integer testint9999 = new Integer(-9999);
+        assertEquals(objArray[0].toString(), tm.pollFirstEntry().getKey());
+        assertEquals(objArray[1], tm.pollFirstEntry().getValue());
+        assertEquals(objArray[10], tm.pollFirstEntry().getValue());
+        tm.put(testint.toString(), testint);
+        tm.put(testint10000.toString(), testint10000);
+        assertEquals(testint.toString(), tm.pollFirstEntry().getKey());
+        assertEquals(testint10000, tm.pollFirstEntry().getValue());
+        tm.put(testint9999.toString(), testint9999);
+        assertEquals(testint9999.toString(), tm.pollFirstEntry().getKey());
+        Entry entry = tm.pollFirstEntry();
+        assertEntry(entry);
+        assertEquals(objArray[100], entry.getValue());
+        tm.clear();
+        assertNull(tm.pollFirstEntry());
+    }
+
+    /**
+     * {@link java.util.TreeMap#pollLastEntry()
+     */
+    public void test_pollLastEntry() throws Exception {
+        Integer testint10000 = new Integer(10000);
+        Integer testint9999 = new Integer(9999);
+        assertEquals(objArray[999].toString(), tm.pollLastEntry().getKey());
+        assertEquals(objArray[998], tm.pollLastEntry().getValue());
+        assertEquals(objArray[997], tm.pollLastEntry().getValue());
+        tm.put(testint10000.toString(), testint10000);
+        assertEquals(objArray[996], tm.pollLastEntry().getValue());
+        tm.put(testint9999.toString(), testint9999);
+        assertEquals(testint9999.toString(), tm.pollLastEntry().getKey());
+        Entry entry = tm.pollLastEntry();
+        assertEquals(objArray[995], entry.getValue());
+        assertEntry(entry);
+        tm.clear();
+        assertNull(tm.pollLastEntry());
+    }
+
+    /**
+     * {@link java.util.TreeMap#lowerEntry(Object)
+     */
+    public void test_lowerEntry() throws Exception {
+        Integer testint10000 = new Integer(10000);
+        Integer testint9999 = new Integer(9999);
+        assertEquals(objArray[999], tm.lowerEntry(testint9999.toString())
+                .getValue());
+        assertEquals(objArray[100], tm.lowerEntry(testint10000.toString())
+                .getValue());
+        tm.put(testint10000.toString(), testint10000);
+        tm.put(testint9999.toString(), testint9999);
+        assertEquals(objArray[999], tm.lowerEntry(testint9999.toString())
+                .getValue());
+        Entry entry = tm.lowerEntry(testint10000.toString());
+        assertEquals(objArray[100], entry.getValue());
+        assertEntry(entry);
+        try {
+            tm.lowerEntry(testint10000);
+            fail("should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+        try {
+            tm.lowerEntry(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        tm.clear();
+        assertNull(tm.lowerEntry(testint9999.toString()));
+        assertNull(tm.lowerEntry(null));
+    }
+
+    /**
+     * {@link java.util.TreeMap#lowerKey(Object)
+     */
+    public void test_lowerKey() throws Exception {
+        Integer testint10000 = new Integer(10000);
+        Integer testint9999 = new Integer(9999);
+        assertEquals(objArray[999].toString(), tm.lowerKey(testint9999
+                .toString()));
+        assertEquals(objArray[100].toString(), tm.lowerKey(testint10000
+                .toString()));
+        tm.put(testint10000.toString(), testint10000);
+        tm.put(testint9999.toString(), testint9999);
+        assertEquals(objArray[999].toString(), tm.lowerKey(testint9999
+                .toString()));
+        assertEquals(objArray[100].toString(), tm.lowerKey(testint10000
+                .toString()));
+        try {
+            tm.lowerKey(testint10000);
+            fail("should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+        try {
+            tm.lowerKey(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        tm.clear();
+        assertNull(tm.lowerKey(testint9999.toString()));
+        assertNull(tm.lowerKey(null));
+    }
+
+    /**
+     * {@link java.util.TreeMap#floorEntry(Object)
+     */
+    public void test_floorEntry() throws Exception {
+        Integer testint10000 = new Integer(10000);
+        Integer testint9999 = new Integer(9999);
+        assertEquals(objArray[999], tm.floorEntry(testint9999.toString())
+                .getValue());
+        assertEquals(objArray[100], tm.floorEntry(testint10000.toString())
+                .getValue());
+        tm.put(testint10000.toString(), testint10000);
+        tm.put(testint9999.toString(), testint9999);
+        assertEquals(testint9999, tm.floorEntry(testint9999.toString())
+                .getValue());
+        Entry entry = tm.floorEntry(testint10000.toString());
+        assertEquals(testint10000, entry.getValue());
+        assertEntry(entry);
+        try {
+            tm.floorEntry(testint10000);
+            fail("should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+        try {
+            tm.floorEntry(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        tm.clear();
+        assertNull(tm.floorEntry(testint9999.toString()));
+        assertNull(tm.floorEntry(null));
+    }
+
+    /**
+     * {@link java.util.TreeMap#floorKey(Object)
+     */
+    public void test_floorKey() throws Exception {
+        Integer testint10000 = new Integer(10000);
+        Integer testint9999 = new Integer(9999);
+        assertEquals(objArray[999].toString(), tm.floorKey(testint9999
+                .toString()));
+        assertEquals(objArray[100].toString(), tm.floorKey(testint10000
+                .toString()));
+        tm.put(testint10000.toString(), testint10000);
+        tm.put(testint9999.toString(), testint9999);
+        assertEquals(testint9999.toString(), tm
+                .floorKey(testint9999.toString()));
+        assertEquals(testint10000.toString(), tm.floorKey(testint10000
+                .toString()));
+        try {
+            tm.floorKey(testint10000);
+            fail("should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+        try {
+            tm.floorKey(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        tm.clear();
+        assertNull(tm.floorKey(testint9999.toString()));
+        assertNull(tm.floorKey(null));
+    }
+
+    /**
+     * {@link java.util.TreeMap#ceilingEntry(Object)
+     */
+    public void test_ceilingEntry() throws Exception {
+        Integer testint100 = new Integer(100);
+        Integer testint = new Integer(-1);
+        assertEquals(objArray[0], tm.ceilingEntry(testint.toString())
+                .getValue());
+        assertEquals(objArray[100], tm.ceilingEntry(testint100.toString())
+                .getValue());
+        tm.put(testint.toString(), testint);
+        tm.put(testint100.toString(), testint);
+        assertEquals(testint, tm.ceilingEntry(testint.toString()).getValue());
+        Entry entry = tm.ceilingEntry(testint100.toString());
+        assertEquals(testint, entry.getValue());
+        assertEntry(entry);
+        try {
+            tm.ceilingEntry(testint100);
+            fail("should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+        try {
+            tm.ceilingEntry(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        tm.clear();
+        assertNull(tm.ceilingEntry(testint.toString()));
+        assertNull(tm.ceilingEntry(null));
+    }
+
+    /**
+     * {@link java.util.TreeMap#ceilingKey(Object)
+     */
+    public void test_ceilingKey() throws Exception {
+        Integer testint100 = new Integer(100);
+        Integer testint = new Integer(-1);
+        assertEquals(objArray[0].toString(), tm.ceilingKey(testint.toString()));
+        assertEquals(objArray[100].toString(), tm.ceilingKey(testint100
+                .toString()));
+        tm.put(testint.toString(), testint);
+        tm.put(testint100.toString(), testint);
+        assertEquals(testint.toString(), tm.ceilingKey(testint.toString()));
+        assertEquals(testint100.toString(), tm
+                .ceilingKey(testint100.toString()));
+        try {
+            tm.ceilingKey(testint100);
+            fail("should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+        try {
+            tm.ceilingKey(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        tm.clear();
+        assertNull(tm.ceilingKey(testint.toString()));
+        assertNull(tm.ceilingKey(null));
+    }
+
+    /**
+     * {@link java.util.TreeMap#higherEntry(Object)
+     */
+    public void test_higherEntry() throws Exception {
+        Integer testint9999 = new Integer(9999);
+        Integer testint10000 = new Integer(10000);
+        Integer testint100 = new Integer(100);
+        Integer testint = new Integer(-1);
+        assertEquals(objArray[0], tm.higherEntry(testint.toString()).getValue());
+        assertEquals(objArray[101], tm.higherEntry(testint100.toString())
+                .getValue());
+        assertEquals(objArray[101], tm.higherEntry(testint10000.toString())
+                .getValue());
+        tm.put(testint9999.toString(), testint);
+        tm.put(testint100.toString(), testint);
+        tm.put(testint10000.toString(), testint);
+        assertEquals(objArray[0], tm.higherEntry(testint.toString()).getValue());
+        assertEquals(testint, tm.higherEntry(testint100.toString()).getValue());
+        Entry entry = tm.higherEntry(testint10000.toString());
+        assertEquals(objArray[101], entry.getValue());
+        assertEntry(entry);
+        assertNull(tm.higherEntry(testint9999.toString()));
+        try {
+            tm.higherEntry(testint100);
+            fail("should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+        try {
+            tm.higherEntry(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        tm.clear();
+        assertNull(tm.higherEntry(testint.toString()));
+        assertNull(tm.higherEntry(null));
+    }
+
+    /**
+     * {@link java.util.TreeMap#higherKey(Object)
+     */
+    public void test_higherKey() throws Exception {
+        Integer testint9999 = new Integer(9999);
+        Integer testint10000 = new Integer(10000);
+        Integer testint100 = new Integer(100);
+        Integer testint = new Integer(-1);
+        assertEquals(objArray[0].toString(), tm.higherKey(testint.toString()));
+        assertEquals(objArray[101].toString(), tm.higherKey(testint100
+                .toString()));
+        assertEquals(objArray[101].toString(), tm.higherKey(testint10000
+                .toString()));
+        tm.put(testint9999.toString(), testint);
+        tm.put(testint100.toString(), testint);
+        tm.put(testint10000.toString(), testint);
+        assertEquals(objArray[0].toString(), tm.higherKey(testint.toString()));
+        assertEquals(testint10000.toString(), tm.higherKey(testint100
+                .toString()));
+        assertEquals(objArray[101].toString(), tm.higherKey(testint10000
+                .toString()));
+        assertNull(tm.higherKey(testint9999.toString()));
+        try {
+            tm.higherKey(testint100);
+            fail("should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+        try {
+            tm.higherKey(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        tm.clear();
+        assertNull(tm.higherKey(testint.toString()));
+        assertNull(tm.higherKey(null));
+    }
+
+    public void test_navigableKeySet() throws Exception {
+        Integer testint9999 = new Integer(9999);
+        Integer testint10000 = new Integer(10000);
+        Integer testint100 = new Integer(100);
+        Integer testint0 = new Integer(0);
+        NavigableSet set = tm.navigableKeySet();
+        assertFalse(set.contains(testint9999.toString()));
+        tm.put(testint9999.toString(), testint9999);
+        assertTrue(set.contains(testint9999.toString()));
+        tm.remove(testint9999.toString());
+        assertFalse(set.contains(testint9999.toString()));
+        try {
+            set.add(new Object());
+            fail("should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+        try {
+            set.add(null);
+            fail("should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+        try {
+            set.addAll(null);
+            fail("should throw UnsupportedOperationException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        Collection collection = new LinkedList();
+        set.addAll(collection);
+        try {
+            collection.add(new Object());
+            set.addAll(collection);
+            fail("should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+        set.remove(testint100.toString());
+        assertFalse(tm.containsKey(testint100.toString()));
+        assertTrue(tm.containsKey(testint0.toString()));
+        Iterator iter = set.iterator();
+        iter.next();
+        iter.remove();
+        assertFalse(tm.containsKey(testint0.toString()));
+        collection.add(new Integer(200).toString());
+        set.retainAll(collection);
+        assertEquals(1, tm.size());
+        set.removeAll(collection);
+        assertEquals(0, tm.size());
+        tm.put(testint10000.toString(), testint10000);
+        assertEquals(1, tm.size());
+        set.clear();
+        assertEquals(0, tm.size());
+    }
+
+    private void assertEntry(Entry entry) {
+        try {
+            entry.setValue(new Object());
+            fail("should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+        assertEquals((entry.getKey() == null ? 0 : entry.getKey().hashCode())
+                ^ (entry.getValue() == null ? 0 : entry.getValue().hashCode()),
+                entry.hashCode());
+        assertEquals(entry.toString(), entry.getKey() + "=" + entry.getValue());
+    }
+
+    /**
+     * java.util.TreeMap#subMap(java.lang.Object, boolean,
+     *java.lang.Object, boolean)
+     */
+    public void test_subMapLjava_lang_ObjectZLjava_lang_ObjectZ() {
+        // normal case
+        SortedMap subMap = tm.subMap(objArray[100].toString(), true,
+                objArray[109].toString(), true);
+        assertEquals("subMap is of incorrect size", 10, subMap.size());
+        subMap = tm.subMap(objArray[100].toString(), true, objArray[109]
+                .toString(), false);
+        assertEquals("subMap is of incorrect size", 9, subMap.size());
+        for (int counter = 100; counter < 109; counter++) {
+            assertTrue("SubMap contains incorrect elements", subMap.get(
+                    objArray[counter].toString()).equals(objArray[counter]));
+        }
+        subMap = tm.subMap(objArray[100].toString(), false, objArray[109]
+                .toString(), true);
+        assertEquals("subMap is of incorrect size", 9, subMap.size());
+        assertNull(subMap.get(objArray[100].toString()));
+
+        // Exceptions
+        try {
+            tm.subMap(objArray[9].toString(), true, objArray[1].toString(),
+                    true);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            tm.subMap(objArray[9].toString(), false, objArray[1].toString(),
+                    false);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            tm.subMap(null, true, null, true);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            tm.subMap(null, false, objArray[100], true);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            tm.subMap(new LinkedList(), false, objArray[100], true);
+            fail("should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+
+        // use integer elements to test
+        TreeMap<Integer, String> treeMapInt = new TreeMap<Integer, String>();
+        assertEquals(0, treeMapInt.subMap(new Integer(-1), true,
+                new Integer(100), true).size());
+        for (int i = 0; i < 100; i++) {
+            treeMapInt.put(new Integer(i), new Integer(i).toString());
+        }
+        SortedMap<Integer, String> result = treeMapInt.subMap(new Integer(-1),
+                true, new Integer(100), true);
+        assertEquals(100, result.size());
+        result.put(new Integer(-1), new Integer(-1).toString());
+        assertEquals(101, result.size());
+        assertEquals(101, treeMapInt.size());
+        result = treeMapInt
+                .subMap(new Integer(50), true, new Integer(60), true);
+        assertEquals(11, result.size());
+        try {
+            result.put(new Integer(-2), new Integer(-2).toString());
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals(11, result.size());
+        treeMapInt.remove(new Integer(50));
+        assertEquals(100, treeMapInt.size());
+        assertEquals(10, result.size());
+        result.remove(new Integer(60));
+        assertEquals(99, treeMapInt.size());
+        assertEquals(9, result.size());
+        SortedMap<Integer, String> result2 = null;
+        try {
+            result2 = result.subMap(new Integer(-2), new Integer(100));
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        result2 = result.subMap(new Integer(50), new Integer(60));
+        assertEquals(9, result2.size());
+
+        // sub map of sub map
+        NavigableMap<Integer, Object> mapIntObj = new TreeMap<Integer, Object>();
+        for (int i = 0; i < 10; ++i) {
+            mapIntObj.put(i, new Object());
+        }
+        mapIntObj = mapIntObj.subMap(5, false, 9, true);
+        assertEquals(4, mapIntObj.size());
+        mapIntObj = mapIntObj.subMap(5, false, 9, true);
+        assertEquals(4, mapIntObj.size());
+        mapIntObj = mapIntObj.subMap(5, false, 6, false);
+        assertEquals(0, mapIntObj.size());
+
+        // a special comparator dealing with null key
+        tm = new TreeMap(new Comparator() {
+            public int compare(Object o1, Object o2) {
+                if (o1 == null) {
+                    return -1;
+                }
+                return ((String) o1).compareTo((String) o2);
+            }
+        });
+        tm.put(new String("1st"), 1);
+        tm.put(new String("2nd"), 2);
+        tm.put(new String("3rd"), 3);
+        String nullKey = null;
+        tm.put(nullKey, -1);
+        SortedMap s = tm.subMap(null, "3rd");
+        assertEquals(3, s.size());
+        assertTrue(s.containsValue(-1));
+        assertTrue(s.containsValue(1));
+        assertTrue(s.containsValue(2));
+        assertFalse(s.containsKey(null));
+        // RI fails here
+        // assertTrue(s.containsKey("1st"));
+        // assertTrue(s.containsKey("2nd"));
+        s = tm.descendingMap();
+        s = s.subMap("3rd", null);
+        // assertEquals(4, s.size());
+//        assertTrue(s.containsValue(-1));
+//        assertTrue(s.containsValue(1));
+//        assertTrue(s.containsValue(2));
+//        assertTrue(s.containsValue(3));
+        assertFalse(s.containsKey(null));
+        assertTrue(s.containsKey("1st"));
+        assertTrue(s.containsKey("2nd"));
+        assertTrue(s.containsKey("3rd"));
+    }
+
+    public void test_subMap_NullTolerableComparator() {
+        // Null Tolerable Comparator
+        TreeMap<String, String> treeMapWithNull = new TreeMap<String, String>(
+                new MockComparatorNullTolerable());
+        treeMapWithNull.put("key1", "value1"); //$NON-NLS-1$ //$NON-NLS-2$
+        treeMapWithNull.put(null, "value2"); //$NON-NLS-1$
+        SortedMap<String, String> subMapWithNull = treeMapWithNull.subMap(null,
+                true, "key1", true); //$NON-NLS-1$ 
+
+        // RI fails here
+        assertEquals("Size of subMap should be 2:", 2, subMapWithNull.size()); //$NON-NLS-1$
+        assertEquals("value1", subMapWithNull.get("key1"));
+        assertEquals("value2", subMapWithNull.get(null));
+        treeMapWithNull.put("key0", "value2");
+        treeMapWithNull.put("key3", "value3");
+        treeMapWithNull.put("key4", "value4");
+        treeMapWithNull.put("key5", "value5");
+        treeMapWithNull.put("key6", "value6");
+        assertEquals("Size of subMap should be 3:", 3, subMapWithNull.size()); //$NON-NLS-1$
+        subMapWithNull = treeMapWithNull.subMap(null, false, "key1", true); //$NON-NLS-1$
+        assertEquals("Size of subMap should be 2:", 2, subMapWithNull.size()); //$NON-NLS-1$
+    }
+
+
+    /**
+     * java.util.TreeMap#headMap(java.lang.Object, boolea)
+     */
+    public void test_headMapLjava_lang_ObjectZL() {
+        // normal case
+        SortedMap subMap = tm.headMap(objArray[100].toString(), true);
+        assertEquals("subMap is of incorrect size", 4, subMap.size());
+        subMap = tm.headMap(objArray[109].toString(), true);
+        assertEquals("subMap is of incorrect size", 13, subMap.size());
+        for (int counter = 100; counter < 109; counter++) {
+            assertTrue("SubMap contains incorrect elements", subMap.get(
+                    objArray[counter].toString()).equals(objArray[counter]));
+        }
+        subMap = tm.headMap(objArray[100].toString(), false);
+        assertEquals("subMap is of incorrect size", 3, subMap.size());
+        assertNull(subMap.get(objArray[100].toString()));
+
+        // Exceptions
+        assertEquals(0, tm.headMap("", true).size());
+        assertEquals(0, tm.headMap("", false).size());
+
+        try {
+            tm.headMap(null, true);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            tm.headMap(null, false);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            tm.headMap(new Object(), true);
+            fail("should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+        try {
+            tm.headMap(new Object(), false);
+            fail("should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+
+        // use integer elements to test
+        TreeMap<Integer, String> treeMapInt = new TreeMap<Integer, String>();
+        assertEquals(0, treeMapInt.headMap(new Integer(-1), true).size());
+        for (int i = 0; i < 100; i++) {
+            treeMapInt.put(new Integer(i), new Integer(i).toString());
+        }
+        SortedMap<Integer, String> result = treeMapInt
+                .headMap(new Integer(101));
+        assertEquals(100, result.size());
+        try {
+            result.put(new Integer(101), new Integer(101).toString());
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals(100, result.size());
+        assertEquals(100, treeMapInt.size());
+        result = treeMapInt.headMap(new Integer(50), true);
+        assertEquals(51, result.size());
+        result.put(new Integer(-1), new Integer(-1).toString());
+        assertEquals(52, result.size());
+
+        treeMapInt.remove(new Integer(40));
+        assertEquals(100, treeMapInt.size());
+        assertEquals(51, result.size());
+        result.remove(new Integer(30));
+        assertEquals(99, treeMapInt.size());
+        assertEquals(50, result.size());
+        SortedMap<Integer, String> result2 = null;
+        try {
+            result.subMap(new Integer(-2), new Integer(100));
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            result.subMap(new Integer(1), new Integer(100));
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        result2 = result.subMap(new Integer(-2), new Integer(48));
+        assertEquals(47, result2.size());
+
+        result2 = result.subMap(new Integer(40), new Integer(50));
+        assertEquals(9, result2.size());
+
+        // Null Tolerable Comparator
+        TreeMap<String, String> treeMapWithNull = new TreeMap<String, String>(
+                new MockComparatorNullTolerable());
+        treeMapWithNull.put("key1", "value1"); //$NON-NLS-1$ //$NON-NLS-2$
+        treeMapWithNull.put(null, "value2"); //$NON-NLS-1$
+        SortedMap<String, String> subMapWithNull = treeMapWithNull.headMap(
+                null, true); //$NON-NLS-1$ 
+        assertEquals("Size of subMap should be 1:", 1, subMapWithNull.size()); //$NON-NLS-1$
+        assertEquals(null, subMapWithNull.get("key1"));
+        assertEquals("value2", subMapWithNull.get(null));
+        treeMapWithNull.put("key0", "value2");
+        treeMapWithNull.put("key3", "value3");
+        treeMapWithNull.put("key4", "value4");
+        treeMapWithNull.put("key5", "value5");
+        treeMapWithNull.put("key6", "value6");
+        assertEquals("Size of subMap should be 1:", 1, subMapWithNull.size()); //$NON-NLS-1$
+        subMapWithNull = treeMapWithNull.subMap(null, false, "key1", true); //$NON-NLS-1$
+        assertEquals("Size of subMap should be 2:", 2, subMapWithNull.size()); //$NON-NLS-1$
+
+        // head map of head map
+        NavigableMap<Integer, Object> mapIntObj = new TreeMap<Integer, Object>();
+        for (int i = 0; i < 10; ++i) {
+            mapIntObj.put(i, new Object());
+        }
+        mapIntObj = mapIntObj.headMap(5, false);
+        assertEquals(5, mapIntObj.size());
+        mapIntObj = mapIntObj.headMap(5, false);
+        assertEquals(5, mapIntObj.size());
+        mapIntObj = mapIntObj.tailMap(5, false);
+        assertEquals(0, mapIntObj.size());
+    }
+
+    /**
+     * java.util.TreeMap#tailMap(java.lang.Object, boolea)
+     */
+    public void test_tailMapLjava_lang_ObjectZL() {
+        // normal case
+        SortedMap subMap = tm.tailMap(objArray[100].toString(), true);
+        assertEquals("subMap is of incorrect size", 997, subMap.size());
+        subMap = tm.tailMap(objArray[109].toString(), true);
+        assertEquals("subMap is of incorrect size", 988, subMap.size());
+        for (int counter = 119; counter > 110; counter--) {
+            assertTrue("SubMap contains incorrect elements", subMap.get(
+                    objArray[counter].toString()).equals(objArray[counter]));
+        }
+        subMap = tm.tailMap(objArray[100].toString(), false);
+        assertEquals("subMap is of incorrect size", 996, subMap.size());
+        assertNull(subMap.get(objArray[100].toString()));
+
+        // Exceptions
+        assertEquals(1000, tm.tailMap("", true).size());
+        assertEquals(1000, tm.tailMap("", false).size());
+
+        try {
+            tm.tailMap(null, true);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            tm.tailMap(null, false);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            tm.tailMap(new Object(), true);
+            fail("should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+        try {
+            tm.tailMap(new Object(), false);
+            fail("should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
+
+        // use integer elements to test
+        TreeMap<Integer, String> treeMapInt = new TreeMap<Integer, String>();
+        assertEquals(0, treeMapInt.tailMap(new Integer(-1), true).size());
+        for (int i = 0; i < 100; i++) {
+            treeMapInt.put(new Integer(i), new Integer(i).toString());
+        }
+        SortedMap<Integer, String> result = treeMapInt.tailMap(new Integer(1));
+        assertEquals(99, result.size());
+        try {
+            result.put(new Integer(-1), new Integer(-1).toString());
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals(99, result.size());
+        assertEquals(100, treeMapInt.size());
+        result = treeMapInt.tailMap(new Integer(50), true);
+        assertEquals(50, result.size());
+        result.put(new Integer(101), new Integer(101).toString());
+        assertEquals(51, result.size());
+
+        treeMapInt.remove(new Integer(60));
+        assertEquals(100, treeMapInt.size());
+        assertEquals(50, result.size());
+        result.remove(new Integer(70));
+        assertEquals(99, treeMapInt.size());
+        assertEquals(49, result.size());
+        SortedMap<Integer, String> result2 = null;
+        try {
+            result2 = result.subMap(new Integer(-2), new Integer(100));
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        result2 = result.subMap(new Integer(60), new Integer(70));
+        assertEquals(9, result2.size());
+
+        // Null Tolerable Comparator
+        TreeMap<String, String> treeMapWithNull = new TreeMap<String, String>(
+                new MockComparatorNullTolerable());
+        treeMapWithNull.put("key1", "value1"); //$NON-NLS-1$ //$NON-NLS-2$
+        treeMapWithNull.put(null, "value2"); //$NON-NLS-1$
+        SortedMap<String, String> subMapWithNull = treeMapWithNull.tailMap(
+                "key1", true); //$NON-NLS-1$ 
+        assertEquals("Size of subMap should be 1:", 1, subMapWithNull.size()); //$NON-NLS-1$
+        assertEquals("value1", subMapWithNull.get("key1"));
+        assertEquals(null, subMapWithNull.get(null));
+        treeMapWithNull.put("key0", "value2");
+        treeMapWithNull.put("key3", "value3");
+        treeMapWithNull.put("key4", "value4");
+        treeMapWithNull.put("key5", "value5");
+        treeMapWithNull.put("key6", "value6");
+        assertEquals("Size of subMap should be 5:", 5, subMapWithNull.size()); //$NON-NLS-1$
+        subMapWithNull = treeMapWithNull.subMap(null, false, "key1", true); //$NON-NLS-1$
+        assertEquals("Size of subMap should be 2:", 2, subMapWithNull.size()); //$NON-NLS-1$
+
+        // tail map of tail map
+        NavigableMap<Integer, Object> mapIntObj = new TreeMap<Integer, Object>();
+        for (int i = 0; i < 10; ++i) {
+            mapIntObj.put(i, new Object());
+        }
+        mapIntObj = mapIntObj.tailMap(5, false);
+        assertEquals(4, mapIntObj.size());
+        mapIntObj = mapIntObj.tailMap(5, false);
+        assertEquals(4, mapIntObj.size());
+        mapIntObj = mapIntObj.headMap(5, false);
+        assertEquals(0, mapIntObj.size());
+    }
+
+    public void test_descendingMap_subMap() throws Exception {
+        TreeMap<Integer, Object> tm = new TreeMap<Integer, Object>();
+        for (int i = 0; i < 10; ++i) {
+            tm.put(i, new Object());
+        }
+        NavigableMap<Integer, Object> descMap = tm.descendingMap();
+        assertEquals(7, descMap.subMap(8, true, 1, false).size());
+        assertEquals(4, descMap.headMap(6, true).size());
+        assertEquals(2, descMap.tailMap(2, false).size());
+
+        // sub map of sub map of descendingMap
+        NavigableMap<Integer, Object> mapIntObj = new TreeMap<Integer, Object>();
+        for (int i = 0; i < 10; ++i) {
+            mapIntObj.put(i, new Object());
+        }
+        mapIntObj = mapIntObj.descendingMap();
+        NavigableMap<Integer, Object> subMapIntObj = mapIntObj.subMap(9, true,
+                5, false);
+        assertEquals(4, subMapIntObj.size());
+        subMapIntObj = subMapIntObj.subMap(9, true, 5, false);
+        assertEquals(4, subMapIntObj.size());
+        subMapIntObj = subMapIntObj.subMap(6, false, 5, false);
+        assertEquals(0, subMapIntObj.size());
+
+        subMapIntObj = mapIntObj.headMap(5, false);
+        assertEquals(4, subMapIntObj.size());
+        subMapIntObj = subMapIntObj.headMap(5, false);
+        assertEquals(4, subMapIntObj.size());
+        subMapIntObj = subMapIntObj.tailMap(5, false);
+        assertEquals(0, subMapIntObj.size());
+
+        subMapIntObj = mapIntObj.tailMap(5, false);
+        assertEquals(5, subMapIntObj.size());
+        subMapIntObj = subMapIntObj.tailMap(5, false);
+        assertEquals(5, subMapIntObj.size());
+        subMapIntObj = subMapIntObj.headMap(5, false);
+        assertEquals(0, subMapIntObj.size());
+    }
+
+    /**
+     * This test is about an old bug of RI.The bug is that: if the TreeMap has
+     * no comparator or its comparator is not null-tolerable, it can not put a
+     * null-key entry into this TreeMap.But RI can do it when the TreeMap is
+     * empty, and can not do it when the TreeMap is not empty.It is best for
+     * Harmony to follow RI's behavior for legacy reason. This test is to test
+     * the "illegal" TreeMap with the first null key. It can be easily removed
+     * when the bug is fixed in the future.
+     */
+    public void test_illegalFirstNullKey() {
+        // if the comparator is null
+        TreeMap<String, String> map = new TreeMap<String, String>();
+        map.put((String) null, "NullValue");
+        illegalFirstNullKeyMapTester(map);
+        //illegalFirstNullKeyMapTester(map.descendingMap());
+
+        // if the comparator is not null, but do not permit null key
+        map = new TreeMap<String, String>(new Comparator<String>() {
+            public int compare(String object1, String object2) {
+                return object1.compareTo(object2);
+            }
+        });
+        map.put((String) null, "NullValue");
+        illegalFirstNullKeyMapTester(map);
+        //illegalFirstNullKeyMapTester(map.descendingMap());
+
+        // add a few more testcases here based on this situation
+        TreeMap<Integer, String> map2 = new TreeMap<Integer, String>();
+        map2.put(null, "");
+        map2.firstEntry();
+        try {
+            map2.headMap(100).firstKey();
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            map2.tailMap(100).firstKey();
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        // can pass
+        map2.lastEntry();
+    }
+
+    private void illegalFirstNullKeyMapTester(NavigableMap<String, String> map) {
+        try {
+            map.get(null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            map.put("NormalKey", "value");
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        Set<String> keySet = map.keySet();
+        assertTrue(!keySet.isEmpty());
+        assertEquals(1, keySet.size());
+        for (String key : keySet) {
+            assertEquals(key, null);
+            try {
+                map.get(key);
+                fail("Should throw NullPointerException");
+            } catch (NullPointerException e) {
+                // ignore
+            }
+        }
+        Set<Entry<String, String>> entrySet = map.entrySet();
+        assertTrue(!entrySet.isEmpty());
+        assertEquals(1, entrySet.size());
+        for (Entry<String, String> entry : entrySet) {
+            assertEquals(null, entry.getKey());
+            assertEquals("NullValue", entry.getValue());
+        }
+        Collection<String> values = map.values();
+        assertTrue(!values.isEmpty());
+        assertEquals(1, values.size());
+        for (String value : values) {
+            assertEquals("NullValue", value);
+        }
+
+        try {
+            map.headMap(null, true);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // ignore
+        }
+        try {
+            map.headMap(null, false);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // ignore
+        }
+
+        try {
+            map.subMap(null, false, null, false);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // ignore
+        }
+        try {
+            map.subMap(null, true, null, true);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // ignore
+        }
+        try {
+            map.tailMap(null, true);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // ignore
+        }
+        try {
+            map.tailMap(null, false);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // ignore
+        }
+    }
+
+    /**
+     * Tests equals() method.
+     * Tests that no ClassCastException will be thrown in all cases.
+     * Regression test for HARMONY-1639.
+     */
+    public void test_equals() throws Exception {
+        // comparing TreeMaps with different object types
+        Map m1 = new TreeMap();
+        Map m2 = new TreeMap();
+        m1.put("key1", "val1");
+        m1.put("key2", "val2");
+        m2.put(new Integer(1), "val1");
+        m2.put(new Integer(2), "val2");
+        assertFalse("Maps should not be equal 1", m1.equals(m2));
+        assertFalse("Maps should not be equal 2", m2.equals(m1));
+
+        // comparing TreeMap with HashMap
+        m1 = new TreeMap();
+        m2 = new HashMap();
+        m1.put("key", "val");
+        m2.put(new Object(), "val");
+        assertFalse("Maps should not be equal 3", m1.equals(m2));
+        assertFalse("Maps should not be equal 4", m2.equals(m1));
+
+        // comparing TreeMaps with not-comparable objects inside
+        m1 = new TreeMap();
+        m2 = new TreeMap();
+        m1.put(new Object(), "val1");
+        m2.put(new Object(), "val1");
+        assertFalse("Maps should not be equal 5", m1.equals(m2));
+        assertFalse("Maps should not be equal 6", m2.equals(m1));
+    }
+
+    public void test_remove_from_iterator() throws Exception {
+        Set set = tm.keySet();
+        Iterator iter = set.iterator();
+        iter.next();
+        iter.remove();
+        try {
+            iter.remove();
+            fail("should throw IllegalStateException");
+        } catch (IllegalStateException e) {
+            // expected
+        }
+    }
+
+    /**
+     * Tests entrySet().contains() method behaviour with respect to entries
+     * with null values.
+     * Regression test for HARMONY-5788.
+     */
+    public void test_entrySet_contains() throws Exception {
+        TreeMap master = new TreeMap<String, String>();
+        TreeMap test_map = new TreeMap<String, String>();
+
+        master.put("null", null);
+        Object[] entry = master.entrySet().toArray();
+        assertFalse("Empty map should not contain the null-valued entry",
+                test_map.entrySet().contains(entry[0]));
+
+        Map<String, String> submap = test_map.subMap("a", "z");
+        entry = master.entrySet().toArray();
+        assertFalse("Empty submap should not contain the null-valued entry",
+                submap.entrySet().contains(entry[0]));
+
+        test_map.put("null", null);
+        assertTrue("entrySet().containsAll(...) should work with null values",
+                test_map.entrySet().containsAll(master.entrySet()));
+
+        master.clear();
+        master.put("null", '0');
+        entry = master.entrySet().toArray();
+        assertFalse("Null-valued entry should not equal non-null-valued entry",
+                test_map.entrySet().contains(entry[0]));
+    }
+
+    public void test_iterator_next_() {
+        Map m = tm.subMap("0", "1");
+        Iterator it = m.entrySet().iterator();
+        assertEquals("0=0", it.next().toString());
+        while (it.hasNext()) {
+        }
+        try {
+            it.next();
+            fail("should throw java.util.NoSuchElementException");
+        } catch (Exception e) {
+            assertTrue(e instanceof java.util.NoSuchElementException);
+        }
+    }
+
+    public void test_empty_subMap() throws Exception {
+        TreeMap<Float, List<Integer>> tm = new TreeMap<Float, List<Integer>>();
+        SortedMap<Float, List<Integer>> sm = tm.tailMap(1.1f);
+        assertTrue(sm.values().size() == 0);
+    }
+
+    public static TreeMap treeMap = new TreeMap();
+
+    public void test_values_1() {
+        treeMap.put("firstKey", "firstValue");
+        treeMap.put("secondKey", "secondValue");
+        treeMap.put("thirdKey", "thirdValue");
+        Object firstKey = treeMap.firstKey();
+        SortedMap subMap = ((SortedMap) treeMap).subMap(firstKey, firstKey);
+        Iterator iter = subMap.values().iterator();
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    @Override
+    protected void setUp() {
+        tm = new TreeMap();
+        for (int i = 0; i < objArray.length; i++) {
+            Object x = objArray[i] = new Integer(i);
+            tm.put(x.toString(), x);
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/TreeSetTest.java b/luni/src/test/java/tests/api/java/util/TreeSetTest.java
new file mode 100644
index 0000000..6ad00ee
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/TreeSetTest.java
@@ -0,0 +1,350 @@
+/*
+ *  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.util;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+public class TreeSetTest 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;
+        }
+    }
+
+    TreeSet ts;
+
+    Object objArray[] = new Object[1000];
+
+    /**
+     * java.util.TreeSet#TreeSet()
+     */
+    public void test_Constructor() {
+        // Test for method java.util.TreeSet()
+        assertTrue("Did not construct correct TreeSet", new TreeSet().isEmpty());
+    }
+
+    /**
+     * java.util.TreeSet#TreeSet(java.util.Collection)
+     */
+    public void test_ConstructorLjava_util_Collection() {
+        // Test for method java.util.TreeSet(java.util.Collection)
+        TreeSet myTreeSet = new TreeSet(Arrays.asList(objArray));
+        assertTrue("TreeSet incorrect size",
+                myTreeSet.size() == objArray.length);
+        for (int counter = 0; counter < objArray.length; counter++)
+            assertTrue("TreeSet does not contain correct elements", myTreeSet
+                    .contains(objArray[counter]));
+    }
+
+    /**
+     * java.util.TreeSet#TreeSet(java.util.Comparator)
+     */
+    public void test_ConstructorLjava_util_Comparator() {
+        // Test for method java.util.TreeSet(java.util.Comparator)
+        TreeSet myTreeSet = new TreeSet(new ReversedIntegerComparator());
+        assertTrue("Did not construct correct TreeSet", myTreeSet.isEmpty());
+        myTreeSet.add(new Integer(1));
+        myTreeSet.add(new Integer(2));
+        assertTrue(
+                "Answered incorrect first element--did not use custom comparator ",
+                myTreeSet.first().equals(new Integer(2)));
+        assertTrue(
+                "Answered incorrect last element--did not use custom comparator ",
+                myTreeSet.last().equals(new Integer(1)));
+    }
+
+    /**
+     * java.util.TreeSet#TreeSet(java.util.SortedSet)
+     */
+    public void test_ConstructorLjava_util_SortedSet() {
+        // Test for method java.util.TreeSet(java.util.SortedSet)
+        ReversedIntegerComparator comp = new ReversedIntegerComparator();
+        TreeSet myTreeSet = new TreeSet(comp);
+        for (int i = 0; i < objArray.length; i++)
+            myTreeSet.add(objArray[i]);
+        TreeSet anotherTreeSet = new TreeSet(myTreeSet);
+        assertTrue("TreeSet is not correct size",
+                anotherTreeSet.size() == objArray.length);
+        for (int counter = 0; counter < objArray.length; counter++)
+            assertTrue("TreeSet does not contain correct elements",
+                    anotherTreeSet.contains(objArray[counter]));
+        assertTrue("TreeSet does not answer correct comparator", anotherTreeSet
+                .comparator() == comp);
+        assertTrue("TreeSet does not use comparator",
+                anotherTreeSet.first() == objArray[objArray.length - 1]);
+    }
+
+    /**
+     * java.util.TreeSet#add(java.lang.Object)
+     */
+    public void test_addLjava_lang_Object() {
+        // Test for method boolean java.util.TreeSet.add(java.lang.Object)
+        ts.add(new Integer(-8));
+        assertTrue("Failed to add Object", ts.contains(new Integer(-8)));
+        ts.add(objArray[0]);
+        assertTrue("Added existing element", ts.size() == objArray.length + 1);
+
+    }
+
+    /**
+     * java.util.TreeSet#addAll(java.util.Collection)
+     */
+    public void test_addAllLjava_util_Collection() {
+        // Test for method boolean
+        // java.util.TreeSet.addAll(java.util.Collection)
+        TreeSet s = new TreeSet();
+        s.addAll(ts);
+        assertTrue("Incorrect size after add", s.size() == ts.size());
+        Iterator i = ts.iterator();
+        while (i.hasNext())
+            assertTrue("Returned incorrect set", s.contains(i.next()));
+
+    }
+
+    /**
+     * java.util.TreeSet#clear()
+     */
+    public void test_clear() {
+        // Test for method void java.util.TreeSet.clear()
+        ts.clear();
+        assertEquals("Returned non-zero size after clear", 0, ts.size());
+        assertTrue("Found element in cleared set", !ts.contains(objArray[0]));
+    }
+
+    /**
+     * java.util.TreeSet#clone()
+     */
+    public void test_clone() {
+        // Test for method java.lang.Object java.util.TreeSet.clone()
+        TreeSet s = (TreeSet) ts.clone();
+        Iterator i = ts.iterator();
+        while (i.hasNext())
+            assertTrue("Clone failed to copy all elements", s
+                    .contains(i.next()));
+    }
+
+    /**
+     * java.util.TreeSet#comparator()
+     */
+    public void test_comparator() {
+        // Test for method java.util.Comparator java.util.TreeSet.comparator()
+        ReversedIntegerComparator comp = new ReversedIntegerComparator();
+        TreeSet myTreeSet = new TreeSet(comp);
+        assertTrue("Answered incorrect comparator",
+                myTreeSet.comparator() == comp);
+    }
+
+    /**
+     * java.util.TreeSet#contains(java.lang.Object)
+     */
+    public void test_containsLjava_lang_Object() {
+        // Test for method boolean java.util.TreeSet.contains(java.lang.Object)
+        assertTrue("Returned false for valid Object", ts
+                .contains(objArray[objArray.length / 2]));
+        assertTrue("Returned true for invalid Object", !ts
+                .contains(new Integer(-9)));
+        try {
+            ts.contains(new Object());
+        } catch (ClassCastException e) {
+            // Correct
+            return;
+        }
+        fail("Failed to throw exception when passed invalid element");
+
+    }
+
+    /**
+     * java.util.TreeSet#first()
+     */
+    public void test_first() {
+        // Test for method java.lang.Object java.util.TreeSet.first()
+        assertTrue("Returned incorrect first element",
+                ts.first() == objArray[0]);
+    }
+
+    /**
+     * java.util.TreeSet#headSet(java.lang.Object)
+     */
+    public void test_headSetLjava_lang_Object() {
+        // Test for method java.util.SortedSet
+        // java.util.TreeSet.headSet(java.lang.Object)
+        Set s = ts.headSet(new Integer(100));
+        assertEquals("Returned set of incorrect size", 100, s.size());
+        for (int i = 0; i < 100; i++)
+            assertTrue("Returned incorrect set", s.contains(objArray[i]));
+    }
+
+    /**
+     * java.util.TreeSet#isEmpty()
+     */
+    public void test_isEmpty() {
+        // Test for method boolean java.util.TreeSet.isEmpty()
+        assertTrue("Empty set returned false", new TreeSet().isEmpty());
+        assertTrue("Non-Empty returned true", !ts.isEmpty());
+    }
+
+    /**
+     * java.util.TreeSet#iterator()
+     */
+    public void test_iterator() {
+        // Test for method java.util.Iterator java.util.TreeSet.iterator()
+        TreeSet s = new TreeSet();
+        s.addAll(ts);
+        Iterator i = ts.iterator();
+        Set as = new HashSet(Arrays.asList(objArray));
+        while (i.hasNext())
+            as.remove(i.next());
+        assertEquals("Returned incorrect iterator", 0, as.size());
+
+    }
+
+    /**
+     * java.util.TreeSet#last()
+     */
+    public void test_last() {
+        // Test for method java.lang.Object java.util.TreeSet.last()
+        assertTrue("Returned incorrect last element",
+                ts.last() == objArray[objArray.length - 1]);
+    }
+
+    /**
+     * java.util.TreeSet#remove(java.lang.Object)
+     */
+    public void test_removeLjava_lang_Object() {
+        // Test for method boolean java.util.TreeSet.remove(java.lang.Object)
+        ts.remove(objArray[0]);
+        assertTrue("Failed to remove object", !ts.contains(objArray[0]));
+        assertTrue("Failed to change size after remove",
+                ts.size() == objArray.length - 1);
+        try {
+            ts.remove(new Object());
+        } catch (ClassCastException e) {
+            // Correct
+            return;
+        }
+        fail("Failed to throw exception when past uncomparable value");
+    }
+
+    /**
+     * java.util.TreeSet#size()
+     */
+    public void test_size() {
+        // Test for method int java.util.TreeSet.size()
+        assertTrue("Returned incorrect size", ts.size() == objArray.length);
+    }
+
+    /**
+     * java.util.TreeSet#subSet(java.lang.Object, java.lang.Object)
+     */
+    public void test_subSetLjava_lang_ObjectLjava_lang_Object() {
+        // Test for method java.util.SortedSet
+        // java.util.TreeSet.subSet(java.lang.Object, java.lang.Object)
+        final int startPos = objArray.length / 4;
+        final int endPos = 3 * objArray.length / 4;
+        SortedSet aSubSet = ts.subSet(objArray[startPos], objArray[endPos]);
+        assertTrue("Subset has wrong number of elements",
+                aSubSet.size() == (endPos - startPos));
+        for (int counter = startPos; counter < endPos; counter++)
+            assertTrue("Subset does not contain all the elements it should",
+                    aSubSet.contains(objArray[counter]));
+
+        int result;
+        try {
+            ts.subSet(objArray[3], objArray[0]);
+            result = 0;
+        } catch (IllegalArgumentException e) {
+            result = 1;
+        }
+        assertEquals("end less than start should throw", 1, result);
+    }
+
+    /**
+     * java.util.TreeSet#tailSet(java.lang.Object)
+     */
+    public void test_tailSetLjava_lang_Object() {
+        // Test for method java.util.SortedSet
+        // java.util.TreeSet.tailSet(java.lang.Object)
+        Set s = ts.tailSet(new Integer(900));
+        assertEquals("Returned set of incorrect size", 100, s.size());
+        for (int i = 900; i < objArray.length; i++)
+            assertTrue("Returned incorrect set", s.contains(objArray[i]));
+    }
+
+    /**
+     * Tests equals() method.
+     * Tests that no ClassCastException will be thrown in all cases.
+     * Regression test for HARMONY-1639.
+     */
+    public void test_equals() throws Exception {
+        // comparing TreeSets with different object types
+        Set s1 = new TreeSet();
+        Set s2 = new TreeSet();
+        s1.add("key1");
+        s1.add("key2");
+        s2.add(new Integer(1));
+        s2.add(new Integer(2));
+        assertFalse("Sets should not be equal 1", s1.equals(s2));
+        assertFalse("Sets should not be equal 2", s2.equals(s1));
+
+        // comparing TreeSet with HashSet
+        s1 = new TreeSet();
+        s2 = new HashSet();
+        s1.add("key");
+        s2.add(new Object());
+        assertFalse("Sets should not be equal 3", s1.equals(s2));
+        assertFalse("Sets should not be equal 4", s2.equals(s1));
+
+        // comparing TreeSets with not-comparable objects inside
+        s1 = new TreeSet();
+        s2 = new TreeSet();
+        s1.add(new Object());
+        s2.add(new Object());
+        assertFalse("Sets should not be equal 5", s1.equals(s2));
+        assertFalse("Sets should not be equal 6", s2.equals(s1));
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() {
+        ts = new TreeSet();
+        for (int i = 0; i < objArray.length; i++) {
+            Object x = objArray[i] = new Integer(i);
+            ts.add(x);
+        }
+    }
+
+    /**
+     * 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/tests/api/java/util/UnknownFormatConversionExceptionTest.java b/luni/src/test/java/tests/api/java/util/UnknownFormatConversionExceptionTest.java
new file mode 100644
index 0000000..4880275
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/UnknownFormatConversionExceptionTest.java
@@ -0,0 +1,96 @@
+/* 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.util;
+
+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;
+
+public class UnknownFormatConversionExceptionTest extends TestCase {
+
+    /**
+     * java.util.UnknownFormatConversionException#UnknownFormatConversionException(String)
+     */
+    public void test_unknownFormatConversionException() {
+
+        // RI 5.0 will not throw NullPointerException, it is the bug according
+        // to spec.
+        try {
+            new UnknownFormatConversionException(null);
+            fail("should throw NullPointerExcepiton");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    /**
+     * java.util.UnknownFormatConversionException#getConversion()
+     */
+    public void test_getConversion() {
+        String s = "MYTESTSTRING";
+        UnknownFormatConversionException UnknownFormatConversionException = new UnknownFormatConversionException(
+                s);
+        assertEquals(s, UnknownFormatConversionException.getConversion());
+    }
+
+    /**
+     * java.util.UnknownFormatConversionException#getMessage()
+     */
+    public void test_getMessage() {
+        String s = "MYTESTSTRING";
+        UnknownFormatConversionException UnknownFormatConversionException = new UnknownFormatConversionException(
+                s);
+        assertTrue(null != UnknownFormatConversionException.getMessage());
+    }
+
+    // comparator for comparing UnknownFormatConversionException objects
+    private static final SerializableAssert exComparator = new SerializableAssert() {
+        public void assertDeserialized(Serializable initial,
+                Serializable deserialized) {
+
+            SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+                    deserialized);
+
+            UnknownFormatConversionException initEx = (UnknownFormatConversionException) initial;
+            UnknownFormatConversionException desrEx = (UnknownFormatConversionException) deserialized;
+
+            assertEquals("Conversion", initEx.getConversion(), desrEx
+                    .getConversion());
+        }
+    };
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        SerializationTest.verifySelf(new UnknownFormatConversionException(
+                "MYTESTSTRING"), exComparator);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        SerializationTest.verifyGolden(this,
+                new UnknownFormatConversionException("MYTESTSTRING"),
+                exComparator);
+    }
+}
diff --git a/luni/src/test/java/tests/api/java/util/UnknownFormatFlagsExceptionTest.java b/luni/src/test/java/tests/api/java/util/UnknownFormatFlagsExceptionTest.java
new file mode 100644
index 0000000..9d08f0b1
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/util/UnknownFormatFlagsExceptionTest.java
@@ -0,0 +1,94 @@
+/* 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.util;
+
+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;
+
+public class UnknownFormatFlagsExceptionTest extends TestCase {
+
+    /**
+     * java.util.UnknownFormatFlagsException#UnknownFormatFlagsException(String)
+     */
+    public void test_unknownFormatFlagsException() {
+
+        try {
+            new UnknownFormatFlagsException(null);
+            fail("should throw NullPointerExcepiton");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * java.util.UnknownFormatFlagsException#getFlags()
+     */
+    public void test_getFlags() {
+        String s = "MYTESTSTRING";
+        UnknownFormatFlagsException UnknownFormatFlagsException = new UnknownFormatFlagsException(
+                s);
+        assertEquals(s, UnknownFormatFlagsException.getFlags());
+    }
+
+    /**
+     * java.util.UnknownFormatFlagsException#getMessage()
+     */
+    public void test_getMessage() {
+        String s = "MYTESTSTRING";
+        UnknownFormatFlagsException UnknownFormatFlagsException = new UnknownFormatFlagsException(
+                s);
+        assertNotNull(UnknownFormatFlagsException.getMessage());
+    }
+
+    // comparator for comparing UnknownFormatFlagsException objects
+    private static final SerializableAssert exComparator = new SerializableAssert() {
+        public void assertDeserialized(Serializable initial,
+                Serializable deserialized) {
+
+            SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(initial,
+                    deserialized);
+
+            UnknownFormatFlagsException initEx = (UnknownFormatFlagsException) initial;
+            UnknownFormatFlagsException desrEx = (UnknownFormatFlagsException) deserialized;
+
+            assertEquals("Flags", initEx.getFlags(), desrEx.getFlags());
+        }
+    };
+
+    /**
+     * serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+
+        SerializationTest.verifySelf(new UnknownFormatFlagsException(
+                "MYTESTSTRING"), exComparator);
+    }
+
+    /**
+     * serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+
+        SerializationTest.verifyGolden(this, new UnknownFormatFlagsException(
+                "MYTESTSTRING"), exComparator);
+    }
+}
diff --git a/luni/src/test/java/tests/api/pkg1/TestClass.java b/luni/src/test/java/tests/api/pkg1/TestClass.java
new file mode 100644
index 0000000..37765b7
--- /dev/null
+++ b/luni/src/test/java/tests/api/pkg1/TestClass.java
@@ -0,0 +1,30 @@
+/*
+ *  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.pkg1;
+
+import java.io.Serializable;
+
+/**
+ * Used for a serialization test, must have different package and same base name
+ * as the TestClass in o.a.h.l.tests.pkg2
+ */
+public class TestClass implements Serializable {
+    private static final long serialVersionUID = 11111L;
+
+    public int i = 0;
+}
diff --git a/luni/src/test/java/tests/api/pkg2/TestClass.java b/luni/src/test/java/tests/api/pkg2/TestClass.java
new file mode 100644
index 0000000..1df7cdd
--- /dev/null
+++ b/luni/src/test/java/tests/api/pkg2/TestClass.java
@@ -0,0 +1,29 @@
+/*
+ *  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.pkg2;
+
+import java.io.Serializable;
+
+/**
+ * Used for a serialization test, must have different package and same base name
+ * as the TestClass in o.a.h.l.tests.pkg1
+ */
+public class TestClass implements Serializable {
+    private static final long serialVersionUID = 11111L;
+    public int i = 0;
+}
diff --git a/luni/src/test/java/tests/api/support/A.java b/luni/src/test/java/tests/api/support/A.java
new file mode 100644
index 0000000..11522be
--- /dev/null
+++ b/luni/src/test/java/tests/api/support/A.java
@@ -0,0 +1,30 @@
+/*
+ *  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.support;
+
+public class A implements I {
+    private static P pp = new P();
+
+    public A() {
+        pp.setClazz(getClass());
+    }
+
+    public String find(String key) {
+        return pp.findProp(key);
+    }
+}
diff --git a/luni/src/test/java/tests/api/support/B.java b/luni/src/test/java/tests/api/support/B.java
new file mode 100644
index 0000000..f0f6473
--- /dev/null
+++ b/luni/src/test/java/tests/api/support/B.java
@@ -0,0 +1,21 @@
+/*
+ *  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.support;
+
+public class B extends A {
+}
diff --git a/luni/src/test/java/tests/api/support/I.java b/luni/src/test/java/tests/api/support/I.java
new file mode 100644
index 0000000..65cbd22
--- /dev/null
+++ b/luni/src/test/java/tests/api/support/I.java
@@ -0,0 +1,22 @@
+/*
+ *  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.support;
+
+public interface I {
+    String find(String key);
+}
diff --git a/luni/src/test/java/tests/api/support/P.java b/luni/src/test/java/tests/api/support/P.java
new file mode 100644
index 0000000..95e879d
--- /dev/null
+++ b/luni/src/test/java/tests/api/support/P.java
@@ -0,0 +1,45 @@
+/*
+ *  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.support;
+
+import java.util.ResourceBundle;
+
+public class P {
+    private Class c;
+
+    public void setClazz(Class c) {
+        this.c = c;
+    }
+
+    public String findProp(String key) {
+        return findProp(this.c, key);
+    }
+
+    private String findProp(Class cls, String key) {
+        String ret = null;
+        try {
+            ResourceBundle b = ResourceBundle.getBundle(cls.getName());
+            ret = (String) b.getObject(key);
+        } catch (Exception e) {
+        }
+        if (ret == null && !cls.equals(Object.class) && !cls.isPrimitive()) {
+            ret = findProp(cls.getSuperclass(), key);
+        }
+        return ret;
+    }
+}
diff --git a/support/src/test/java/org/apache/harmony/testframework/CharSinkTester.java b/support/src/test/java/org/apache/harmony/testframework/CharSinkTester.java
new file mode 100644
index 0000000..7a1ce25
--- /dev/null
+++ b/support/src/test/java/org/apache/harmony/testframework/CharSinkTester.java
@@ -0,0 +1,209 @@
+/*
+ *  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.testframework;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Arrays;
+import java.util.Random;
+
+/**
+ * Tests behaviour common to all implementations of {@link Writer}. This adapts
+ * writers that collects untransformed chars so that they may be tested.
+ */
+public abstract class CharSinkTester {
+
+    private boolean throwsExceptions = true;
+
+    /**
+     * Creates a new writer ready to receive an arbitrary number of chars. Each
+     * time this method is invoked, any previously returned writers may be
+     * discarded.
+     */
+    public abstract Writer create() throws Exception;
+
+    /**
+     * Returns the current set of chars written to the writer last returned by
+     * {@link #create}, and releases any resources held by that writer.
+     */
+    public abstract char[] getChars() throws Exception;
+
+    /**
+     * Configures whether the writer is expected to throw exceptions when an
+     * error is encountered. Classes like {@code PrintWriter} report errors via
+     * an API method instead.
+     */
+    public CharSinkTester setThrowsExceptions(boolean throwsExceptions) {
+        this.throwsExceptions = throwsExceptions;
+        return this;
+    }
+
+    public final TestSuite createTests() {
+        TestSuite result = new TestSuite();
+        result.addTest(new SinkTestCase("sinkTestNoWriting"));
+        result.addTest(new SinkTestCase("sinkTestWriteZeroChars"));
+        result.addTest(new SinkTestCase("sinkTestWriteCharByChar"));
+        result.addTest(new SinkTestCase("sinkTestWriteArray"));
+        result.addTest(new SinkTestCase("sinkTestWriteOffset"));
+        result.addTest(new SinkTestCase("sinkTestWriteLargeArray"));
+
+        if (throwsExceptions) {
+            result.addTest(new SinkTestCase("sinkTestWriteAfterClose"));
+        } else {
+            result.addTest(new SinkTestCase("sinkTestWriteAfterCloseSuppressed"));
+        }
+
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getName();
+    }
+
+    private static void assertArrayEquals(char[] expected, char[] actual) {
+        Assert.assertEquals(Arrays.toString(expected), Arrays.toString(actual));
+    }
+
+    public class SinkTestCase extends TestCase {
+
+        private SinkTestCase(String name) {
+            super(name);
+        }
+
+        public void sinkTestNoWriting() throws Exception {
+            char[] expected = new char[] { };
+
+            Writer out = create();
+            out.close();
+            assertArrayEquals(expected, getChars());
+        }
+
+        public void sinkTestWriteZeroChars() throws Exception {
+            char[] expected = new char[] { };
+
+            Writer out = create();
+            char[] a = new char[1024];
+            out.write(a, 1000, 0);
+            out.write(a, 0, 0);
+            out.write(new char[] { });
+
+            out.close();
+            assertArrayEquals(expected, getChars());
+        }
+
+        public void sinkTestWriteCharByChar() throws Exception {
+            char[] expected = "EFGCDECBA".toCharArray();
+
+            Writer out = create();
+            for (char c : expected) {
+                out.write(c);
+            }
+
+            out.close();
+            assertArrayEquals(expected, getChars());
+        }
+
+        public void sinkTestWriteArray() throws Exception {
+            char[] expected = "EFGCDECBA".toCharArray();
+
+            Writer out = create();
+
+            out.write("EF".toCharArray());
+            out.write("GCDE".toCharArray());
+            out.write("CBA".toCharArray());
+
+            out.close();
+            assertArrayEquals(expected, getChars());
+        }
+
+        public void sinkTestWriteOffset() throws Exception {
+            char[] expected = "EFGCDECBA".toCharArray();
+            Writer out = create();
+
+            char[] a = new char[1024];
+            a[1000] = 'E';
+            a[1001] = 'F';
+            out.write(a, 1000, 2);
+
+            char[] b = new char[1024];
+            b[1020] = 'G';
+            b[1021] = 'C';
+            b[1022] = 'D';
+            b[1023] = 'E';
+            out.write(b, 1020, 4);
+
+            char[] c = new char[1024];
+            c[0] = 'C';
+            c[1] = 'B';
+            c[2] = 'A';
+            out.write(c, 0, 3);
+
+            out.close();
+            assertArrayEquals(expected, getChars());
+        }
+
+        public void sinkTestWriteLargeArray() throws Exception {
+            Random dice = new Random();
+            char[] expected = new char[(1024 * 1024) + 1]; // 2 MB + 1 char
+            for (int c = 0; c < expected.length; c++) {
+                expected[c] = (char) ('A' + dice.nextInt(26));
+            }
+
+            Writer out = create();
+            out.write(expected);
+            out.close();
+
+            assertArrayEquals(expected, getChars());
+        }
+
+        public void sinkTestWriteAfterClose() throws Exception {
+            char[] expectedChars = "EF".toCharArray();
+            Writer out = create();
+
+            out.write(expectedChars);
+            out.close();
+
+            try {
+                out.write("GCDE".toCharArray());
+                fail("expected already closed exception");
+            } catch (IOException expected) {
+            }
+
+            assertArrayEquals(expectedChars, getChars());
+        }
+
+        public void sinkTestWriteAfterCloseSuppressed() throws Exception {
+            Writer out = create();
+            out.write("EF".toCharArray());
+            out.close();
+            out.write("GCDE".toCharArray()); // no exception expected!
+        }
+
+        // adding a new test? Don't forget to update createTests().
+
+        @Override
+        public String getName() {
+            return CharSinkTester.this.toString() + ":" + super.getName();
+        }
+    }
+}
diff --git a/support/src/test/java/org/apache/harmony/testframework/CharWrapperTester.java b/support/src/test/java/org/apache/harmony/testframework/CharWrapperTester.java
new file mode 100644
index 0000000..3bbebf2
--- /dev/null
+++ b/support/src/test/java/org/apache/harmony/testframework/CharWrapperTester.java
@@ -0,0 +1,258 @@
+/*
+ *  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.testframework;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.io.IOException;
+import java.io.Writer;
+
+/**
+ * Tests behaviour common to wrapping and filtering implementations of {@link
+ * Writer}.
+ */
+public abstract class CharWrapperTester {
+
+    private boolean throwsExceptions = true;
+
+    /**
+     * Creates a new output stream that receives one stream of chars, optionally
+     * transforms it, and emits another stream of chars to {@code delegate}.
+     */
+    public abstract Writer create(Writer delegate) throws Exception;
+
+    /**
+     * Decodes the chars received by the delegate into their original form: the
+     * chars originally received by this wrapper.
+     */
+    public abstract char[] decode(char[] delegateChars) throws Exception;
+
+    /**
+     * Configures whether the writer is expected to throw exceptions when an
+     * error is encountered. Classes like {@code PrintWriter} report errors via
+     * an API method instead.
+     */
+    public CharWrapperTester setThrowsExceptions(boolean throwsExceptions) {
+        this.throwsExceptions = throwsExceptions;
+        return this;
+    }
+
+    public final TestSuite createTests() {
+        TestSuite result = new TestSuite();
+        result.addTest(new WrapperSinkTester()
+                .setThrowsExceptions(throwsExceptions)
+                .createTests());
+
+        if (throwsExceptions) {
+            result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaFlush"));
+            result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaClose"));
+            result.addTest(new WrapperTestCase("wrapperTestCloseThrows"));
+        } else {
+            result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaFlushSuppressed"));
+            result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaCloseSuppressed"));
+            result.addTest(new WrapperTestCase("wrapperTestCloseThrowsSuppressed"));
+        }
+
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getName();
+    }
+
+    private class WrapperSinkTester extends CharSinkTester {
+        private ClosableStringWriter delegate;
+
+        @Override
+        public Writer create() throws Exception {
+            delegate = new ClosableStringWriter();
+            return CharWrapperTester.this.create(delegate);
+        }
+
+        @Override
+        public char[] getChars() throws Exception {
+            return decode(delegate.buffer.toString().toCharArray());
+        }
+
+        @Override
+        public String toString() {
+            return CharWrapperTester.this.toString();
+        }
+    }
+
+    public class WrapperTestCase extends TestCase {
+
+        private WrapperTestCase(String name) {
+            super(name);
+        }
+
+        @Override
+        public String getName() {
+            return CharWrapperTester.this.toString() + ":" + super.getName();
+        }
+
+        public void wrapperTestFlushThrowsViaFlushSuppressed() throws Exception {
+            FailOnFlushWriter delegate = new FailOnFlushWriter();
+            Writer o = create(delegate);
+            o.write("BUT");
+            o.write("TERS");
+            o.flush();
+            assertTrue(delegate.flushed);
+        }
+
+        public void wrapperTestFlushThrowsViaCloseSuppressed() throws Exception {
+            FailOnFlushWriter delegate = new FailOnFlushWriter();
+            Writer o = create(delegate);
+            o.write("BUT");
+            o.write("TERS");
+            o.close();
+            assertTrue(delegate.flushed);
+        }
+
+        public void wrapperTestFlushThrowsViaFlush() throws Exception {
+            FailOnFlushWriter delegate = new FailOnFlushWriter();
+
+            Writer o = create(delegate);
+            try {
+                // any of these is permitted to flush
+                o.write("BUT");
+                o.write("TERS");
+                o.flush();
+                assertTrue(delegate.flushed);
+                fail("flush exception ignored");
+            } catch (IOException expected) {
+                assertEquals("Flush failed", expected.getMessage());
+            }
+        }
+
+        public void wrapperTestFlushThrowsViaClose() throws Exception {
+            FailOnFlushWriter delegate = new FailOnFlushWriter();
+
+            Writer o = create(delegate);
+            try {
+                // any of these is permitted to flush
+                o.write("BUT");
+                o.write("TERS");
+                o.close();
+                assertTrue(delegate.flushed);
+                fail("flush exception ignored");
+            } catch (IOException expected) {
+                assertEquals("Flush failed", expected.getMessage());
+            }
+
+            try {
+                o.write("BARK");
+                fail("expected already closed exception");
+            } catch (IOException expected) {
+            }
+        }
+
+        public void wrapperTestCloseThrows() throws Exception {
+            FailOnCloseWriter delegate = new FailOnCloseWriter();
+            Writer o = create(delegate);
+            try {
+                o.close();
+                assertTrue(delegate.closed);
+                fail("close exception ignored");
+            } catch (IOException expected) {
+                assertEquals("Close failed", expected.getMessage());
+            }
+        }
+
+        public void wrapperTestCloseThrowsSuppressed() throws Exception {
+            FailOnCloseWriter delegate = new FailOnCloseWriter();
+            Writer o = create(delegate);
+            o.close();
+            assertTrue(delegate.closed);
+        }
+
+        // adding a new test? Don't forget to update createTests().
+    }
+
+    /**
+     * A custom Writer that respects the closed state. The built-in StringWriter
+     * doesn't respect close(), which makes testing wrapped streams difficult.
+     */
+    private static class ClosableStringWriter extends Writer {
+        private final StringBuilder buffer = new StringBuilder();
+        private boolean closed = false;
+
+        @Override
+        public void close() throws IOException {
+            closed = true;
+        }
+
+        @Override
+        public void flush() throws IOException {
+        }
+
+        @Override
+        public void write(char[] buf, int offset, int count) throws IOException {
+            if (closed) {
+                throw new IOException();
+            }
+            buffer.append(buf, offset, count);
+        }
+    }
+
+    private static class FailOnFlushWriter extends Writer {
+        boolean flushed = false;
+        boolean closed = false;
+
+        @Override
+        public void write(char[] buf, int offset, int count) throws IOException {
+            if (closed) {
+                throw new IOException("Already closed");
+            }
+        }
+
+        @Override
+        public void close() throws IOException {
+            closed = true;
+            flush();
+        }
+
+        @Override
+        public void flush() throws IOException {
+            if (!flushed) {
+                flushed = true;
+                throw new IOException("Flush failed");
+            }
+        }
+    }
+
+    private static class FailOnCloseWriter extends Writer {
+        boolean closed = false;
+
+        @Override
+        public void flush() throws IOException {
+        }
+
+        @Override
+        public void write(char[] buf, int offset, int count) throws IOException {
+        }
+
+        @Override
+        public void close() throws IOException {
+            closed = true;
+            throw new IOException("Close failed");
+        }
+    }
+}
\ No newline at end of file
diff --git a/support/src/test/java/org/apache/harmony/testframework/SinkTester.java b/support/src/test/java/org/apache/harmony/testframework/SinkTester.java
new file mode 100644
index 0000000..6c12384
--- /dev/null
+++ b/support/src/test/java/org/apache/harmony/testframework/SinkTester.java
@@ -0,0 +1,221 @@
+/*
+ *  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.testframework;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.Random;
+
+/**
+ * Tests behaviour common to all implementations of {@link OutputStream}. This
+ * adapts streams that collects untransformed bytes so that they may be tested.
+ */
+public abstract class SinkTester {
+
+    private boolean throwsExceptions = true;
+
+    /**
+     * Creates a new output stream ready to receive an arbitrary number of
+     * bytes. Each time this method is invoked, any previously returned output
+     * streams may be discarded.
+     */
+    public abstract OutputStream create() throws Exception;
+
+    /**
+     * Returns the current set of bytes written to the output stream last
+     * returned by {@link #create}, and releases any resources held by that
+     * stream.
+     */
+    public abstract byte[] getBytes() throws Exception;
+
+    /**
+     * Configures whether the stream is expected to throw exceptions when an
+     * error is encountered. Classes like {@code PrintStream} report errors via
+     * an API method instead.
+     */
+    public SinkTester setThrowsExceptions(boolean throwsExceptions) {
+        this.throwsExceptions = throwsExceptions;
+        return this;
+    }
+
+    public final TestSuite createTests() {
+        TestSuite result = new TestSuite();
+        result.addTest(new SinkTestCase("sinkTestNoWriting"));
+        result.addTest(new SinkTestCase("sinkTestWriteZeroBytes"));
+        result.addTest(new SinkTestCase("sinkTestWriteByteByByte"));
+        result.addTest(new SinkTestCase("sinkTestWriteArray"));
+        result.addTest(new SinkTestCase("sinkTestWriteOffset"));
+        result.addTest(new SinkTestCase("sinkTestWriteLargeArray"));
+
+        if (throwsExceptions) {
+            result.addTest(new SinkTestCase("sinkTestWriteAfterClose"));
+        } else {
+            result.addTest(new SinkTestCase("sinkTestWriteAfterCloseSuppressed"));
+        }
+
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getName();
+    }
+
+    private static void assertArrayEquals(byte[] expected, byte[] actual) {
+        Assert.assertEquals(Arrays.toString(expected), Arrays.toString(actual));
+    }
+
+    public class SinkTestCase extends TestCase {
+
+        private SinkTestCase(String name) {
+            super(name);
+        }
+
+        public void sinkTestNoWriting() throws Exception {
+            byte[] expected = new byte[] { };
+
+            OutputStream out = create();
+            out.close();
+            assertArrayEquals(expected, getBytes());
+        }
+
+        public void sinkTestWriteZeroBytes() throws Exception {
+            byte[] expected = new byte[] { };
+
+            OutputStream out = create();
+            byte[] a = new byte[1024];
+            out.write(a, 1000, 0);
+            out.write(a, 0, 0);
+            out.write(new byte[] { });
+
+            out.close();
+            assertArrayEquals(expected, getBytes());
+        }
+
+        public void sinkTestWriteByteByByte() throws Exception {
+            byte[] expected = new byte[] { 5, 6, 7, 3, 4, 5, 3, 2, 1 };
+
+            OutputStream out = create();
+            for (byte b : expected) {
+                out.write(b);
+            }
+
+            out.close();
+            assertArrayEquals(expected, getBytes());
+        }
+
+        public void sinkTestWriteArray() throws Exception {
+            byte[] expected = new byte[] {
+                    5, 6,
+                    7, 3, 4, 5,
+                    3, 2, 1
+            };
+
+            OutputStream out = create();
+
+            byte[] a = new byte[] { 5, 6 };
+            out.write(a);
+
+            byte[] b = new byte[] { 7, 3, 4, 5 };
+            out.write(b);
+
+            byte[] c = new byte[] { 3, 2, 1 };
+            out.write(c);
+
+            out.close();
+            assertArrayEquals(expected, getBytes());
+        }
+
+        public void sinkTestWriteOffset() throws Exception {
+            byte[] expected = new byte[] {
+                    5, 6,
+                    7, 3, 4, 5,
+                    3, 2, 1
+            };
+
+            OutputStream out = create();
+
+            byte[] a = new byte[1024];
+            a[1000] = 5;
+            a[1001] = 6;
+            out.write(a, 1000, 2);
+
+            byte[] b = new byte[1024];
+            b[1020] = 7;
+            b[1021] = 3;
+            b[1022] = 4;
+            b[1023] = 5;
+            out.write(b, 1020, 4);
+
+            byte[] c = new byte[1024];
+            c[0] = 3;
+            c[1] = 2;
+            c[2] = 1;
+            out.write(c, 0, 3);
+
+            out.close();
+            assertArrayEquals(expected, getBytes());
+        }
+
+        public void sinkTestWriteLargeArray() throws Exception {
+            byte[] expected = new byte[(1024 * 1024) + 1]; // 1 MB + 1 byte
+            new Random().nextBytes(expected);
+
+            OutputStream out = create();
+            out.write(expected);
+            out.close();
+
+            assertArrayEquals(expected, getBytes());
+        }
+
+        public void sinkTestWriteAfterClose() throws Exception {
+            byte[] expectedBytes = { 5, 6 };
+            OutputStream out = create();
+
+            out.write(expectedBytes);
+            out.close();
+
+            try {
+                out.write(new byte[] { 7, 3, 4, 5 });
+                fail("expected already closed exception");
+            } catch (IOException expected) {
+            }
+
+            assertArrayEquals(expectedBytes, getBytes());
+        }
+
+        public void sinkTestWriteAfterCloseSuppressed() throws Exception {
+            OutputStream out = create();
+            out.write(new byte[] { 5, 6 });
+            out.close();
+            out.write(new byte[] { 7, 3, 4, 5 }); // no exception expected!
+        }
+
+        // adding a new test? Don't forget to update createTests().
+
+        @Override
+        public String getName() {
+            return SinkTester.this.toString() + ":" + super.getName();
+        }
+    }
+}
diff --git a/support/src/test/java/org/apache/harmony/testframework/WrapperTester.java b/support/src/test/java/org/apache/harmony/testframework/WrapperTester.java
new file mode 100644
index 0000000..515c94f
--- /dev/null
+++ b/support/src/test/java/org/apache/harmony/testframework/WrapperTester.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 org.apache.harmony.testframework;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Tests behaviour common to wrapping and filtering implementations of {@link
+ * OutputStream}.
+ */
+public abstract class WrapperTester {
+
+    private boolean throwsExceptions = true;
+
+    /**
+     * Creates a new output stream that receives one stream of bytes, optionally
+     * transforms it, and emits another stream of bytes to {@code delegate}.
+     */
+    public abstract OutputStream create(OutputStream delegate) throws Exception;
+
+    /**
+     * Decodes the bytes received by the delegate into their original form: the
+     * bytes originally received by this wrapper.
+     */
+    public abstract byte[] decode(byte[] delegateBytes) throws Exception;
+
+    /**
+     * Configures whether the stream is expected to throw exceptions when an
+     * error is encountered. Classes like {@code PrintStream} report errors via
+     * an API method instead.
+     */
+    public WrapperTester setThrowsExceptions(boolean throwsExceptions) {
+        this.throwsExceptions = throwsExceptions;
+        return this;
+    }
+
+    public final TestSuite createTests() {
+        TestSuite result = new TestSuite();
+        result.addTest(new WrapperSinkTester()
+                .setThrowsExceptions(throwsExceptions)
+                .createTests());
+
+        if (throwsExceptions) {
+            result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaFlush"));
+            result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaClose"));
+            result.addTest(new WrapperTestCase("wrapperTestCloseThrows"));
+        } else {
+            result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaFlushSuppressed"));
+            result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaCloseSuppressed"));
+            result.addTest(new WrapperTestCase("wrapperTestCloseThrowsSuppressed"));
+        }
+
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getName();
+    }
+
+    private class WrapperSinkTester extends SinkTester {
+        private ClosableByteArrayOutputStream delegate;
+
+        @Override
+        public OutputStream create() throws Exception {
+            delegate = new ClosableByteArrayOutputStream();
+            return WrapperTester.this.create(delegate);
+        }
+
+        @Override
+        public byte[] getBytes() throws Exception {
+            return WrapperTester.this.decode(delegate.bytesOut.toByteArray());
+        }
+
+        @Override
+        public String toString() {
+            return WrapperTester.this.toString();
+        }
+    }
+
+    public class WrapperTestCase extends TestCase {
+
+        private WrapperTestCase(String name) {
+            super(name);
+        }
+
+        @Override
+        public String getName() {
+            return WrapperTester.this.toString() + ":" + super.getName();
+        }
+
+        public void wrapperTestFlushThrowsViaFlushSuppressed() throws Exception {
+            FailOnFlushOutputStream delegate = new FailOnFlushOutputStream();
+            OutputStream o = create(delegate);
+            o.write(new byte[] { 8, 6, 7, 5 });
+            o.write(new byte[] { 3, 0, 9 });
+            o.flush();
+            assertTrue(delegate.flushed);
+        }
+
+        public void wrapperTestFlushThrowsViaCloseSuppressed() throws Exception {
+            FailOnFlushOutputStream delegate = new FailOnFlushOutputStream();
+            OutputStream o = create(delegate);
+            o.write(new byte[] { 8, 6, 7, 5 });
+            o.write(new byte[] { 3, 0, 9 });
+            o.close();
+            assertTrue(delegate.flushed);
+        }
+
+        public void wrapperTestFlushThrowsViaFlush() throws Exception {
+            FailOnFlushOutputStream delegate = new FailOnFlushOutputStream();
+
+            OutputStream o = create(delegate);
+            try {
+                // any of these is permitted to flush
+                o.write(new byte[] { 8, 6, 7, 5 });
+                o.write(new byte[] { 3, 0, 9 });
+                o.flush();
+                assertTrue(delegate.flushed);
+                fail("flush exception ignored");
+            } catch (IOException expected) {
+                assertEquals("Flush failed", expected.getMessage());
+            }
+        }
+
+        public void wrapperTestFlushThrowsViaClose() throws Exception {
+            FailOnFlushOutputStream delegate = new FailOnFlushOutputStream();
+
+            OutputStream o = create(delegate);
+            try {
+                // any of these is permitted to flush
+                o.write(new byte[] { 8, 6, 7, 5 });
+                o.write(new byte[] { 3, 0, 9 });
+                o.close();
+                assertTrue(delegate.flushed);
+                fail("flush exception ignored");
+            } catch (IOException expected) {
+                assertEquals("Flush failed", expected.getMessage());
+            }
+
+            try {
+                o.write(new byte[] { 4, 4, 5 });
+                fail("expected already closed exception");
+            } catch (IOException expected) {
+            }
+        }
+
+        public void wrapperTestCloseThrows() throws Exception {
+            FailOnCloseOutputStream delegate = new FailOnCloseOutputStream();
+            OutputStream o = create(delegate);
+            try {
+                o.close();
+                assertTrue(delegate.closed);
+                fail("close exception ignored");
+            } catch (IOException expected) {
+                assertEquals("Close failed", expected.getMessage());
+            }
+        }
+
+        public void wrapperTestCloseThrowsSuppressed() throws Exception {
+            FailOnCloseOutputStream delegate = new FailOnCloseOutputStream();
+            OutputStream o = create(delegate);
+            o.close();
+            assertTrue(delegate.closed);
+        }
+
+        // adding a new test? Don't forget to update createTests().
+    }
+
+    private static class ClosableByteArrayOutputStream extends OutputStream {
+        private final ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
+        private boolean closed = false;
+
+        @Override
+        public void close() throws IOException {
+            closed = true;
+        }
+
+        @Override
+        public void write(int oneByte) throws IOException {
+            if (closed) {
+                throw new IOException();
+            }
+            bytesOut.write(oneByte);
+        }
+    }
+
+    private static class FailOnFlushOutputStream extends OutputStream {
+        boolean flushed = false;
+        boolean closed = false;
+
+        @Override
+        public void write(int oneByte) throws IOException {
+            if (closed) {
+                throw new IOException("Already closed");
+            }
+        }
+
+        @Override
+        public void close() throws IOException {
+            closed = true;
+            flush();
+        }
+
+        @Override
+        public void flush() throws IOException {
+            if (!flushed) {
+                flushed = true;
+                throw new IOException("Flush failed");
+            }
+        }
+    }
+
+    private static class FailOnCloseOutputStream extends ByteArrayOutputStream {
+        boolean closed = false;
+
+        @Override
+        public void close() throws IOException {
+            closed = true;
+            throw new IOException("Close failed");
+        }
+    }
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/AbstractService.java b/support/src/test/java/tests/resources/ServiceLoader/AbstractService.java
new file mode 100644
index 0000000..bff9660
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/AbstractService.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 tests.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public abstract class AbstractService {
+    /**
+     * @return name of the class
+     */
+    public abstract String myNameIs();
+
+    /**
+     * test of internal interface
+     */
+    public interface InternalService {
+        /**
+         * @return name
+         */
+        public String myInternalNameIs();
+    }
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/Service.java b/support/src/test/java/tests/resources/ServiceLoader/Service.java
new file mode 100644
index 0000000..c36fdb3
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/Service.java
@@ -0,0 +1,28 @@
+/*
+ *  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.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public interface Service {
+    /**
+     * @return name of the class
+     */
+    public String myNameIs();
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/ServiceDuplicateIn2File.java b/support/src/test/java/tests/resources/ServiceLoader/ServiceDuplicateIn2File.java
new file mode 100644
index 0000000..b09bc81
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/ServiceDuplicateIn2File.java
@@ -0,0 +1,28 @@
+/*
+ *  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.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public interface ServiceDuplicateIn2File {
+    /**
+     * @return name of the class
+     */
+    public String myNameIs();
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/ServiceFinalClass.java b/support/src/test/java/tests/resources/ServiceLoader/ServiceFinalClass.java
new file mode 100644
index 0000000..767f016
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/ServiceFinalClass.java
@@ -0,0 +1,31 @@
+/*
+ *  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.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public final class ServiceFinalClass {
+    /**
+     * @return name of the class
+     */
+    @SuppressWarnings("nls")
+    public String myNameIs() {
+        return "ServiceFinalClass";
+    }
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/ServiceForAllCommentTest.java b/support/src/test/java/tests/resources/ServiceLoader/ServiceForAllCommentTest.java
new file mode 100644
index 0000000..e982b3f
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/ServiceForAllCommentTest.java
@@ -0,0 +1,28 @@
+/*
+ *  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.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public interface ServiceForAllCommentTest {
+    /**
+     * @return name of the class
+     */
+    public String myNameIs();
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/ServiceForEmptyTest.java b/support/src/test/java/tests/resources/ServiceLoader/ServiceForEmptyTest.java
new file mode 100644
index 0000000..d777293
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/ServiceForEmptyTest.java
@@ -0,0 +1,28 @@
+/*
+ *  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.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public interface ServiceForEmptyTest {
+    /**
+     * @return name of the class
+     */
+    public String myNameIs();
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/ServiceForIllegalNameTest.java b/support/src/test/java/tests/resources/ServiceLoader/ServiceForIllegalNameTest.java
new file mode 100644
index 0000000..4e9cde7
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/ServiceForIllegalNameTest.java
@@ -0,0 +1,28 @@
+/*
+ *  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.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public interface ServiceForIllegalNameTest {
+    /**
+     * @return name of the class
+     */
+    public String myNameIs();
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/ServiceForWrongNameTest.java b/support/src/test/java/tests/resources/ServiceLoader/ServiceForWrongNameTest.java
new file mode 100644
index 0000000..910faec
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/ServiceForWrongNameTest.java
@@ -0,0 +1,28 @@
+/*
+ *  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.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public interface ServiceForWrongNameTest {
+    /**
+     * @return name of the class
+     */
+    public String myNameIs();
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/ServiceIn2File.java b/support/src/test/java/tests/resources/ServiceLoader/ServiceIn2File.java
new file mode 100644
index 0000000..49f19d7
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/ServiceIn2File.java
@@ -0,0 +1,28 @@
+/*
+ *  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.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public interface ServiceIn2File {
+    /**
+     * @return name of the class
+     */
+    public String myNameIs();
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/ServiceIn2FileWithEmptyConfig.java b/support/src/test/java/tests/resources/ServiceLoader/ServiceIn2FileWithEmptyConfig.java
new file mode 100644
index 0000000..ad63606
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/ServiceIn2FileWithEmptyConfig.java
@@ -0,0 +1,28 @@
+/*
+ *  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.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public interface ServiceIn2FileWithEmptyConfig {
+    /**
+     * @return name of the class
+     */
+    public String myNameIs();
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/ServiceMoreThanOne.java b/support/src/test/java/tests/resources/ServiceLoader/ServiceMoreThanOne.java
new file mode 100644
index 0000000..895972e
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/ServiceMoreThanOne.java
@@ -0,0 +1,31 @@
+/*
+ *  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.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public class ServiceMoreThanOne {
+    /**
+     * @return name of the class
+     */
+    @SuppressWarnings("nls")
+    public String myNameIs() {
+        return "ServiceMoreThanOne";
+    }
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/ServiceWithDuplicateSons.java b/support/src/test/java/tests/resources/ServiceLoader/ServiceWithDuplicateSons.java
new file mode 100644
index 0000000..a299931
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/ServiceWithDuplicateSons.java
@@ -0,0 +1,28 @@
+/*
+ *  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.resources.ServiceLoader;
+
+/**
+ * A class just for test cases of java.util.ServiceLoader.
+ */
+public interface ServiceWithDuplicateSons {
+    /**
+     * @return name of the class
+     */
+    public String myNameIs();
+}
diff --git a/support/src/test/java/tests/resources/ServiceLoader/hyts_services.jar b/support/src/test/java/tests/resources/ServiceLoader/hyts_services.jar
new file mode 100644
index 0000000..12503a6
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/hyts_services.jar
Binary files differ
diff --git a/support/src/test/java/tests/resources/ServiceLoader/hyts_services2.jar b/support/src/test/java/tests/resources/ServiceLoader/hyts_services2.jar
new file mode 100644
index 0000000..a7a754a
--- /dev/null
+++ b/support/src/test/java/tests/resources/ServiceLoader/hyts_services2.jar
Binary files differ
diff --git a/support/src/test/java/tests/support/Streams.java b/support/src/test/java/tests/support/Streams.java
new file mode 100644
index 0000000..f9f5c77
--- /dev/null
+++ b/support/src/test/java/tests/support/Streams.java
@@ -0,0 +1,58 @@
+/*
+ *  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.support;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringWriter;
+
+/**
+ * Utility methods for working with byte and character streams.
+ */
+public class Streams {
+    private Streams() {
+    }
+
+    /**
+     * Drains the stream into a byte array and returns the result.
+     */
+    public static byte[] streamToBytes(InputStream source) throws IOException {
+        byte[] buffer = new byte[1024];
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        int count;
+        while ((count = source.read(buffer)) != -1) {
+            out.write(buffer, 0, count);
+        }
+        return out.toByteArray();
+    }
+
+    /**
+     * Drains the stream into a string and returns the result.
+     */
+    public static String streamToString(Reader fileReader) throws IOException {
+        char[] buffer = new char[1024];
+        StringWriter out = new StringWriter();
+        int count;
+        while ((count = fileReader.read(buffer)) != -1) {
+            out.write(buffer, 0, count);
+        }
+        return out.toString();
+    }
+}
diff --git a/support/src/test/java/tests/support/Support_TimeZone.java b/support/src/test/java/tests/support/Support_TimeZone.java
new file mode 100644
index 0000000..e2c3e65
--- /dev/null
+++ b/support/src/test/java/tests/support/Support_TimeZone.java
@@ -0,0 +1,82 @@
+/* 
+ * 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.support;
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+/**
+ * Sample java.util.TimeZone subclass to test getDSTSavings() and getOffset(long)
+ * APIs
+ */
+public class Support_TimeZone extends TimeZone {
+    private static final long serialVersionUID = 1L;
+
+    int rawOffset;
+
+    boolean useDaylightTime;
+
+    public Support_TimeZone(int rawOffset, boolean useDaylightTime) {
+        this.rawOffset = rawOffset;
+        this.useDaylightTime = useDaylightTime;
+    }
+
+    @Override
+    public int getRawOffset() {
+        return rawOffset;
+    }
+
+    /**
+     * let's assume this timezone has daylight savings from the 4th month till
+     * the 10th month of the year to ame things simple.
+     */
+    @Override
+    public boolean inDaylightTime(java.util.Date p1) {
+        if (!useDaylightTime) {
+            return false;
+        }
+        GregorianCalendar cal = new GregorianCalendar();
+        cal.setTime(p1);
+        int month = cal.get(Calendar.MONTH);
+
+        if (month > 4 && month < 10) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean useDaylightTime() {
+        return useDaylightTime;
+    }
+
+    /*
+      * return 0 to keep it simple, since this subclass is not used to test this
+      * method..
+      */
+    @Override
+    public int getOffset(int p1, int p2, int p3, int p4, int p5, int p6) {
+        return 0;
+    }
+
+    @Override
+    public void setRawOffset(int p1) {
+        rawOffset = p1;
+    }
+}
diff --git a/support/src/test/java/tests/support/resource/Support_Resources.java b/support/src/test/java/tests/support/resource/Support_Resources.java
index ddcb881..82143ac 100644
--- a/support/src/test/java/tests/support/resource/Support_Resources.java
+++ b/support/src/test/java/tests/support/resource/Support_Resources.java
@@ -196,4 +196,18 @@
         xml.close();
         return f;
     }
+
+    public static void copyLocalFileTo(File dest, InputStream in) throws IOException {
+        if (!dest.exists()) {
+            FileOutputStream out = new FileOutputStream(dest);
+            int result;
+            byte[] buf = new byte[4096];
+            while ((result = in.read(buf)) != -1) {
+                out.write(buf, 0, result);
+            }
+            in.close();
+            out.close();
+            dest.deleteOnExit();
+        }
+    }
 }
diff --git a/support/src/test/java/tests/util/SerializationTester.java b/support/src/test/java/tests/util/SerializationTester.java
new file mode 100644
index 0000000..93bff70
--- /dev/null
+++ b/support/src/test/java/tests/util/SerializationTester.java
@@ -0,0 +1,231 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.net.URL;
+
+/**
+ * This class simplifies the serialization test.
+ */
+public class SerializationTester {
+
+    /*
+      * --------------------------------------------------------------------
+      * Class variables
+      * --------------------------------------------------------------------
+      */
+
+    // the last deserialized object
+    private static Object lastOutput = null;
+
+    /*
+      * -------------------------------------------------------------------
+      * Constructors
+      * -------------------------------------------------------------------
+      */
+
+    private SerializationTester() {
+
+    }
+
+    /*
+      * -------------------------------------------------------------------
+      * Methods
+      * -------------------------------------------------------------------
+      */
+
+    /**
+     * Serialize an object and then deserialize it.
+     *
+     * @param inputObject the input object
+     * @return the deserialized object
+     */
+    public static Object getDeserilizedObject(Object inputObject)
+            throws IOException, ClassNotFoundException {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(bos);
+        oos.writeObject(inputObject);
+        oos.close();
+
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        ObjectInputStream ois = new ObjectInputStream(bis);
+        Object outputObject = ois.readObject();
+        lastOutput = outputObject;
+        ois.close();
+        return outputObject;
+    }
+
+    /**
+     * Tests the serialization and deserialization of const objects.
+     *
+     * @param inputObject A const object
+     * @return true if the deserialized object is the same as the input object,
+     *         otherwise false
+     * @throws Exception If any occurs.
+     */
+    public static boolean assertSame(Object inputObject) throws Exception {
+        return inputObject == getDeserilizedObject(inputObject);
+    }
+
+    /**
+     * Tests the serialization and deserialization of instance objects.
+     *
+     * @param inputObject An object
+     * @return true if the deserialized object is equal to the input object,
+     *         otherwise false
+     * @throws Exception If any occurs.
+     */
+    public static boolean assertEquals(Object inputObject) throws Exception {
+        return inputObject.equals(getDeserilizedObject(inputObject));
+    }
+
+    /**
+     * Tests the serialization compatibility with reference const objects.
+     *
+     * @param obj      the object to be checked
+     * @param fileName the serialization output file generated by reference
+     * @return true if compatible, otherwise false
+     * @throws Exception If any occurs.
+     */
+    public static boolean assertCompabilitySame(Object obj, String fileName)
+            throws Exception {
+        return obj == readObject(obj, fileName);
+    }
+
+    /**
+     * Tests the serialization compatibility with reference for instance
+     * objects.
+     *
+     * @param obj      the object to be checked
+     * @param fileName the serialization output file generated by reference
+     * @return true if compatible, otherwise false
+     * @throws Exception If any occurs.
+     */
+    public static boolean assertCompabilityEquals(Object obj, String fileName)
+            throws Exception {
+        return obj.equals(readObject(obj, fileName));
+    }
+
+    /**
+     * Deserialize an object from a file.
+     *
+     * @param obj      the object to be serialized if no serialization file is found
+     * @param fileName the serialization file
+     * @return the deserialized object
+     * @throws Exception If any occurs.
+     */
+    public static Object readObject(Object obj, String fileName)
+            throws Exception {
+        InputStream input = null;
+        ObjectInputStream oinput = null;
+        URL url = SerializationTester.class.getClassLoader().getResource(
+                fileName);
+        if (null == url) {
+            // serialization file does not exist, create one in the current dir
+            writeObject(obj, new File(fileName).getName());
+            throw new Error(
+                    "Serialization file does not exist, created in the current dir.");
+        }
+        input = url.openStream();
+        try {
+            oinput = new ObjectInputStream(input);
+            Object newObj = oinput.readObject();
+            return newObj;
+        } finally {
+            try {
+                if (null != oinput) {
+                    oinput.close();
+                }
+            } catch (Exception e) {
+                // ignore
+            }
+            try {
+                if (null != input) {
+                    input.close();
+                }
+            } catch (Exception e) {
+                // ignore
+            }
+        }
+    }
+
+    /*
+      * Creates a serialization output.
+      *
+      * @param obj the object to be serialized @param fileName the output file
+      * @throws Exception If any occurs.
+      */
+    public static void writeObject(Object obj, String fileName)
+            throws Exception {
+        // String path = SerializationTester.class.getResource(".").getPath();
+        // if (path.endsWith(".")) {
+        // path = path.substring(0, path.length() - 1);
+        // }
+        // if (!path.endsWith("/")) {
+        // path += "/";
+        // }
+        // path += fileName;
+        // System.out.println(path);
+        OutputStream output = null;
+        ObjectOutputStream ooutput = null;
+        try {
+            output = new FileOutputStream(fileName);
+            ooutput = new ObjectOutputStream(output);
+            ooutput.writeObject(obj);
+        } finally {
+            try {
+                if (null != ooutput) {
+                    ooutput.close();
+                }
+            } catch (Exception e) {
+                // ignore
+            }
+            try {
+                if (null != output) {
+                    output.close();
+                }
+            } catch (Exception e) {
+                // ignore
+            }
+        }
+    }
+
+    /**
+     * Gets the last deserialized object.
+     *
+     * @return the last deserialized object
+     */
+    public static Object getLastOutput() {
+        return lastOutput;
+    }
+
+    /*
+      * For test purpose.
+      */
+    public static void main(String[] args) {
+    }
+}