Merge "Fix UnmodifiableEntrySet.toArray() ordering"
diff --git a/NOTICE b/NOTICE
index 818f6c5..951e506 100644
--- a/NOTICE
+++ b/NOTICE
@@ -32,7 +32,7 @@
    ==  NOTICE file for the ICU License.                                   ==
    =========================================================================
 
-Copyright (c) 1995-2009 International Business Machines Corporation and others
+Copyright (c) 1995-2014 International Business Machines Corporation and others
 
 All rights reserved.
 
@@ -66,250 +66,6 @@
 
 
    =========================================================================
-   ==  NOTICE file for the JUnit License.                                 ==
-   =========================================================================
-
-Common Public License - v 1.0
-
-THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON
-PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF
-THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
-
-1. DEFINITIONS
-
-"Contribution" means:
-
-      a) in the case of the initial Contributor, the initial code and
-         documentation distributed under this Agreement, and
-      b) in the case of each subsequent Contributor:
-
-      i) changes to the Program, and
-
-      ii) additions to the Program;
-
-      where such changes and/or additions to the Program originate
-      from and are distributed by that particular Contributor. A
-      Contribution 'originates' from a Contributor if it was added to
-      the Program by such Contributor itself or anyone acting on such
-      Contributor's behalf. Contributions do not include additions to
-      the Program which: (i) are separate modules of software
-      distributed in conjunction with the Program under their own
-      license agreement, and (ii) are not derivative works of the
-      Program.
-
-"Contributor" means any person or entity that distributes the Program.
-
-"Licensed Patents " mean patent claims licensable by a Contributor
-which are necessarily infringed by the use or sale of its Contribution
-alone or when combined with the Program.
-
-"Program" means the Contributions distributed in accordance with this
-Agreement.
-
-"Recipient" means anyone who receives the Program under this
-Agreement, including all Contributors.
-
-2. GRANT OF RIGHTS
-
-      a) Subject to the terms of this Agreement, each Contributor
-      hereby grants Recipient a non-exclusive, worldwide, royalty-free
-      copyright license to reproduce, prepare derivative works of,
-      publicly display, publicly perform, distribute and sublicense
-      the Contribution of such Contributor, if any, and such
-      derivative works, in source code and object code form.
-
-      b) Subject to the terms of this Agreement, each Contributor
-      hereby grants Recipient a non-exclusive, worldwide, royalty-free
-      patent license under Licensed Patents to make, use, sell, offer
-      to sell, import and otherwise transfer the Contribution of such
-      Contributor, if any, in source code and object code form. This
-      patent license shall apply to the combination of the
-      Contribution and the Program if, at the time the Contribution is
-      added by the Contributor, such addition of the Contribution
-      causes such combination to be covered by the Licensed Patents.
-      The patent license shall not apply to any other combinations
-      which include the Contribution. No hardware per se is licensed
-      hereunder.
-
-      c) Recipient understands that although each Contributor grants
-      the licenses to its Contributions set forth herein, no
-      assurances are provided by any Contributor that the Program does
-      not infringe the patent or other intellectual property rights of
-      any other entity. Each Contributor disclaims any liability to
-      Recipient for claims brought by any other entity based on
-      infringement of intellectual property rights or otherwise. As a
-      condition to exercising the rights and licenses granted
-      hereunder, each Recipient hereby assumes sole responsibility to
-      secure any other intellectual property rights needed, if any.
-      For example, if a third party patent license is required to
-      allow Recipient to distribute the Program, it is Recipient's
-      responsibility to acquire that license before distributing the
-      Program.
-
-      d) Each Contributor represents that to its knowledge it has
-      sufficient copyright rights in its Contribution, if any, to
-      grant the copyright license set forth in this Agreement.
-
-3. REQUIREMENTS
-
-A Contributor may choose to distribute the Program in object code form
-under its own license agreement, provided that:
-
-      a) it complies with the terms and conditions of this Agreement; and
-
-      b) its license agreement:
-
-      i) effectively disclaims on behalf of all Contributors all
-      warranties and conditions, express and implied, including
-      warranties or conditions of title and non-infringement, and
-      implied warranties or conditions of merchantability and fitness
-      for a particular purpose;
-
-      ii) effectively excludes on behalf of all Contributors all
-      liability for damages, including direct, indirect, special,
-      incidental and consequential damages, such as lost profits;
-
-      iii) states that any provisions which differ from this Agreement
-      are offered by that Contributor alone and not by any other
-      party; and
-
-      iv) states that source code for the Program is available from
-      such Contributor, and informs licensees how to obtain it in a
-      reasonable manner on or through a medium customarily used for
-      software exchange.
-
-When the Program is made available in source code form:
-
-      a) it must be made available under this Agreement; and 
-
-      b) a copy of this Agreement must be included with each copy of
-      the Program.
-
-Contributors may not remove or alter any copyright notices contained
-within the Program.
-
-Each Contributor must identify itself as the originator of its
-Contribution, if any, in a manner that reasonably allows subsequent
-Recipients to identify the originator of the Contribution.
-
-4. COMMERCIAL DISTRIBUTION
-
-Commercial distributors of software may accept certain
-responsibilities with respect to end users, business partners and the
-like. While this license is intended to facilitate the commercial use
-of the Program, the Contributor who includes the Program in a
-commercial product offering should do so in a manner which does not
-create potential liability for other Contributors. Therefore, if a
-Contributor includes the Program in a commercial product offering,
-such Contributor ("Commercial Contributor") hereby agrees to defend
-and indemnify every other Contributor ("Indemnified Contributor")
-against any losses, damages and costs (collectively "Losses") arising
-from claims, lawsuits and other legal actions brought by a third party
-against the Indemnified Contributor to the extent caused by the acts
-or omissions of such Commercial Contributor in connection with its
-distribution of the Program in a commercial product offering. The
-obligations in this section do not apply to any claims or Losses
-relating to any actual or alleged intellectual property infringement.
-In order to qualify, an Indemnified Contributor must: a) promptly
-notify the Commercial Contributor in writing of such claim, and b)
-allow the Commercial Contributor to control, and cooperate with the
-Commercial Contributor in, the defense and any related settlement
-negotiations. The Indemnified Contributor may participate in any such
-claim at its own expense.
-
-For example, a Contributor might include the Program in a commercial
-product offering, Product X. That Contributor is then a Commercial
-Contributor. If that Commercial Contributor then makes performance
-claims, or offers warranties related to Product X, those performance
-claims and warranties are such Commercial Contributor's responsibility
-alone. Under this section, the Commercial Contributor would have to
-defend claims against the other Contributors related to those
-performance claims and warranties, and if a court requires any other
-Contributor to pay any damages as a result, the Commercial Contributor
-must pay those damages.
-
-5. NO WARRANTY
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
-PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
-WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
-OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
-responsible for determining the appropriateness of using and
-distributing the Program and assumes all risks associated with its
-exercise of rights under this Agreement, including but not limited to
-the risks and costs of program errors, compliance with applicable
-laws, damage to or loss of data, programs or equipment, and
-unavailability or interruption of operations.
-
-6. DISCLAIMER OF LIABILITY
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR
-ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
-WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
-DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
-HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-7. GENERAL
-
-If any provision of this Agreement is invalid or unenforceable under
-applicable law, it shall not affect the validity or enforceability of
-the remainder of the terms of this Agreement, and without further
-action by the parties hereto, such provision shall be reformed to the
-minimum extent necessary to make such provision valid and enforceable.
-
-If Recipient institutes patent litigation against a Contributor with
-respect to a patent applicable to software (including a cross-claim or
-counterclaim in a lawsuit), then any patent licenses granted by that
-Contributor to such Recipient under this Agreement shall terminate as
-of the date such litigation is filed. In addition, if Recipient
-institutes patent litigation against any entity (including a
-cross-claim or counterclaim in a lawsuit) alleging that the Program
-itself (excluding combinations of the Program with other software or
-hardware) infringes such Recipient's patent(s), then such Recipient's
-rights granted under Section 2(b) shall terminate as of the date such
-litigation is filed.
-
-All Recipient's rights under this Agreement shall terminate if it
-fails to comply with any of the material terms or conditions of this
-Agreement and does not cure such failure in a reasonable period of
-time after becoming aware of such noncompliance. If all Recipient's
-rights under this Agreement terminate, Recipient agrees to cease use
-and distribution of the Program as soon as reasonably practicable.
-However, Recipient's obligations under this Agreement and any licenses
-granted by Recipient relating to the Program shall continue and
-survive.
-
-Everyone is permitted to copy and distribute copies of this Agreement,
-but in order to avoid inconsistency the Agreement is copyrighted and
-may only be modified in the following manner. The Agreement Steward
-reserves the right to publish new versions (including revisions) of
-this Agreement from time to time. No one other than the Agreement
-Steward has the right to modify this Agreement. IBM is the initial
-Agreement Steward. IBM may assign the responsibility to serve as the
-Agreement Steward to a suitable separate entity. Each new version of
-the Agreement will be given a distinguishing version number. The
-Program (including Contributions) may always be distributed subject to
-the version of the Agreement under which it was received. In addition,
-after a new version of the Agreement is published, Contributor may
-elect to distribute the Program (including its Contributions) under
-the new version. Except as expressly stated in Sections 2(a) and 2(b)
-above, Recipient receives no rights or licenses to the intellectual
-property of any Contributor under this Agreement, whether expressly,
-by implication, estoppel or otherwise. All rights in the Program not
-expressly granted under this Agreement are reserved.
-
-This Agreement is governed by the laws of the State of New York and
-the intellectual property laws of the United States of America. No
-party to this Agreement will bring a legal action under this Agreement
-more than one year after the cause of action arose. Each party waives
-its rights to a jury trial in any resulting litigation.
-
-
-   =========================================================================
    ==  NOTICE file for the KXML License.                                  ==
    =========================================================================
 
@@ -336,38 +92,6 @@
 
 
    =========================================================================
-   ==  NOTICE file for the SQLite Java Wrapper License.                   ==
-   =========================================================================
-
-This software is copyrighted by Christian Werner <chw@ch-werner.de>
-and others. The following terms apply to all files associated with the
-software unless explicitly disclaimed in individual files.
-
-The authors hereby grant permission to use, copy, modify, distribute,
-and license this software and its documentation for any purpose, provided
-that existing copyright notices are retained in all copies and that this
-notice is included verbatim in any distributions. No written agreement,
-license, or royalty fee is required for any of the authorized uses.
-Modifications to this software may be copyrighted by their authors
-and need not follow the licensing terms described here, provided that
-the new terms are clearly indicated on the first page of each file where
-they apply.
-
-IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
-FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
-ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
-DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
-THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
-INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
-IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
-NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
-MODIFICATIONS.
-
-
-   =========================================================================
    ==  NOTICE file for the W3C License.                                   ==
    =========================================================================
 
diff --git a/NativeCode.mk b/NativeCode.mk
index 98e87b0..12e8114 100644
--- a/NativeCode.mk
+++ b/NativeCode.mk
@@ -127,6 +127,7 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/NativeCode.mk
 LOCAL_SHARED_LIBRARIES += $(core_shared_libraries) libexpat-host libicuuc-host libicui18n-host libcrypto-host libz-host
 LOCAL_STATIC_LIBRARIES += $(core_static_libraries) libziparchive-host libutils
+LOCAL_MULTILIB := both
 include $(BUILD_HOST_SHARED_LIBRARY)
 
 ifeq ($(LIBCORE_SKIP_TESTS),)
diff --git a/benchmarks/src/benchmarks/ReferenceGetBenchmark.java b/benchmarks/src/benchmarks/ReferenceGetBenchmark.java
new file mode 100644
index 0000000..80142a1
--- /dev/null
+++ b/benchmarks/src/benchmarks/ReferenceGetBenchmark.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package benchmarks;
+
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.*;
+
+public class ReferenceGetBenchmark extends SimpleBenchmark {
+    @Param boolean intrinsicDisabled;
+
+    private Object obj = "str";
+
+    protected void setUp() throws Exception {
+        Field intrinsicDisabledField = Reference.class.getDeclaredField("disableIntrinsic");
+        intrinsicDisabledField.setAccessible(true);
+        intrinsicDisabledField.setBoolean(null, intrinsicDisabled);
+    }
+
+    public void timeSoftReferenceGet(int reps) throws Exception {
+        Reference soft = new SoftReference(obj);
+        for (int i = 0; i < reps; i++) {
+            Object o = soft.get();
+        }
+    }
+
+    public void timeWeakReferenceGet(int reps) throws Exception {
+        Reference weak = new WeakReference(obj);
+        for (int i = 0; i < reps; i++) {
+            Object o = weak.get();
+        }
+    }
+
+    public void timeNonPreservedWeakReferenceGet(int reps) throws Exception {
+        Reference weak = new WeakReference(obj);
+        obj = null;
+        Runtime.getRuntime().gc();
+        for (int i = 0; i < reps; i++) {
+            Object o = weak.get();
+        }
+    }
+}
diff --git a/benchmarks/src/benchmarks/SystemArrayCopyBenchmark.java b/benchmarks/src/benchmarks/SystemArrayCopyBenchmark.java
index c22e819..5095ee1 100644
--- a/benchmarks/src/benchmarks/SystemArrayCopyBenchmark.java
+++ b/benchmarks/src/benchmarks/SystemArrayCopyBenchmark.java
@@ -24,17 +24,77 @@
           "2048", "4096", "8192", "16384", "32768", "65536", "131072", "262144"})
   int arrayLength;
 
-  // This copies a char array indirectly via String.getChars() as the
-  // System.arraycopy() call site optimization currently works within
-  // the core libraries only. Add direct System.arraycopy() benchmarks
-  // (including ones for other primitive types) later once this
-  // limitation goes away.
-  public void timeStringCharArrayCopy(int reps) {
+  // Provides benchmarking for different types of arrays using the arraycopy function.
+
+  public void timeSystemCharArrayCopy(int reps) {
     final int len = arrayLength;
+    char[] src = new char[len];
     char[] dst = new char[len];
-    String str = new String(new char[len]);
     for (int rep = 0; rep < reps; ++rep) {
-      str.getChars(0, len, dst, 0);
+      System.arraycopy(src, 0, dst, 0, len);
+    }
+  }
+
+  public void timeSystemByteArrayCopy(int reps) {
+    final int len = arrayLength;
+    byte[] src = new byte[len];
+    byte[] dst = new byte[len];
+    for (int rep = 0; rep < reps; ++rep) {
+      System.arraycopy(src, 0, dst, 0, len);
+    }
+  }
+
+  public void timeSystemShortArrayCopy(int reps) {
+    final int len = arrayLength;
+    short[] src = new short[len];
+    short[] dst = new short[len];
+    for (int rep = 0; rep < reps; ++rep) {
+      System.arraycopy(src, 0, dst, 0, len);
+    }
+  }
+
+  public void timeSystemIntArrayCopy(int reps) {
+    final int len = arrayLength;
+    int[] src = new int[len];
+    int[] dst = new int[len];
+    for (int rep = 0; rep < reps; ++rep) {
+      System.arraycopy(src, 0, dst, 0, len);
+    }
+  }
+
+  public void timeSystemLongArrayCopy(int reps) {
+    final int len = arrayLength;
+    long[] src = new long[len];
+    long[] dst = new long[len];
+    for (int rep = 0; rep < reps; ++rep) {
+      System.arraycopy(src, 0, dst, 0, len);
+    }
+  }
+
+  public void timeSystemFloatArrayCopy(int reps) {
+    final int len = arrayLength;
+    float[] src = new float[len];
+    float[] dst = new float[len];
+    for (int rep = 0; rep < reps; ++rep) {
+      System.arraycopy(src, 0, dst, 0, len);
+    }
+  }
+
+  public void timeSystemDoubleArrayCopy(int reps) {
+    final int len = arrayLength;
+    double[] src = new double[len];
+    double[] dst = new double[len];
+    for (int rep = 0; rep < reps; ++rep) {
+      System.arraycopy(src, 0, dst, 0, len);
+    }
+  }
+
+  public void timeSystemBooleanArrayCopy(int reps) {
+    final int len = arrayLength;
+    boolean[] src = new boolean[len];
+    boolean[] dst = new boolean[len];
+    for (int rep = 0; rep < reps; ++rep) {
+      System.arraycopy(src, 0, dst, 0, len);
     }
   }
 }
diff --git a/benchmarks/src/benchmarks/regression/SSLSocketFactoryBenchmark.java b/benchmarks/src/benchmarks/regression/SSLSocketFactoryBenchmark.java
new file mode 100644
index 0000000..d0448d6
--- /dev/null
+++ b/benchmarks/src/benchmarks/regression/SSLSocketFactoryBenchmark.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package benchmarks.regression;
+
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+import javax.net.ssl.SSLSocketFactory;
+
+public class SSLSocketFactoryBenchmark extends SimpleBenchmark {
+    public void time(int reps) throws Exception {
+        for (int i = 0; i < reps; ++i) {
+            SSLSocketFactory.getDefault();
+        }
+    }
+}
diff --git a/dex/src/main/java/com/android/dex/DexException.java b/dex/src/main/java/com/android/dex/DexException.java
index a30a46f..ee0af18 100644
--- a/dex/src/main/java/com/android/dex/DexException.java
+++ b/dex/src/main/java/com/android/dex/DexException.java
@@ -22,7 +22,7 @@
  * Thrown when there's a format problem reading, writing, or generally
  * processing a dex file.
  */
-public final class DexException extends ExceptionWithContext {
+public class DexException extends ExceptionWithContext {
     public DexException(String message) {
         super(message);
     }
diff --git a/dex/src/main/java/com/android/dex/DexIndexOverflowException.java b/dex/src/main/java/com/android/dex/DexIndexOverflowException.java
new file mode 100644
index 0000000..3226207
--- /dev/null
+++ b/dex/src/main/java/com/android/dex/DexIndexOverflowException.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.dex;
+
+/**
+ * Thrown when there's an index overflow writing a dex file.
+ */
+public final class DexIndexOverflowException extends DexException {
+    public DexIndexOverflowException(String message) {
+        super(message);
+    }
+
+    public DexIndexOverflowException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/internal/net/www/protocol/file/FileURLConnectionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/internal/net/www/protocol/file/FileURLConnectionTest.java
index 1f4ad1f..d6f2c01 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/internal/net/www/protocol/file/FileURLConnectionTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/internal/net/www/protocol/file/FileURLConnectionTest.java
@@ -112,8 +112,6 @@
         assertEquals(conn.getContentType(), conn.getHeaderField("content-type"));
         assertEquals(Integer.toString(conn.getContentLength()),
                 conn.getHeaderField("content-length"));
-        assertEquals(Long.toString(conn.getContentLengthLong()),
-                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"));
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ConsoleTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ConsoleTest.java
index ec423e9..99becf9 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ConsoleTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ConsoleTest.java
@@ -95,12 +95,6 @@
         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()}
      */
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/HttpCookieTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/HttpCookieTest.java
index 306e697..d1cf18f 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/HttpCookieTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/HttpCookieTest.java
@@ -234,16 +234,6 @@
         assertFalse(cookie.getSecure());
     }
 
-    public void test_Is_SetHttpOnly() {
-        HttpCookie cookie = new HttpCookie("testName", "value");
-        assertFalse(cookie.isHttpOnly());
-
-        cookie.setHttpOnly(true);
-        assertTrue(cookie.isHttpOnly());
-        cookie.setHttpOnly(false);
-        assertFalse(cookie.isHttpOnly());
-    }
-
     /**
      * java.net.HttpCookie#getPath(), setPath(String)
      * @since 1.6
@@ -817,24 +807,20 @@
         // Default is !httpOnly.
         List<HttpCookie> list = HttpCookie.parse("Set-Cookie: SID=31d4d96e407aad42");
         HttpCookie cookie = list.get(0);
-        assertFalse(cookie.isHttpOnly());
 
         // Well formed, simple.
         list = HttpCookie.parse("Set-Cookie: SID=31d4d96e407aad42; HttpOnly");
         cookie = list.get(0);
-        assertTrue(cookie.isHttpOnly());
 
         // Well formed, other attributes present.
         list = HttpCookie.parse("Set-Cookie: SID=31d4d96e407aad42; Path=/; Secure; HttpOnly");
         cookie = list.get(0);
-        assertTrue(cookie.isHttpOnly());
         assertTrue(cookie.getSecure());
         assertEquals("/", cookie.getPath());
 
         // Mangled spacing, casing and attributes that have an (ignored) value.
         list = HttpCookie.parse("Set-Cookie:SID=31d4d96e407aad42;Path=/;secure=false;httponly=false");
         cookie = list.get(0);
-        assertTrue(cookie.isHttpOnly());
         assertTrue(cookie.getSecure());
         assertEquals("/", cookie.getPath());
     }
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/DatagramChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/DatagramChannelTest.java
index 731e907..4469e01 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/DatagramChannelTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/DatagramChannelTest.java
@@ -25,7 +25,6 @@
 import java.net.SocketAddress;
 import java.net.SocketException;
 import java.nio.ByteBuffer;
-import java.nio.channels.AlreadyBoundException;
 import java.nio.channels.AsynchronousCloseException;
 import java.nio.channels.ClosedChannelException;
 import java.nio.channels.DatagramChannel;
@@ -72,11 +71,11 @@
         channel1 = DatagramChannel.open();
         channel2 = DatagramChannel.open();
 
-        channel1.bind(new InetSocketAddress(Inet6Address.LOOPBACK, 0));
-        channel2.bind(new InetSocketAddress(Inet6Address.LOOPBACK, 0));
+        channel1.socket().bind(new InetSocketAddress(Inet6Address.LOOPBACK, 0));
+        channel2.socket().bind(new InetSocketAddress(Inet6Address.LOOPBACK, 0));
 
-        channel1Address = (InetSocketAddress) channel1.getLocalAddress();
-        channel2Address = (InetSocketAddress) channel2.getLocalAddress();
+        channel1Address = (InetSocketAddress) channel1.socket().getLocalSocketAddress();
+        channel2Address = (InetSocketAddress) channel2.socket().getLocalSocketAddress();
 
         this.datagramSocket1 = new DatagramSocket(0, Inet6Address.LOOPBACK);
         this.datagramSocket2 = new DatagramSocket(0, Inet6Address.LOOPBACK);
@@ -1943,7 +1942,7 @@
             sourceArray[i] = (byte) i;
         }
 
-        this.channel1.connect(channel1.getLocalAddress());
+        this.channel1.connect(channel1.socket().getLocalSocketAddress());
         this.channel2.connect(datagramSocket1Address); // the different addr
 
         // write
@@ -1973,7 +1972,7 @@
         assertEquals(CAPACITY_NORMAL, dc.write(sourceBuf));
 
         // Connect channel2 after data has been written.
-        channel2.connect(dc.getLocalAddress());
+        channel2.connect(dc.socket().getLocalSocketAddress());
 
         // read
         ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
@@ -2165,7 +2164,7 @@
         assertEquals(CAPACITY_NORMAL, dc.write(sourceBuf));
 
         // Connect channel2 after data has been written.
-        channel2.connect(dc.getLocalAddress());
+        channel2.connect(dc.socket().getLocalSocketAddress());
 
         // read
         ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
@@ -2383,8 +2382,8 @@
     public void test_bounded_harmony6493() throws IOException {
         DatagramChannel server = DatagramChannel.open();
         InetSocketAddress addr = new InetSocketAddress("localhost", 0);
-        server.bind(addr);
-        SocketAddress boundedAddress = server.getLocalAddress();
+        server.socket().bind(addr);
+        SocketAddress boundedAddress = server.socket().getLocalSocketAddress();
 
         DatagramChannel client = DatagramChannel.open();
         ByteBuffer sent = ByteBuffer.allocate(1024);
@@ -2400,11 +2399,11 @@
     public void test_bind_null() throws Exception {
         DatagramChannel dc = DatagramChannel.open();
         try {
-            assertNull(dc.getLocalAddress());
+            assertNull(dc.socket().getLocalSocketAddress());
 
-            dc.bind(null);
+            dc.socket().bind(null);
 
-            InetSocketAddress localAddress = (InetSocketAddress) dc.getLocalAddress();
+            InetSocketAddress localAddress = (InetSocketAddress) dc.socket().getLocalSocketAddress();
             assertTrue(localAddress.getAddress().isAnyLocalAddress());
             assertTrue(localAddress.getPort() > 0);
         } finally {
@@ -2416,7 +2415,7 @@
         DatagramChannel dc = DatagramChannel.open();
         try {
             // Bind to a local address that is in use
-            dc.bind(channel1Address);
+            dc.socket().bind(channel1Address);
             fail();
         } catch (IOException expected) {
         } finally {
@@ -2429,38 +2428,25 @@
         dc.close();
 
         try {
-            dc.bind(null);
+            dc.socket().bind(null);
             fail();
-        } catch (ClosedChannelException expected) {
-        } finally {
-            dc.close();
-        }
-    }
-
-    public void test_bind_twice() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-        dc.bind(null);
-
-        try {
-            dc.bind(null);
-            fail();
-        } catch (AlreadyBoundException expected) {
+        } catch (IOException expected) {
         } finally {
             dc.close();
         }
     }
 
     public void test_bind_explicitPort() throws Exception {
-        InetSocketAddress address = (InetSocketAddress) channel1.getLocalAddress();
+        InetSocketAddress address = (InetSocketAddress) channel1.socket().getLocalSocketAddress();
         assertTrue(address.getPort() > 0);
 
         DatagramChannel dc = DatagramChannel.open();
         // Allow the socket to bind to a port we know is already in use.
         dc.socket().setReuseAddress(true);
         InetSocketAddress bindAddress = new InetSocketAddress("localhost", address.getPort());
-        dc.bind(bindAddress);
+        dc.socket().bind(bindAddress);
 
-        InetSocketAddress boundAddress = (InetSocketAddress) dc.getLocalAddress();
+        InetSocketAddress boundAddress = (InetSocketAddress) dc.socket().getLocalSocketAddress();
         assertEquals(bindAddress.getHostName(), boundAddress.getHostName());
         assertEquals(bindAddress.getPort(), boundAddress.getPort());
 
@@ -2471,16 +2457,16 @@
     /** Checks that the SocketChannel and associated Socket agree on the socket state. */
     public void test_bind_socketSync() throws IOException {
         DatagramChannel dc = DatagramChannel.open();
-        assertNull(dc.getLocalAddress());
+        assertNull(dc.socket().getLocalSocketAddress());
 
         DatagramSocket socket = dc.socket();
         assertNull(socket.getLocalSocketAddress());
         assertFalse(socket.isBound());
 
         InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
-        dc.bind(bindAddr);
+        dc.socket().bind(bindAddr);
 
-        InetSocketAddress actualAddr = (InetSocketAddress) dc.getLocalAddress();
+        InetSocketAddress actualAddr = (InetSocketAddress) dc.socket().getLocalSocketAddress();
         assertEquals(actualAddr, socket.getLocalSocketAddress());
         assertEquals(bindAddr.getHostName(), actualAddr.getHostName());
         assertTrue(socket.isBound());
@@ -2499,14 +2485,14 @@
      */
     public void test_bind_socketSyncAfterBind() throws IOException {
         DatagramChannel dc = DatagramChannel.open();
-        assertNull(dc.getLocalAddress());
+        assertNull(dc.socket().getLocalSocketAddress());
 
         InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
-        dc.bind(bindAddr);
+        dc.socket().bind(bindAddr);
 
         // Socket creation after bind().
         DatagramSocket socket = dc.socket();
-        InetSocketAddress actualAddr = (InetSocketAddress) dc.getLocalAddress();
+        InetSocketAddress actualAddr = (InetSocketAddress) dc.socket().getLocalSocketAddress();
         assertEquals(actualAddr, socket.getLocalSocketAddress());
         assertEquals(bindAddr.getHostName(), actualAddr.getHostName());
         assertTrue(socket.isBound());
@@ -2521,21 +2507,17 @@
 
     public void test_getLocalSocketAddress_afterClose() throws IOException {
         DatagramChannel dc = DatagramChannel.open();
-        assertNull(dc.getLocalAddress());
+        assertNull(dc.socket().getLocalSocketAddress());
 
         InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
-        dc.bind(bindAddr);
+        dc.socket().bind(bindAddr);
 
-        assertNotNull(dc.getLocalAddress());
+        assertNotNull(dc.socket().getLocalSocketAddress());
 
         dc.close();
 
         assertFalse(dc.isOpen());
 
-        try {
-            dc.getLocalAddress();
-            fail();
-        } catch (ClosedChannelException expected) {
-        }
+        dc.socket().getLocalSocketAddress();
     }
 }
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileChannelTest.java
index ccf5a14..990badc 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileChannelTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileChannelTest.java
@@ -786,7 +786,6 @@
         // shared lock, but it works on Windows & Linux.
         assertTrue(fileLock.isShared());
         assertSame(readOnlyFileChannel, fileLock.channel());
-        assertSame(readOnlyFileChannel, fileLock.acquiredBy());
         assertEquals(POSITION, fileLock.position());
         assertEquals(SIZE, fileLock.size());
     }
@@ -801,7 +800,6 @@
         assertTrue(fileLock.isValid());
         assertFalse(fileLock.isShared());
         assertSame(writeOnlyFileChannel, fileLock.channel());
-        assertSame(writeOnlyFileChannel, fileLock.acquiredBy());
         assertEquals(POSITION, fileLock.position());
         assertEquals(SIZE, fileLock.size());
     }
@@ -818,7 +816,6 @@
         assertEquals(POSITION, fileLock.position());
         assertEquals(SIZE, fileLock.size());
         assertSame(readOnlyFileChannel, fileLock.channel());
-        assertSame(readOnlyFileChannel, fileLock.acquiredBy());
     }
 
     /**
@@ -997,7 +994,6 @@
         // shared lock, but it works on Windows & Linux.
         assertTrue(fileLock.isShared());
         assertSame(readOnlyFileChannel, fileLock.channel());
-        assertSame(readOnlyFileChannel, fileLock.acquiredBy());
         assertEquals(POSITION, fileLock.position());
         assertEquals(SIZE, fileLock.size());
     }
@@ -1012,7 +1008,6 @@
         assertTrue(fileLock.isValid());
         assertFalse(fileLock.isShared());
         assertSame(writeOnlyFileChannel, fileLock.channel());
-        assertSame(writeOnlyFileChannel, fileLock.acquiredBy());
         assertEquals(POSITION, fileLock.position());
         assertEquals(SIZE, fileLock.size());
     }
@@ -1029,7 +1024,6 @@
         assertEquals(POSITION, fileLock.position());
         assertEquals(SIZE, fileLock.size());
         assertSame(readOnlyFileChannel, fileLock.channel());
-        assertSame(readOnlyFileChannel, fileLock.acquiredBy());
     }
 
     /**
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileLockTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileLockTest.java
index c4d372b..7e3b671 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileLockTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileLockTest.java
@@ -75,7 +75,6 @@
 	public void test_Constructor_Ljava_nio_channels_FileChannelJJZ() {
 		FileLock fileLock1 = new MockFileLock(null, 0, 0, false);
 		assertNull(fileLock1.channel());
-		assertNull(fileLock1.acquiredBy());
 
 		try {
 			new MockFileLock(readWriteChannel, -1, 0, false);
@@ -108,15 +107,6 @@
 	}
 
 	/**
-	 * @tests java.nio.channels.FileLock#acquiredBy()
-	 */
-	public void test_acquiredBy() {
-		assertSame(readWriteChannel, mockLock.acquiredBy());
-		FileLock lock = new MockFileLock(null, 0, 10, true);
-		assertNull(lock.acquiredBy());
-	}
-
-	/**
 	 * @tests java.nio.channels.FileLock#position()
 	 */
 	public void test_position() {
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ServerSocketChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ServerSocketChannelTest.java
index b417adc..c1d592a 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ServerSocketChannelTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/ServerSocketChannelTest.java
@@ -24,7 +24,6 @@
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.nio.ByteBuffer;
-import java.nio.channels.AlreadyBoundException;
 import java.nio.channels.AsynchronousCloseException;
 import java.nio.channels.ClosedChannelException;
 import java.nio.channels.IllegalBlockingModeException;
@@ -115,11 +114,11 @@
     public void test_bind_null() throws Exception {
         ServerSocketChannel ssc = ServerSocketChannel.open();
         try {
-            assertNull(ssc.getLocalAddress());
+            assertNull(ssc.socket().getLocalSocketAddress());
 
-            ssc.bind(null);
+            ssc.socket().bind(null);
 
-            InetSocketAddress localAddress = (InetSocketAddress) ssc.getLocalAddress();
+            InetSocketAddress localAddress = (InetSocketAddress) ssc.socket().getLocalSocketAddress();
             assertTrue(localAddress.getAddress().isAnyLocalAddress());
             assertTrue(localAddress.getPort() > 0);
         } finally {
@@ -129,12 +128,12 @@
 
     public void test_bind_failure() throws Exception {
         ServerSocketChannel portHog = ServerSocketChannel.open();
-        portHog.bind(null);
+        portHog.socket().bind(null);
 
         ServerSocketChannel ssc = ServerSocketChannel.open();
         try {
             // Bind to a local address that is in use
-            ssc.bind(portHog.getLocalAddress());
+            ssc.socket().bind(portHog.socket().getLocalSocketAddress());
             fail();
         } catch (IOException expected) {
         } finally {
@@ -148,22 +147,9 @@
         ssc.close();
 
         try {
-            ssc.bind(null);
+            ssc.socket().bind(null);
             fail();
-        } catch (ClosedChannelException expected) {
-        } finally {
-            ssc.close();
-        }
-    }
-
-    public void test_bind_twice() throws Exception {
-        ServerSocketChannel ssc = ServerSocketChannel.open();
-        ssc.bind(null);
-
-        try {
-            ssc.bind(null);
-            fail();
-        } catch (AlreadyBoundException expected) {
+        } catch (IOException expected) {
         } finally {
             ssc.close();
         }
@@ -172,9 +158,9 @@
     public void test_bind_explicitPort() throws Exception {
         ServerSocketChannel portPickingChannel = ServerSocketChannel.open();
         // Have the OS find a free port.
-        portPickingChannel.bind(null);
+        portPickingChannel.socket().bind(null);
 
-        InetSocketAddress address = (InetSocketAddress) portPickingChannel.getLocalAddress();
+        InetSocketAddress address = (InetSocketAddress) portPickingChannel.socket().getLocalSocketAddress();
         assertTrue(address.getPort() > 0);
         portPickingChannel.close();
 
@@ -182,9 +168,9 @@
         // close() and bind().
         ServerSocketChannel ssc = ServerSocketChannel.open();
         InetSocketAddress bindAddress = new InetSocketAddress("localhost", address.getPort());
-        ssc.bind(bindAddress);
+        ssc.socket().bind(bindAddress);
 
-        InetSocketAddress boundAddress = (InetSocketAddress) ssc.getLocalAddress();
+        InetSocketAddress boundAddress = (InetSocketAddress) ssc.socket().getLocalSocketAddress();
         assertEquals(bindAddress.getHostName(), boundAddress.getHostName());
         assertEquals(bindAddress.getPort(), boundAddress.getPort());
 
@@ -193,16 +179,16 @@
 
     public void test_bind_socketSync() throws IOException {
         ServerSocketChannel ssc = ServerSocketChannel.open();
-        assertNull(ssc.getLocalAddress());
+        assertNull(ssc.socket().getLocalSocketAddress());
 
         ServerSocket socket = ssc.socket();
         assertNull(socket.getLocalSocketAddress());
         assertFalse(socket.isBound());
 
         InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
-        ssc.bind(bindAddr);
+        ssc.socket().bind(bindAddr);
 
-        InetSocketAddress actualAddr = (InetSocketAddress) ssc.getLocalAddress();
+        InetSocketAddress actualAddr = (InetSocketAddress) ssc.socket().getLocalSocketAddress();
         assertEquals(actualAddr, socket.getLocalSocketAddress());
         assertEquals(bindAddr.getHostName(), actualAddr.getHostName());
         assertTrue(socket.isBound());
@@ -216,14 +202,14 @@
 
     public void test_bind_socketSyncAfterBind() throws IOException {
         ServerSocketChannel ssc = ServerSocketChannel.open();
-        assertNull(ssc.getLocalAddress());
+        assertNull(ssc.socket().getLocalSocketAddress());
 
         InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
-        ssc.bind(bindAddr);
+        ssc.socket().bind(bindAddr);
 
         // Socket creation after bind().
         ServerSocket socket = ssc.socket();
-        InetSocketAddress actualAddr = (InetSocketAddress) ssc.getLocalAddress();
+        InetSocketAddress actualAddr = (InetSocketAddress) ssc.socket().getLocalSocketAddress();
         assertEquals(actualAddr, socket.getLocalSocketAddress());
         assertEquals(bindAddr.getHostName(), actualAddr.getHostName());
         assertTrue(socket.isBound());
@@ -241,22 +227,18 @@
 
     public void test_getLocalSocketAddress_afterClose() throws IOException {
         ServerSocketChannel ssc = ServerSocketChannel.open();
-        assertNull(ssc.getLocalAddress());
+        assertNull(ssc.socket().getLocalSocketAddress());
 
         InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
-        ssc.bind(bindAddr);
+        ssc.socket().bind(bindAddr);
 
-        assertNotNull(ssc.getLocalAddress());
+        assertNotNull(ssc.socket().getLocalSocketAddress());
 
         ssc.close();
 
         assertFalse(ssc.isOpen());
 
-        try {
-            ssc.getLocalAddress();
-            fail();
-        } catch (ClosedChannelException expected) {
-        }
+        ssc.socket().getLocalSocketAddress();
     }
 
     // -------------------------------------------------------------------
@@ -387,7 +369,7 @@
 
     public void testAccept_Block_NoConnect() throws IOException {
         assertTrue(this.serverChannel.isBlocking());
-        serverChannel.bind(null);
+        serverChannel.socket().bind(null);
         // blocking mode , will block and wait for ever...
         // so must close the server channel with another thread.
         new Thread() {
@@ -410,7 +392,7 @@
     }
 
     public void testAccept_NonBlock_NoConnect() throws IOException {
-        this.serverChannel.bind(null);
+        this.serverChannel.socket().bind(null);
         this.serverChannel.configureBlocking(false);
         // non-blocking mode , will immediately return
         assertNull(this.serverChannel.accept());
@@ -420,13 +402,13 @@
      * @tests ServerSocketChannel#accept().socket()
      */
     public void test_read_Blocking_RealData() throws IOException {
-        serverChannel.bind(null);
+        serverChannel.socket().bind(null);
         ByteBuffer buf = ByteBuffer.allocate(CAPACITY_NORMAL);
 
         for (int i = 0; i < CAPACITY_NORMAL; i++) {
             buf.put((byte) i);
         }
-        clientChannel.connect(serverChannel.getLocalAddress());
+        clientChannel.connect(serverChannel.socket().getLocalSocketAddress());
         Socket serverSocket = serverChannel.accept().socket();
         InputStream in = serverSocket.getInputStream();
         buf.flip();
@@ -459,13 +441,13 @@
      */
     public void test_read_NonBlocking_RealData() throws Exception {
         serverChannel.configureBlocking(false);
-        serverChannel.bind(null);
+        serverChannel.socket().bind(null);
         ByteBuffer buf = ByteBuffer.allocate(CAPACITY_NORMAL);
         for (int i = 0; i < CAPACITY_NORMAL; i++) {
             buf.put((byte) i);
         }
         buf.flip();
-        clientChannel.connect(serverChannel.getLocalAddress());
+        clientChannel.connect(serverChannel.socket().getLocalSocketAddress());
         Socket serverSocket = serverChannel.accept().socket();
         InputStream in = serverSocket.getInputStream();
         clientChannel.write(buf);
@@ -478,13 +460,13 @@
      */
     public void test_write_Blocking_RealData() throws IOException {
         assertTrue(serverChannel.isBlocking());
-        serverChannel.bind(null);
+        serverChannel.socket().bind(null);
 
         byte[] writeContent = new byte[CAPACITY_NORMAL];
         for (int i = 0; i < writeContent.length; i++) {
             writeContent[i] = (byte) i;
         }
-        clientChannel.connect(serverChannel.getLocalAddress());
+        clientChannel.connect(serverChannel.socket().getLocalSocketAddress());
         Socket socket = serverChannel.accept().socket();
         OutputStream out = socket.getOutputStream();
         out.write(writeContent);
@@ -499,13 +481,13 @@
      */
     public void test_write_NonBlocking_RealData() throws Exception {
         serverChannel.configureBlocking(false);
-        serverChannel.bind(null);
+        serverChannel.socket().bind(null);
 
         byte[] writeContent = new byte[CAPACITY_NORMAL];
         for (int i = 0; i < CAPACITY_NORMAL; i++) {
             writeContent[i] = (byte) i;
         }
-        clientChannel.connect(serverChannel.getLocalAddress());
+        clientChannel.connect(serverChannel.socket().getLocalSocketAddress());
         Socket clientSocket = serverChannel.accept().socket();
         OutputStream out = clientSocket.getOutputStream();
         out.write(writeContent);
@@ -519,13 +501,13 @@
      */
     public void test_read_LByteBuffer_Blocking_ReadWriteRealLargeData()
             throws IOException, InterruptedException {
-        serverChannel.bind(null);
+        serverChannel.socket().bind(null);
         ByteBuffer buf = ByteBuffer.allocate(CAPACITY_64KB);
         for (int i = 0; i < CAPACITY_64KB; i++) {
             buf.put((byte) i);
         }
         buf.flip();
-        clientChannel.connect(serverChannel.getLocalAddress());
+        clientChannel.connect(serverChannel.socket().getLocalSocketAddress());
         WriteChannelThread writeThread = new WriteChannelThread(clientChannel, buf);
         writeThread.start();
         Socket socket = serverChannel.accept().socket();
@@ -564,13 +546,13 @@
     public void test_read_LByteBuffer_NonBlocking_ReadWriteRealLargeData()
             throws Exception {
         serverChannel.configureBlocking(false);
-        serverChannel.bind(null);
+        serverChannel.socket().bind(null);
         ByteBuffer buf = ByteBuffer.allocate(CAPACITY_64KB);
         for (int i = 0; i < CAPACITY_64KB; i++) {
             buf.put((byte) i);
         }
         buf.flip();
-        clientChannel.connect(serverChannel.getLocalAddress());
+        clientChannel.connect(serverChannel.socket().getLocalSocketAddress());
         WriteChannelThread writeThread = new WriteChannelThread(clientChannel, buf);
         writeThread.start();
         Socket socket = serverChannel.accept().socket();
@@ -589,12 +571,12 @@
     public void test_write_LByteBuffer_NonBlocking_ReadWriteRealLargeData()
             throws Exception {
         serverChannel.configureBlocking(false);
-        serverChannel.bind(null);
+        serverChannel.socket().bind(null);
         byte[] writeContent = new byte[CAPACITY_64KB];
         for (int i = 0; i < writeContent.length; i++) {
             writeContent[i] = (byte) i;
         }
-        clientChannel.connect(serverChannel.getLocalAddress());
+        clientChannel.connect(serverChannel.socket().getLocalSocketAddress());
         Socket socket = serverChannel.accept().socket();
         WriteSocketThread writeThread = new WriteSocketThread(socket, writeContent);
         writeThread.start();
@@ -632,12 +614,12 @@
      */
     public void test_write_LByteBuffer_Blocking_ReadWriteRealLargeData()
             throws Exception {
-        serverChannel.bind(null);
+        serverChannel.socket().bind(null);
         byte[] writeContent = new byte[CAPACITY_64KB];
         for (int i = 0; i < writeContent.length; i++) {
             writeContent[i] = (byte) i;
         }
-        clientChannel.connect(serverChannel.getLocalAddress());
+        clientChannel.connect(serverChannel.socket().getLocalSocketAddress());
         Socket socket = serverChannel.accept().socket();
         WriteSocketThread writeThread = new WriteSocketThread(socket, writeContent);
         writeThread.start();
@@ -679,7 +661,7 @@
         final int SO_TIMEOUT = 10;
         ServerSocketChannel sc = ServerSocketChannel.open();
         try {
-            sc.bind(null);
+            sc.socket().bind(null);
             sc.configureBlocking(false);
             ServerSocket ss = sc.socket();
             ss.setSoTimeout(SO_TIMEOUT);
@@ -740,7 +722,7 @@
     public void test_socket_accept_Nonblocking_Bound() throws IOException {
         // regression test for Harmony-748
         serverChannel.configureBlocking(false);
-        serverChannel.bind(null);
+        serverChannel.socket().bind(null);
         ServerSocket gotSocket = serverChannel.socket();
         try {
             gotSocket.accept();
@@ -761,7 +743,7 @@
     public void test_socket_accept_Blocking_Bound() throws IOException {
         // regression test for Harmony-748
         serverChannel.configureBlocking(true);
-        serverChannel.bind(null);
+        serverChannel.socket().bind(null);
         serverChannel.close();
         try {
             serverChannel.socket().accept();
@@ -773,8 +755,8 @@
      * Regression test for HARMONY-4961
      */
     public void test_socket_getLocalPort() throws IOException {
-        serverChannel.bind(null);
-        clientChannel.connect(serverChannel.getLocalAddress());
+        serverChannel.socket().bind(null);
+        clientChannel.connect(serverChannel.socket().getLocalSocketAddress());
         SocketChannel myChannel = serverChannel.accept();
         int port = myChannel.socket().getLocalPort();
         assertEquals(serverChannel.socket().getLocalPort(), port);
@@ -788,7 +770,7 @@
      */
     public void test_accept_configureBlocking() throws Exception {
         InetSocketAddress localAddr = new InetSocketAddress("localhost", 0);
-        serverChannel.bind(localAddr);
+        serverChannel.socket().bind(localAddr);
 
         // configure the channel non-blocking
         // when it is accepting in main thread
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SocketChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SocketChannelTest.java
index 52dff79..51a8cff 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SocketChannelTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SocketChannelTest.java
@@ -30,7 +30,6 @@
 import java.net.SocketException;
 import java.nio.Buffer;
 import java.nio.ByteBuffer;
-import java.nio.channels.AlreadyBoundException;
 import java.nio.channels.AlreadyConnectedException;
 import java.nio.channels.ClosedChannelException;
 import java.nio.channels.ConnectionPendingException;
@@ -155,21 +154,21 @@
     }
 
     public void testBind_Null() throws Exception {
-        assertNull(channel1.getLocalAddress());
+        assertNull(channel1.socket().getLocalSocketAddress());
 
-        channel1.bind(null);
+        channel1.socket().bind(null);
 
-        InetSocketAddress localAddress = (InetSocketAddress) channel1.getLocalAddress();
+        InetSocketAddress localAddress = (InetSocketAddress) channel1.socket().getLocalSocketAddress();
         assertTrue(localAddress.getAddress().isAnyLocalAddress());
         assertTrue(localAddress.getPort() > 0);
     }
 
     public void testBind_Failure() throws Exception {
-        assertNull(channel1.getLocalAddress());
+        assertNull(channel1.socket().getLocalSocketAddress());
 
         try {
             // Bind to a local address that is in use
-            channel1.bind(localAddr1);
+            channel1.socket().bind(localAddr1);
             fail();
         } catch (IOException expected) {
         }
@@ -179,27 +178,17 @@
         channel1.close();
 
         try {
-            channel1.bind(null);
+            channel1.socket().bind(null);
             fail();
-        } catch (ClosedChannelException expected) {
-        }
-    }
-
-    public void testBind_Twice() throws Exception {
-        channel1.bind(null);
-
-        try {
-            channel1.bind(null);
-            fail();
-        } catch (AlreadyBoundException expected) {
+        } catch (IOException expected) {
         }
     }
 
     public void testBind_explicitPort() throws Exception {
         ServerSocketChannel portPickingChannel = ServerSocketChannel.open();
         // Have the OS find a free port.
-        portPickingChannel.bind(null);
-        InetSocketAddress address = (InetSocketAddress) portPickingChannel.getLocalAddress();
+        portPickingChannel.socket().bind(null);
+        InetSocketAddress address = (InetSocketAddress) portPickingChannel.socket().getLocalSocketAddress();
         assertTrue(address.getPort() > 0);
         portPickingChannel.close();
 
@@ -208,31 +197,27 @@
         InetSocketAddress bindAddress = new InetSocketAddress("localhost", address.getPort());
         // Allow the socket to bind to a port we know is already in use.
         channel1.socket().setReuseAddress(true);
-        channel1.bind(bindAddress);
+        channel1.socket().bind(bindAddress);
 
-        InetSocketAddress boundAddress = (InetSocketAddress) channel1.getLocalAddress();
+        InetSocketAddress boundAddress = (InetSocketAddress) channel1.socket().getLocalSocketAddress();
         assertEquals(bindAddress.getHostName(), boundAddress.getHostName());
         assertEquals(bindAddress.getPort(), boundAddress.getPort());
     }
 
     public void test_getLocalSocketAddress_afterClose() throws IOException {
         SocketChannel sc = SocketChannel.open();
-        assertNull(sc.getLocalAddress());
+        assertNull(sc.socket().getLocalSocketAddress());
 
         InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
-        sc.bind(bindAddr);
+        sc.socket().bind(bindAddr);
 
-        assertNotNull(sc.getLocalAddress());
+        assertNotNull(sc.socket().getLocalSocketAddress());
 
         sc.close();
 
         assertFalse(sc.isOpen());
 
-        try {
-            sc.getLocalAddress();
-            fail();
-        } catch (ClosedChannelException expected) {
-        }
+        sc.socket().getLocalSocketAddress();
     }
 
     /*
@@ -479,11 +464,10 @@
 
     public void testSocket_getLocalAddress() throws Exception {
         Socket socket = channel1.socket();
-        assertNotNull(socket.getLocalAddress());
 
         channel1.connect(localAddr1);
 
-        assertNotNull(socket.getLocalAddress());
+        assertNotNull(socket.getLocalSocketAddress());
     }
 
     public void testSocket_getLocalSocketAddress() throws Exception {
@@ -1882,7 +1866,7 @@
         ServerSocket serversocket = theServerChannel.socket();
         serversocket.setReuseAddress(true);
         // Bind the socket
-        theServerChannel.bind(address);
+        theServerChannel.socket().bind(address);
 
         boolean doneNonBlockingConnect = false;
         // Loop so that we make sure we're definitely testing finishConnect()
@@ -2203,7 +2187,7 @@
         ByteBuffer buffer = ByteBuffer.allocateDirect(128);
 
         ServerSocketChannel server = ServerSocketChannel.open();
-        server.bind(new InetSocketAddress(InetAddress.getLocalHost(), 0), 5);
+        server.socket().bind(new InetSocketAddress(InetAddress.getLocalHost(), 0), 5);
         Socket client = new Socket(InetAddress.getLocalHost(), server.socket()
                 .getLocalPort());
         client.setTcpNoDelay(false);
@@ -2821,9 +2805,9 @@
      */
     public void test_writev() throws Exception {
         ServerSocketChannel ssc = ServerSocketChannel.open();
-        ssc.bind(null);
+        ssc.socket().bind(null);
         SocketChannel sc = SocketChannel.open();
-        sc.connect(ssc.getLocalAddress());
+        sc.connect(ssc.socket().getLocalSocketAddress());
         SocketChannel sock = ssc.accept();
         ByteBuffer[] buf = { ByteBuffer.allocate(10), ByteBuffer.allocateDirect(20) };
 
@@ -2848,10 +2832,10 @@
     public void test_writev2() throws Exception {
         ServerSocketChannel ssc = ServerSocketChannel.open();
         ssc.configureBlocking(false);
-        ssc.bind(null);
+        ssc.socket().bind(null);
         SocketChannel sc = SocketChannel.open();
         sc.configureBlocking(false);
-        boolean connected = sc.connect(ssc.getLocalAddress());
+        boolean connected = sc.connect(ssc.socket().getLocalSocketAddress());
         SocketChannel sock = ssc.accept();
         if (!connected) {
             sc.finishConnect();
@@ -2886,10 +2870,10 @@
     public void test_write$NonBlockingException() throws Exception {
         ServerSocketChannel ssc = ServerSocketChannel.open();
         ssc.configureBlocking(false);
-        ssc.bind(null);
+        ssc.socket().bind(null);
         SocketChannel sc = SocketChannel.open();
         sc.configureBlocking(false);
-        boolean connected = sc.connect(ssc.getLocalAddress());
+        boolean connected = sc.connect(ssc.socket().getLocalSocketAddress());
         SocketChannel sock = ssc.accept();
         if (!connected) {
             sc.finishConnect();
@@ -2922,9 +2906,9 @@
     public void test_write$LByteBuffer2() throws IOException {
         // Set-up
         ServerSocketChannel server = ServerSocketChannel.open();
-        server.bind(null);
+        server.socket().bind(null);
         SocketChannel client = SocketChannel.open();
-        client.connect(server.getLocalAddress());
+        client.connect(server.socket().getLocalSocketAddress());
         SocketChannel worker = server.accept();
 
         // Test overlapping buffers
@@ -2954,9 +2938,9 @@
     public void test_write$LByteBuffer_buffers() throws IOException {
         // Set-up
         ServerSocketChannel server = ServerSocketChannel.open();
-        server.bind(null);
+        server.socket().bind(null);
         SocketChannel client = SocketChannel.open();
-        client.connect(server.getLocalAddress());
+        client.connect(server.socket().getLocalSocketAddress());
         SocketChannel worker = server.accept();
 
         // A variety of buffer types to write
@@ -2996,9 +2980,9 @@
     public void test_write$LByteBuffer_writes() throws IOException {
         // Set-up
         ServerSocketChannel server = ServerSocketChannel.open();
-        server.bind(null);
+        server.socket().bind(null);
         SocketChannel client = SocketChannel.open();
-        client.connect(server.getLocalAddress());
+        client.connect(server.socket().getLocalSocketAddress());
         SocketChannel worker = server.accept();
 
         // Data to write
@@ -3038,10 +3022,10 @@
     public void test_write$LByteBuffer_invalid() throws IOException {
         // Set-up
         ServerSocketChannel server = ServerSocketChannel.open();
-        server.bind(null);
+        server.socket().bind(null);
 
         SocketChannel client = SocketChannel.open();
-        client.connect(server.getLocalAddress());
+        client.connect(server.socket().getLocalSocketAddress());
 
         SocketChannel worker = server.accept();
 
@@ -3141,9 +3125,9 @@
             throws Exception {
         // regression 1 for HARMONY-549
         ServerSocketChannel ssc = ServerSocketChannel.open();
-        ssc.bind(null);
+        ssc.socket().bind(null);
         SocketChannel sc = SocketChannel.open();
-        sc.connect(ssc.getLocalAddress());
+        sc.connect(ssc.socket().getLocalSocketAddress());
         ssc.accept().close();
         ByteBuffer[] buf = { ByteBuffer.allocate(10) };
         assertEquals(-1, sc.read(buf, 0, 1));
@@ -3157,9 +3141,9 @@
     public void test_socketChannel_write_ByteBufferII() throws Exception {
         // regression 2 for HARMONY-549
         ServerSocketChannel ssc = ServerSocketChannel.open();
-        ssc.bind(null);
+        ssc.socket().bind(null);
         SocketChannel sc = SocketChannel.open();
-        sc.connect(ssc.getLocalAddress());
+        sc.connect(ssc.socket().getLocalSocketAddress());
         SocketChannel sock = ssc.accept();
         ByteBuffer[] buf = { ByteBuffer.allocate(10), null };
         try {
@@ -3179,9 +3163,9 @@
     public void test_socketChannel_read_ByteBufferII_bufNULL() throws Exception {
         // regression 3 for HARMONY-549
         ServerSocketChannel ssc = ServerSocketChannel.open();
-        ssc.bind(null);
+        ssc.socket().bind(null);
         SocketChannel sc = SocketChannel.open();
-        sc.connect(ssc.getLocalAddress());
+        sc.connect(ssc.socket().getLocalSocketAddress());
         ssc.accept();
         ByteBuffer[] buf = new ByteBuffer[2];
         buf[0] = ByteBuffer.allocate(1);
@@ -3201,9 +3185,9 @@
     public void test_socketChannel_write_close() throws Exception {
         // regression 4 for HARMONY-549
         ServerSocketChannel ssc = ServerSocketChannel.open();
-        ssc.bind(null);
+        ssc.socket().bind(null);
         SocketChannel sc = SocketChannel.open();
-        sc.connect(ssc.getLocalAddress());
+        sc.connect(ssc.socket().getLocalSocketAddress());
         SocketChannel sock = ssc.accept();
         ByteBuffer buf = null;
         ssc.close();
@@ -3226,9 +3210,9 @@
         ByteBuffer readBuf = ByteBuffer.allocate(11);
         ByteBuffer buf = ByteBuffer.wrap(testStr.getBytes());
         ServerSocketChannel ssc = ServerSocketChannel.open();
-        ssc.bind(null);
+        ssc.socket().bind(null);
         SocketChannel sc = SocketChannel.open();
-        sc.connect(ssc.getLocalAddress());
+        sc.connect(ssc.socket().getLocalSocketAddress());
         buf.position(2);
         ssc.accept().write(buf);
         assertEquals(9, sc.read(readBuf));
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/WeakHashMapTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/WeakHashMapTest.java
index 0d34f72..1d5294f 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/WeakHashMapTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/WeakHashMapTest.java
@@ -199,13 +199,18 @@
         values = null;
         keyArray[50] = null;
 
-        int count = 0;
+        FinalizationTester.induceFinalization();
+        long startTime = System.currentTimeMillis();
+        // We use a busy wait loop here since we can not know when the ReferenceQueue
+        // daemon will enqueue the cleared references on their internal reference
+        // queues. The current timeout is 5 seconds.
         do {
-            System.gc();
-            System.gc();
-            FinalizationTester.induceFinalization();
-            count++;
-        } while (count <= 5 && entrySet.size() == 100);
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+            }
+        } while (entrySet.size() != 99 &&
+                 System.currentTimeMillis() - startTime < 5000);
 
         assertTrue(
                 "Incorrect number of entries returned after gc--wanted 99, got: "
diff --git a/libart/src/main/java/dalvik/system/VMRuntime.java b/libart/src/main/java/dalvik/system/VMRuntime.java
index 48b2dfa..a905c71 100644
--- a/libart/src/main/java/dalvik/system/VMRuntime.java
+++ b/libart/src/main/java/dalvik/system/VMRuntime.java
@@ -39,6 +39,7 @@
         ABI_TO_INSTRUCTION_SET_MAP.put("armeabi", "arm");
         ABI_TO_INSTRUCTION_SET_MAP.put("armeabi-v7a", "arm");
         ABI_TO_INSTRUCTION_SET_MAP.put("mips", "mips");
+        ABI_TO_INSTRUCTION_SET_MAP.put("mips64", "mips64");
         ABI_TO_INSTRUCTION_SET_MAP.put("x86", "x86");
         ABI_TO_INSTRUCTION_SET_MAP.put("x86_64", "x86_64");
         ABI_TO_INSTRUCTION_SET_MAP.put("arm64-v8a", "arm64");
@@ -325,4 +326,14 @@
 
         return instructionSet;
     }
+
+    public static boolean is64BitInstructionSet(String instructionSet) {
+        return "arm64".equals(instructionSet) ||
+                "x86_64".equals(instructionSet) ||
+                "mips64".equals(instructionSet);
+    }
+
+    public static boolean is64BitAbi(String abi) {
+        return is64BitInstructionSet(getInstructionSet(abi));
+    }
 }
diff --git a/libart/src/main/java/java/lang/Enum.java b/libart/src/main/java/java/lang/Enum.java
index e9545a1..ac5fc9a 100644
--- a/libart/src/main/java/java/lang/Enum.java
+++ b/libart/src/main/java/java/lang/Enum.java
@@ -149,7 +149,7 @@
      * @see java.lang.Comparable
      */
     public final int compareTo(E o) {
-        return ordinal - o.ordinal();
+        return ordinal - ((Enum<?>) o).ordinal;
     }
 
     /**
diff --git a/libart/src/main/java/java/lang/String.java b/libart/src/main/java/java/lang/String.java
index ab36752..0107b6e 100644
--- a/libart/src/main/java/java/lang/String.java
+++ b/libart/src/main/java/java/lang/String.java
@@ -31,23 +31,22 @@
 import libcore.util.EmptyArray;
 
 /**
- * An immutable sequence of characters/code units ({@code char}s). A
- * {@code String} is represented by array of UTF-16 values, such that
- * Unicode supplementary characters (code points) are stored/encoded as
- * surrogate pairs via Unicode code units ({@code char}).
+ * An immutable sequence of UTF-16 {@code char}s.
+ * See {@link Character} for details about the relationship between {@code char} and
+ * Unicode code points.
  *
  * <a name="backing_array"><h3>Backing Arrays</h3></a>
- * This class is implemented using a char[]. The length of the array may exceed
+ * This class is implemented using a {@code char[]}. The length of the array may exceed
  * the length of the string. For example, the string "Hello" may be backed by
  * the array {@code ['H', 'e', 'l', 'l', 'o', 'W'. 'o', 'r', 'l', 'd']} with
  * offset 0 and length 5.
  *
- * <p>Multiple strings can share the same char[] because strings are immutable.
+ * <p>Multiple strings can share the same {@code char[]} because strings are immutable.
  * The {@link #substring} method <strong>always</strong> returns a string that
  * shares the backing array of its source string. Generally this is an
- * optimization: fewer character arrays need to be allocated, and less copying
+ * optimization: fewer {@code char[]}s need to be allocated, and less copying
  * is necessary. But this can also lead to unwanted heap retention. Taking a
- * short substring of long string means that the long shared char[] won't be
+ * short substring of long string means that the long shared {@code char[]} won't be
  * garbage until both strings are garbage. This typically happens when parsing
  * small substrings out of a large input. To avoid this where necessary, call
  * {@code new String(longString.subString(...))}. The string copy constructor
@@ -64,23 +63,12 @@
 
     private static final char REPLACEMENT_CHAR = (char) 0xfffd;
 
-    /**
-     * CaseInsensitiveComparator compares Strings ignoring the case of the
-     * characters.
-     */
     private static final class CaseInsensitiveComparator implements
             Comparator<String>, Serializable {
         private static final long serialVersionUID = 8575799808933029326L;
 
         /**
-         * Compare the two objects to determine the relative ordering.
-         *
-         * @param o1
-         *            an Object to compare
-         * @param o2
-         *            an Object to compare
-         * @return an int < 0 if object1 is less than object2, 0 if they are
-         *         equal, and > 0 if object1 is greater
+         * See {@link java.lang.String#compareToIgnoreCase}.
          *
          * @exception ClassCastException
          *                if objects are not the correct type
@@ -91,7 +79,9 @@
     }
 
     /**
-     * A comparator ignoring the case of the characters.
+     * Compares strings using {@link #compareToIgnoreCase}.
+     * This is not suitable for case-insensitive string comparison for all locales.
+     * Use a {@link java.text.Collator} instead.
      */
     public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator();
 
@@ -131,7 +121,7 @@
 
     /**
      * Converts the byte array to a string, setting the high byte of every
-     * character to the specified value.
+     * {@code char} to the specified value.
      *
      * @param data
      *            the byte array to convert to a string.
@@ -161,7 +151,7 @@
 
     /**
      * Converts the byte array to a string, setting the high byte of every
-     * character to {@code high}.
+     * {@code char} to {@code high}.
      *
      * @throws NullPointerException
      *             if {@code data == null}.
@@ -220,7 +210,7 @@
      * Converts the byte array to a string using the given charset.
      *
      * <p>The behavior when the bytes cannot be decoded by the given charset
-     * is to replace malformed input and unmappable characters with the charset's default
+     * is to replace malformed input and unmappable code points with the charset's default
      * replacement string. Use {@link java.nio.charset.CharsetDecoder} for more control.
      *
      * @throws IndexOutOfBoundsException
@@ -382,8 +372,8 @@
     }
 
     /**
-     * Initializes this string to contain the characters in the specified
-     * character array. Modifying the character array after creating the string
+     * Initializes this string to contain the given {@code char}s.
+     * Modifying the array after creating the string
      * has no effect on the string.
      *
      * @throws NullPointerException if {@code data == null}
@@ -393,8 +383,8 @@
     }
 
     /**
-     * Initializes this string to contain the specified characters in the
-     * character array. Modifying the character array after creating the string
+     * Initializes this string to contain the given {@code char}s.
+     * Modifying the array after creating the string
      * has no effect on the string.
      *
      * @throws NullPointerException
@@ -414,7 +404,7 @@
 
     /*
      * Internal version of the String(char[], int, int) constructor.
-     * Does not range check, null check, or copy the character array.
+     * Does not range check, null check, or copy the array.
      */
     String(int offset, int charCount, char[] chars) {
         this.value = chars;
@@ -423,8 +413,8 @@
     }
 
     /**
-     * Constructs a new string with the same sequence of characters as {@code
-     * toCopy}. The returned string's <a href="#backing_array">backing array</a>
+     * Constructs a copy of the given string.
+     * The returned string's <a href="#backing_array">backing array</a>
      * is no larger than necessary.
      */
     public String(String toCopy) {
@@ -496,7 +486,7 @@
     }
 
     /**
-     * Returns the character at {@code index}.
+     * Returns the {@code char} at {@code index}.
      * @throws IndexOutOfBoundsException if {@code index < 0} or {@code index >= length()}.
      */
     public char charAt(int index) {
@@ -533,44 +523,36 @@
     }
 
     /**
-     * Compares the specified string to this string using the Unicode values of
-     * the characters. Returns 0 if the strings contain the same characters in
-     * the same order. Returns a negative integer if the first non-equal
-     * character in this string has a Unicode value which is less than the
-     * Unicode value of the character at the same position in the specified
-     * string, or if this string is a prefix of the specified string. Returns a
-     * positive integer if the first non-equal character in this string has a
-     * Unicode value which is greater than the Unicode value of the character at
-     * the same position in the specified string, or if the specified string is
-     * a prefix of this string.
+     * Compares this string to the given string.
      *
-     * @param string
-     *            the string to compare.
-     * @return 0 if the strings are equal, a negative integer if this string is
-     *         before the specified string, or a positive integer if this string
-     *         is after the specified string.
+     * <p>The strings are compared one {@code char} at a time.
+     * In the discussion of the return value below, note that {@code char} does not
+     * mean code point, though this should only be visible for surrogate pairs.
+     *
+     * <p>If there is an index at which the two strings differ, the result is
+     * the difference between the two {@code char}s at the lowest such index.
+     * If not, but the lengths of the strings differ, the result is the difference
+     * between the two strings' lengths.
+     * If the strings are the same length and every {@code char} is the same, the result is 0.
+     *
      * @throws NullPointerException
      *             if {@code string} is {@code null}.
      */
     public native int compareTo(String string);
 
     /**
-     * Compares the specified string to this string using the Unicode values of
-     * the characters, ignoring case differences. Returns 0 if the strings
-     * contain the same characters in the same order. Returns a negative integer
-     * if the first non-equal character in this string has a Unicode value which
-     * is less than the Unicode value of the character at the same position in
-     * the specified string, or if this string is a prefix of the specified
-     * string. Returns a positive integer if the first non-equal character in
-     * this string has a Unicode value which is greater than the Unicode value
-     * of the character at the same position in the specified string, or if the
-     * specified string is a prefix of this string.
+     * Compares this string to the given string, ignoring case differences.
      *
-     * @param string
-     *            the string to compare.
-     * @return 0 if the strings are equal, a negative integer if this string is
-     *         before the specified string, or a positive integer if this string
-     *         is after the specified string.
+     * <p>The strings are compared one {@code char} at a time. This is not suitable
+     * for case-insensitive string comparison for all locales.
+     * Use a {@link java.text.Collator} instead.
+     *
+     * <p>If there is an index at which the two strings differ, the result is
+     * the difference between the two {@code char}s at the lowest such index.
+     * If not, but the lengths of the strings differ, the result is the difference
+     * between the two strings' lengths.
+     * If the strings are the same length and every {@code char} is the same, the result is 0.
+     *
      * @throws NullPointerException
      *             if {@code string} is {@code null}.
      */
@@ -611,13 +593,10 @@
     }
 
     /**
-     * Creates a new string containing the characters in the specified character
-     * array. Modifying the character array after creating the string has no
+     * Creates a new string by copying the given {@code char[]}.
+     * Modifying the array after creating the string has no
      * effect on the string.
      *
-     * @param data
-     *            the array of characters.
-     * @return the new string.
      * @throws NullPointerException
      *             if {@code data} is {@code null}.
      */
@@ -626,17 +605,10 @@
     }
 
     /**
-     * Creates a new string containing the specified characters in the character
-     * array. Modifying the character array after creating the string has no
+     * Creates a new string by copying the given subsequence of the given {@code char[]}.
+     * Modifying the array after creating the string has no
      * effect on the string.
-     *
-     * @param data
-     *            the array of characters.
-     * @param start
-     *            the starting offset in the character array.
-     * @param length
-     *            the number of characters to use.
-     * @return the new string.
+
      * @throws NullPointerException
      *             if {@code data} is {@code null}.
      * @throws IndexOutOfBoundsException
@@ -651,10 +623,6 @@
      * Compares the specified string to this string to determine if the
      * specified string is a suffix.
      *
-     * @param suffix
-     *            the suffix to look for.
-     * @return {@code true} if the specified string is a suffix of this string,
-     *         {@code false} otherwise.
      * @throws NullPointerException
      *             if {@code suffix} is {@code null}.
      */
@@ -663,15 +631,9 @@
     }
 
     /**
-     * Compares the specified object to this string and returns true if they are
-     * equal. The object must be an instance of string with the same characters
-     * in the same order.
-     *
-     * @param other
-     *            the object to compare.
-     * @return {@code true} if the specified object is equal to this string,
-     *         {@code false} otherwise.
-     * @see #hashCode
+     * Compares the given object to this string and returns true if they are
+     * equal. The object must be an instance of {@code String} with the same length,
+     * where for every index, {@code charAt} on each string returns the same value.
      */
     @Override public boolean equals(Object other) {
         if (other == this) {
@@ -710,13 +672,11 @@
     }
 
     /**
-     * Compares the specified string to this string ignoring the case of the
-     * characters and returns true if they are equal.
+     * Compares the given string to this string ignoring case.
      *
-     * @param string
-     *            the string to compare.
-     * @return {@code true} if the specified string is equal to this string,
-     *         {@code false} otherwise.
+     * <p>The strings are compared one {@code char} at a time. This is not suitable
+     * for case-insensitive string comparison for all locales.
+     * Use a {@link java.text.Collator} instead.
      */
     @FindBugsSuppressWarnings("ES_COMPARING_PARAMETER_STRING_WITH_EQ")
     public boolean equalsIgnoreCase(String string) {
@@ -740,17 +700,17 @@
     }
 
     /**
-     * Mangles this string into a byte array by stripping the high order bits from
-     * each character. Use {@link #getBytes()} or {@link #getBytes(String)} instead.
+     * Mangles a subsequence of this string into a byte array by stripping the high order bits from
+     * each {@code char}. Use {@link #getBytes()} or {@link #getBytes(String)} instead.
      *
      * @param start
-     *            the starting offset of characters to copy.
+     *            the start offset in this string.
      * @param end
-     *            the ending offset of characters to copy.
+     *            the end+1 offset in this string.
      * @param data
      *            the destination byte array.
      * @param index
-     *            the starting offset in the destination byte array.
+     *            the start offset in the destination byte array.
      * @throws NullPointerException
      *             if {@code data} is {@code null}.
      * @throws IndexOutOfBoundsException
@@ -760,7 +720,6 @@
      */
     @Deprecated
     public void getBytes(int start, int end, byte[] data, int index) {
-        // Note: last character not copied!
         if (start >= 0 && start <= end && end <= count) {
             end += offset;
             try {
@@ -776,7 +735,7 @@
     }
 
     /**
-     * Returns a new byte array containing the characters of this string encoded using the
+     * Returns a new byte array containing the code points in this string encoded using the
      * system's {@link java.nio.charset.Charset#defaultCharset default charset}.
      *
      * <p>The behavior when this string cannot be represented in the system's default charset
@@ -788,7 +747,7 @@
     }
 
     /**
-     * Returns a new byte array containing the characters of this string encoded using the
+     * Returns a new byte array containing the code points of this string encoded using the
      * named charset.
      *
      * <p>The behavior when this string cannot be represented in the named charset
@@ -801,11 +760,11 @@
     }
 
     /**
-     * Returns a new byte array containing the characters of this string encoded using the
+     * Returns a new byte array containing the code points of this string encoded using the
      * given charset.
      *
      * <p>The behavior when this string cannot be represented in the given charset
-     * is to replace malformed input and unmappable characters with the charset's default
+     * is to replace malformed input and unmappable code points with the charset's default
      * replacement byte array. Use {@link java.nio.charset.CharsetEncoder} for more control.
      *
      * @since 1.6
@@ -830,17 +789,17 @@
     }
 
     /**
-     * Copies the specified characters in this string to the character array
-     * starting at the specified offset in the character array.
+     * Copies the given subsequence of this string to the given array
+     * starting at the given offset.
      *
      * @param start
-     *            the starting offset of characters to copy.
+     *            the start offset in this string.
      * @param end
-     *            the ending offset of characters to copy.
+     *            the end+1 offset in this string.
      * @param buffer
-     *            the destination character array.
+     *            the destination array.
      * @param index
-     *            the starting offset in the character array.
+     *            the start offset in the destination array.
      * @throws NullPointerException
      *             if {@code buffer} is {@code null}.
      * @throws IndexOutOfBoundsException
@@ -849,7 +808,6 @@
      *             index}
      */
     public void getChars(int start, int end, char[] buffer, int index) {
-        // Note: last character not copied!
         if (start >= 0 && start <= end && end <= count) {
             System.arraycopy(value, start + offset, buffer, index, end - start);
         } else {
@@ -859,12 +817,11 @@
     }
 
     /**
-     * Version of getChars without bounds checks, for use by other classes
+     * getChars without bounds checks, for use by other classes
      * within the java.lang package only.  The caller is responsible for
      * ensuring that start >= 0 && start <= end && end <= count.
      */
     void _getChars(int start, int end, char[] buffer, int index) {
-        // NOTE last character not copied!
         System.arraycopy(value, start + offset, buffer, index, end - start);
     }
 
@@ -885,14 +842,9 @@
     }
 
     /**
-     * Searches in this string for the first index of the specified character.
-     * The search for the character starts at the beginning and moves towards
+     * Returns the first index of the given code point, or -1.
+     * The search starts at the beginning and moves towards
      * the end of this string.
-     *
-     * @param c
-     *            the character to find.
-     * @return the index in this string of the specified character, -1 if the
-     *         character isn't found.
      */
     public int indexOf(int c) {
         // TODO: just "return indexOf(c, 0);" when the JIT can inline that deep.
@@ -903,16 +855,9 @@
     }
 
     /**
-     * Searches in this string for the index of the specified character. The
-     * search for the character starts at the specified offset and moves towards
+     * Returns the next index of the given code point, or -1. The
+     * search starts at the given offset and moves towards
      * the end of this string.
-     *
-     * @param c
-     *            the character to find.
-     * @param start
-     *            the starting offset.
-     * @return the index in this string of the specified character, -1 if the
-     *         character isn't found.
      */
     public int indexOf(int c, int start) {
         if (c > 0xffff) {
@@ -933,14 +878,10 @@
     }
 
     /**
-     * Searches in this string for the first index of the specified string. The
-     * search for the string starts at the beginning and moves towards the end
+     * Returns the first index of the given string, or -1. The
+     * search starts at the beginning and moves towards the end
      * of this string.
      *
-     * @param string
-     *            the string to find.
-     * @return the index of the first character of the specified string in this
-     *         string, -1 if the specified string is not a substring.
      * @throws NullPointerException
      *             if {@code string} is {@code null}.
      */
@@ -976,16 +917,10 @@
     }
 
     /**
-     * Searches in this string for the index of the specified string. The search
-     * for the string starts at the specified offset and moves towards the end
+     * Returns the next index of the given string in this string, or -1. The search
+     * for the string starts at the given offset and moves towards the end
      * of this string.
      *
-     * @param subString
-     *            the string to find.
-     * @param start
-     *            the starting offset.
-     * @return the index of the first character of the specified string in this
-     *         string, -1 if the specified string is not a substring.
      * @throws NullPointerException
      *             if {@code subString} is {@code null}.
      */
@@ -1048,7 +983,7 @@
 
     /**
      * Returns the last index of the code point {@code c}, or -1.
-     * The search for the character starts at the end and moves towards the
+     * The search starts at the end and moves towards the
      * beginning of this string.
      */
     public int lastIndexOf(int c) {
@@ -1068,7 +1003,7 @@
 
     /**
      * Returns the last index of the code point {@code c}, or -1.
-     * The search for the character starts at offset {@code start} and moves towards
+     * The search starts at offset {@code start} and moves towards
      * the beginning of this string.
      */
     public int lastIndexOf(int c, int start) {
@@ -1101,14 +1036,10 @@
     }
 
     /**
-     * Searches in this string for the last index of the specified string. The
-     * search for the string starts at the end and moves towards the beginning
+     * Returns the index of the start of the last match for the given string in this string, or -1.
+     * The search for the string starts at the end and moves towards the beginning
      * of this string.
      *
-     * @param string
-     *            the string to find.
-     * @return the index of the first character of the specified string in this
-     *         string, -1 if the specified string is not a substring.
      * @throws NullPointerException
      *             if {@code string} is {@code null}.
      */
@@ -1118,16 +1049,11 @@
     }
 
     /**
-     * Searches in this string for the index of the specified string. The search
-     * for the string starts at the specified offset and moves towards the
-     * beginning of this string.
+     * Returns the index of the start of the previous match for the given string in this string,
+     * or -1.
+     * The search for the string starts at the given index and moves towards the beginning
+     * of this string.
      *
-     * @param subString
-     *            the string to find.
-     * @param start
-     *            the starting offset.
-     * @return the index of the first character of the specified string in this
-     *         string , -1 if the specified string is not a substring.
      * @throws NullPointerException
      *             if {@code subString} is {@code null}.
      */
@@ -1164,26 +1090,21 @@
     }
 
     /**
-     * Returns the number of characters in this string.
+     * Returns the number of {@code char}s in this string. If this string contains surrogate pairs,
+     * this is not the same as the number of code points.
      */
     public int length() {
         return count;
     }
 
     /**
-     * Compares the specified string to this string and compares the specified
-     * range of characters to determine if they are the same.
+     * Returns true if the given subsequence of the given string matches this string starting
+     * at the given offset.
      *
-     * @param thisStart
-     *            the starting offset in this string.
-     * @param string
-     *            the string to compare.
-     * @param start
-     *            the starting offset in the specified string.
-     * @param length
-     *            the number of characters to compare.
-     * @return {@code true} if the ranges of characters are equal, {@code false}
-     *         otherwise
+     * @param thisStart the start offset in this string.
+     * @param string the other string.
+     * @param start the start offset in {@code string}.
+     * @param length the number of {@code char}s to compare.
      * @throws NullPointerException
      *             if {@code string} is {@code null}.
      */
@@ -1212,22 +1133,21 @@
     }
 
     /**
-     * Compares the specified string to this string and compares the specified
-     * range of characters to determine if they are the same. When ignoreCase is
-     * true, the case of the characters is ignored during the comparison.
+     * Returns true if the given subsequence of the given string matches this string starting
+     * at the given offset.
+     *
+     * <p>If ignoreCase is true, case is ignored during the comparison.
+     * The strings are compared one {@code char} at a time. This is not suitable
+     * for case-insensitive string comparison for all locales.
+     * Use a {@link java.text.Collator} instead.
      *
      * @param ignoreCase
-     *            specifies if case should be ignored.
-     * @param thisStart
-     *            the starting offset in this string.
-     * @param string
-     *            the string to compare.
-     * @param start
-     *            the starting offset in the specified string.
-     * @param length
-     *            the number of characters to compare.
-     * @return {@code true} if the ranges of characters are equal, {@code false}
-     *         otherwise.
+     *     specifies if case should be ignored (use {@link java.text.Collator} instead for
+     *     non-ASCII case insensitivity).
+     * @param thisStart the start offset in this string.
+     * @param string the other string.
+     * @param start the start offset in {@code string}.
+     * @param length the number of {@code char}s to compare.
      * @throws NullPointerException
      *             if {@code string} is {@code null}.
      */
@@ -1259,14 +1179,7 @@
     }
 
     /**
-     * Copies this string replacing occurrences of the specified character with
-     * another character.
-     *
-     * @param oldChar
-     *            the character to replace.
-     * @param newChar
-     *            the replacement character.
-     * @return a new string with occurrences of oldChar replaced by newChar.
+     * Returns a copy of this string after replacing occurrences of the given {@code char} with another.
      */
     public String replace(char oldChar, char newChar) {
         char[] buffer = value;
@@ -1295,15 +1208,10 @@
     }
 
     /**
-     * Copies this string replacing occurrences of the specified target sequence
-     * with another sequence. The string is processed from the beginning to the
+     * Returns a copy of this string after replacing occurrences of {@code target} replaced
+     * with {@code replacement}. The string is processed from the beginning to the
      * end.
      *
-     * @param target
-     *            the sequence to replace.
-     * @param replacement
-     *            the replacement sequence.
-     * @return the resulting string.
      * @throws NullPointerException
      *             if {@code target} or {@code replacement} is {@code null}.
      */
@@ -1324,11 +1232,11 @@
 
         String replacementString = replacement.toString();
 
-        // The empty target matches at the start and end and between each character.
+        // The empty target matches at the start and end and between each char.
         int targetLength = targetString.length();
         if (targetLength == 0) {
-            // The result contains the original 'count' characters, a copy of the
-            // replacement string before every one of those characters, and a final
+            // The result contains the original 'count' chars, a copy of the
+            // replacement string before every one of those chars, and a final
             // copy of the replacement string at the end.
             int resultLength = count + (count + 1) * replacementString.length();
             StringBuilder result = new StringBuilder(resultLength);
@@ -1344,7 +1252,7 @@
         StringBuilder result = new StringBuilder(count);
         int searchStart = 0;
         do {
-            // Copy characters before the match...
+            // Copy chars before the match...
             result.append(value, offset + searchStart, matchStart - searchStart);
             // Insert the replacement...
             result.append(replacementString);
@@ -1389,13 +1297,9 @@
     }
 
     /**
-     * Returns a string containing a suffix of this string. The returned string
-     * shares this string's <a href="#backing_array">backing array</a>.
+     * Returns a string containing a suffix of this string starting at {@code start}.
+     * The returned string shares this string's <a href="#backing_array">backing array</a>.
      *
-     * @param start
-     *            the offset of the first character.
-     * @return a new string containing the characters from start to the end of
-     *         the string.
      * @throws IndexOutOfBoundsException
      *             if {@code start < 0} or {@code start > length()}.
      */
@@ -1410,24 +1314,18 @@
     }
 
     /**
-     * Returns a string containing a subsequence of characters from this string.
-     * The returned string shares this string's <a href="#backing_array">backing
-     * array</a>.
+     * Returns a string containing the given subsequence of this string.
+     * The returned string shares this string's <a href="#backing_array">backing array</a>.
      *
-     * @param start
-     *            the offset of the first character.
-     * @param end
-     *            the offset one past the last character.
-     * @return a new string containing the characters from start to end - 1
+     * @param start the start offset.
+     * @param end the end+1 offset.
      * @throws IndexOutOfBoundsException
-     *             if {@code start < 0}, {@code start > end} or {@code end >
-     *             length()}.
+     *             if {@code start < 0}, {@code start > end} or {@code end > length()}.
      */
     public String substring(int start, int end) {
         if (start == 0 && end == count) {
             return this;
         }
-        // NOTE last character not copied!
         // Fast range check.
         if (start >= 0 && start <= end && end <= count) {
             return new String(offset + start, end - start, value);
@@ -1436,8 +1334,8 @@
     }
 
     /**
-     * Returns a new {@code char} array containing a copy of the characters in this string.
-     * This is expensive and rarely useful. If you just want to iterate over the characters in
+     * Returns a new {@code char} array containing a copy of the {@code char}s in this string.
+     * This is expensive and rarely useful. If you just want to iterate over the {@code char}s in
      * the string, use {@link #charAt} instead.
      */
     public char[] toCharArray() {
@@ -1509,11 +1407,8 @@
     }
 
     /**
-     * Copies this string removing white space characters from the beginning and
-     * end of the string.
-     *
-     * @return a new string with characters <code><= \\u0020</code> removed from
-     *         the beginning and the end.
+     * Returns a string with no code points <code><= \\u0020</code> at
+     * the beginning or end.
      */
     public String trim() {
         int start = offset, last = offset + count - 1;
@@ -1531,13 +1426,10 @@
     }
 
     /**
-     * Creates a new string containing the characters in the specified character
-     * array. Modifying the character array after creating the string has no
+     * Returns a new string containing the same {@code char}s as the given
+     * array. Modifying the array after creating the string has no
      * effect on the string.
      *
-     * @param data
-     *            the array of characters.
-     * @return the new string.
      * @throws NullPointerException
      *             if {@code data} is {@code null}.
      */
@@ -1546,20 +1438,12 @@
     }
 
     /**
-     * Creates a new string containing the specified characters in the character
-     * array. Modifying the character array after creating the string has no
+     * Returns a new string containing the same {@code char}s as the given
+     * subset of the given array. Modifying the array after creating the string has no
      * effect on the string.
      *
-     * @param data
-     *            the array of characters.
-     * @param start
-     *            the starting offset in the character array.
-     * @param length
-     *            the number of characters to use.
-     * @return the new string.
      * @throws IndexOutOfBoundsException
-     *             if {@code length < 0}, {@code start < 0} or {@code start +
-     *             length > data.length}
+     *             if {@code length < 0}, {@code start < 0} or {@code start + length > data.length}
      * @throws NullPointerException
      *             if {@code data} is {@code null}.
      */
@@ -1568,11 +1452,7 @@
     }
 
     /**
-     * Converts the specified character to its string representation.
-     *
-     * @param value
-     *            the character.
-     * @return the character converted to a string.
+     * Returns a new string of just the given {@code char}.
      */
     public static String valueOf(char value) {
         String s;
@@ -1586,44 +1466,28 @@
     }
 
     /**
-     * Converts the specified double to its string representation.
-     *
-     * @param value
-     *            the double.
-     * @return the double converted to a string.
+     * Returns the string representation of the given double.
      */
     public static String valueOf(double value) {
         return Double.toString(value);
     }
 
     /**
-     * Converts the specified float to its string representation.
-     *
-     * @param value
-     *            the float.
-     * @return the float converted to a string.
+     * Returns the string representation of the given float.
      */
     public static String valueOf(float value) {
         return Float.toString(value);
     }
 
     /**
-     * Converts the specified integer to its string representation.
-     *
-     * @param value
-     *            the integer.
-     * @return the integer converted to a string.
+     * Returns the string representation of the given int.
      */
     public static String valueOf(int value) {
         return Integer.toString(value);
     }
 
     /**
-     * Converts the specified long to its string representation.
-     *
-     * @param value
-     *            the long.
-     * @return the long converted to a string.
+     * Returns the string representation of the given long.
      */
     public static String valueOf(long value) {
         return Long.toString(value);
@@ -1656,36 +1520,27 @@
     }
 
     /**
-     * Returns whether the characters in the StringBuffer {@code strbuf} are the
-     * same as those in this string.
+     * Returns true if the {@code char}s in the given {@code StringBuffer} are the same
+     * as those in this string.
      *
-     * @param strbuf
-     *            the StringBuffer to compare this string to.
-     * @return {@code true} if the characters in {@code strbuf} are identical to
-     *         those in this string. If they are not, {@code false} will be
-     *         returned.
      * @throws NullPointerException
-     *             if {@code strbuf} is {@code null}.
+     *             if {@code sb} is {@code null}.
      * @since 1.4
      */
-    public boolean contentEquals(StringBuffer strbuf) {
-        synchronized (strbuf) {
-            int size = strbuf.length();
+    public boolean contentEquals(StringBuffer sb) {
+        synchronized (sb) {
+            int size = sb.length();
             if (count != size) {
                 return false;
             }
-            return regionMatches(0, new String(0, size, strbuf.getValue()), 0,
-                    size);
+            return regionMatches(0, new String(0, size, sb.getValue()), 0, size);
         }
     }
 
     /**
-     * Compares a {@code CharSequence} to this {@code String} to determine if
-     * their contents are equal.
+     * Returns true if the {@code char}s in the given {@code CharSequence} are the same
+     * as those in this string.
      *
-     * @param cs
-     *            the character sequence to compare to.
-     * @return {@code true} if equal, otherwise {@code false}
      * @since 1.5
      */
     public boolean contentEquals(CharSequence cs) {
@@ -1804,14 +1659,8 @@
     }
 
     /**
-     * Has the same result as the substring function, but is present so that
-     * string may implement the CharSequence interface.
+     * Equivalent to {@link #substring(int, int)} but needed to implement {@code CharSequence}.
      *
-     * @param start
-     *            the offset the first character.
-     * @param end
-     *            the offset of one past the last character to include.
-     * @return the subsequence requested.
      * @throws IndexOutOfBoundsException
      *             if {@code start < 0}, {@code end < 0}, {@code start > end} or
      *             {@code end > length()}.
@@ -1872,13 +1721,8 @@
     }
 
     /**
-     * Determines if this {@code String} contains the sequence of characters in
-     * the {@code CharSequence} passed.
+     * Returns true if this string contains the {@code chars}s from the given {@code CharSequence}.
      *
-     * @param cs
-     *            the character sequence to search for.
-     * @return {@code true} if the sequence of characters are contained in this
-     *         string, otherwise {@code false}.
      * @since 1.5
      */
     public boolean contains(CharSequence cs) {
diff --git a/libart/src/main/java/java/lang/ref/Reference.java b/libart/src/main/java/java/lang/ref/Reference.java
index 3b03ff1..31ea588 100644
--- a/libart/src/main/java/java/lang/ref/Reference.java
+++ b/libart/src/main/java/java/lang/ref/Reference.java
@@ -98,6 +98,22 @@
 public abstract class Reference<T> {
 
     /**
+     * Forces JNI path.
+     * If GC is not in progress (ie: not going through slow path), the referent
+     * can be quickly returned through intrinsic without passing through JNI.
+     * This flag forces the JNI path so that it can be tested and benchmarked.
+     */
+    private static boolean disableIntrinsic = false;
+
+    /**
+     * Slow path flag for the reference processor.
+     * Used by the reference processor to determine whether or not the referent
+     * can be immediately returned. Because the referent might get swept during
+     * GC, the slow path, which passes through JNI, must be taken.
+     */
+    private static boolean slowPathEnabled = false;
+
+    /**
      * The object to which this reference refers.
      * VM requirement: this field <em>must</em> be called "referent"
      * and be an object.
diff --git a/luni/src/main/java/java/io/Console.java b/luni/src/main/java/java/io/Console.java
index b6532eb..fe07694c 100644
--- a/luni/src/main/java/java/io/Console.java
+++ b/luni/src/main/java/java/io/Console.java
@@ -127,48 +127,17 @@
     }
 
     /**
-     * Reads a password from the console. The password will not be echoed to the display.
-     *
-     * @return a character array containing the password, or null at EOF.
+     * This method is unimplemented on Android.
      */
     public char[] readPassword() {
-        synchronized (CONSOLE_LOCK) {
-            int previousState = setEcho(false, 0);
-            try {
-                String password = readLine();
-                writer.println(); // We won't have echoed the user's newline.
-                return (password == null) ? null : password.toCharArray();
-            } finally {
-                setEcho(true, previousState);
-            }
-        }
+        throw new UnsupportedOperationException();
     }
 
-    private static int setEcho(boolean on, int previousState) {
-        try {
-            return setEchoImpl(on, previousState);
-        } catch (IOException ex) {
-            throw new IOError(ex);
-        }
-    }
-    private static native int setEchoImpl(boolean on, int previousState) throws IOException;
-
     /**
-     * Reads a password from the console. The password will not be echoed to the display.
-     * A formatted prompt is also displayed.
-     *
-     * @param format the format string (see {@link java.util.Formatter#format})
-     * @param args
-     *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by {@code format},
-     *            additional arguments are ignored.
-     * @return a character array containing the password, or null at EOF.
+     * This method is unimplemented on Android.
      */
     public char[] readPassword(String format, Object... args) {
-        synchronized (CONSOLE_LOCK) {
-            format(format, args);
-            return readPassword();
-        }
+        throw new UnsupportedOperationException();
     }
 
     /**
diff --git a/luni/src/main/java/java/lang/Character.java b/luni/src/main/java/java/lang/Character.java
index 2bf3a89..8efd6cd 100644
--- a/luni/src/main/java/java/lang/Character.java
+++ b/luni/src/main/java/java/lang/Character.java
@@ -1526,426 +1526,6 @@
 
     private static native int unicodeBlockForCodePoint(int codePoint);
 
-    /**
-     * Represents a <a href="http://www.unicode.org/reports/tr24/">Unicode script</a>.
-     * Every Unicode code point is contained by a single {@code UnicodeScript}. Code points
-     * shared between scripts will be in {@code COMMON}. Code points for combining
-     * characters that can be applied to multiple scripts will be in {@code INHERITED}
-     * because they inherit the script of their base character. Code points whose scripts
-     * don't have a corresponding {@code UnicodeScript} will be in {@code UNKNOWN}.
-     *
-     * @since 1.7
-     * @hide
-     */
-    public static enum UnicodeScript {
-        /** ISO 15924 English name "Arabic" */
-        ARABIC,
-        /** ISO 15924 English name "Armenian" */
-        ARMENIAN,
-        /** ISO 15924 English name "Avestan" */
-        AVESTAN,
-        /** ISO 15924 English name "Balinese" */
-        BALINESE,
-        /** ISO 15924 English name "Bamum" */
-        BAMUM,
-        /** ISO 15924 English name "Batak" */
-        BATAK,
-        /** ISO 15924 English name "Bengali" */
-        BENGALI,
-        /** ISO 15924 English name "Bopomofo" */
-        BOPOMOFO,
-        /** ISO 15924 English name "Brahmi" */
-        BRAHMI,
-        /** ISO 15924 English name "Braille" */
-        BRAILLE,
-        /** ISO 15924 English name "Buginese" */
-        BUGINESE,
-        /** ISO 15924 English name "Buhid" */
-        BUHID,
-        /** ISO 15924 English name "Unified Canadian Aboriginal Syllabics" */
-        CANADIAN_ABORIGINAL,
-        /** ISO 15924 English name "Carian" */
-        CARIAN,
-        /** ISO 15924 English name "Cham" */
-        CHAM,
-        /** ISO 15924 English name "Cherokee" */
-        CHEROKEE,
-        /** ISO 15924 English name "Common" */
-        COMMON,
-        /** ISO 15924 English name "Coptic" */
-        COPTIC,
-        /** ISO 15924 English name "Cuneiform" */
-        CUNEIFORM,
-        /** ISO 15924 English name "Cypriot" */
-        CYPRIOT,
-        /** ISO 15924 English name "Cyrillic" */
-        CYRILLIC,
-        /** ISO 15924 English name "Deseret" */
-        DESERET,
-        /** ISO 15924 English name "Devanagari" */
-        DEVANAGARI,
-        /** ISO 15924 English name "Egyptian hieroglyphs" */
-        EGYPTIAN_HIEROGLYPHS,
-        /** ISO 15924 English name "Ethiopic" */
-        ETHIOPIC,
-        /** ISO 15924 English name "Georgian" */
-        GEORGIAN,
-        /** ISO 15924 English name "Glagolitic" */
-        GLAGOLITIC,
-        /** ISO 15924 English name "Gothic" */
-        GOTHIC,
-        /** ISO 15924 English name "Greek" */
-        GREEK,
-        /** ISO 15924 English name "Gujarati" */
-        GUJARATI,
-        /** ISO 15924 English name "Gurmukhi" */
-        GURMUKHI,
-        /** ISO 15924 English name "Han" */
-        HAN,
-        /** ISO 15924 English name "Hangul" */
-        HANGUL,
-        /** ISO 15924 English name "Hanunoo" */
-        HANUNOO,
-        /** ISO 15924 English name "Hebrew" */
-        HEBREW,
-        /** ISO 15924 English name "Hiragana" */
-        HIRAGANA,
-        /** ISO 15924 English name "Imperial aramaic" */
-        IMPERIAL_ARAMAIC,
-        /** ISO 15924 English name "Inherited" */
-        INHERITED,
-        /** ISO 15924 English name "Inscriptional pahlavi" */
-        INSCRIPTIONAL_PAHLAVI,
-        /** ISO 15924 English name "Inscriptional parthian" */
-        INSCRIPTIONAL_PARTHIAN,
-        /** ISO 15924 English name "Javanese" */
-        JAVANESE,
-        /** ISO 15924 English name "Kaithi" */
-        KAITHI,
-        /** ISO 15924 English name "Kannada" */
-        KANNADA,
-        /** ISO 15924 English name "Katakana" */
-        KATAKANA,
-        /** ISO 15924 English name "Kayah li" */
-        KAYAH_LI,
-        /** ISO 15924 English name "Kharoshthi" */
-        KHAROSHTHI,
-        /** ISO 15924 English name "Khmer" */
-        KHMER,
-        /** ISO 15924 English name "Lao" */
-        LAO,
-        /** ISO 15924 English name "Latin" */
-        LATIN,
-        /** ISO 15924 English name "Lepcha" */
-        LEPCHA,
-        /** ISO 15924 English name "Limbu" */
-        LIMBU,
-        /** ISO 15924 English name "Linear B" */
-        LINEAR_B,
-        /** ISO 15924 English name "Lisu" */
-        LISU,
-        /** ISO 15924 English name "Lycian" */
-        LYCIAN,
-        /** ISO 15924 English name "Lydian" */
-        LYDIAN,
-        /** ISO 15924 English name "Malayalam" */
-        MALAYALAM,
-        /** ISO 15924 English name "Mandaic" */
-        MANDAIC,
-        /** ISO 15924 English name "Meetei Mayek (Meithei, Meetei)" */
-        MEETEI_MAYEK,
-        /** ISO 15924 English name "Mongolian" */
-        MONGOLIAN,
-        /** ISO 15924 English name "Myanmar" */
-        MYANMAR,
-        /** ISO 15924 English name "New Tai Lue" */
-        NEW_TAI_LUE,
-        /** ISO 15924 English name "Nko" */
-        NKO,
-        /** ISO 15924 English name "Ogham" */
-        OGHAM,
-        /** ISO 15924 English name "Ol Chiki" */
-        OL_CHIKI,
-        /** ISO 15924 English name "Old Italic" */
-        OLD_ITALIC,
-        /** ISO 15924 English name "Old Persian" */
-        OLD_PERSIAN,
-        /** ISO 15924 English name "Old South Arabian" */
-        OLD_SOUTH_ARABIAN,
-        /** ISO 15924 English name "Old Turkic, Orkhon Runic" */
-        OLD_TURKIC,
-        /** ISO 15924 English name "Oriya" */
-        ORIYA,
-        /** ISO 15924 English name "Osmanya" */
-        OSMANYA,
-        /** ISO 15924 English name "Phags-pa" */
-        PHAGS_PA,
-        /** ISO 15924 English name "Phoenician" */
-        PHOENICIAN,
-        /** ISO 15924 English name "Rejang" */
-        REJANG,
-        /** ISO 15924 English name "Runic" */
-        RUNIC,
-        /** ISO 15924 English name "Samaritan" */
-        SAMARITAN,
-        /** ISO 15924 English name "Saurashtra" */
-        SAURASHTRA,
-        /** ISO 15924 English name "Shavian" */
-        SHAVIAN,
-        /** ISO 15924 English name "Sinhala" */
-        SINHALA,
-        /** ISO 15924 English name "Sundanese" */
-        SUNDANESE,
-        /** ISO 15924 English name "Syloti Nagri" */
-        SYLOTI_NAGRI,
-        /** ISO 15924 English name "Syriac" */
-        SYRIAC,
-        /** ISO 15924 English name "Tagalog" */
-        TAGALOG,
-        /** ISO 15924 English name "Tagbanwa" */
-        TAGBANWA,
-        /** ISO 15924 English name "Tai Le" */
-        TAI_LE,
-        /** ISO 15924 English name "Tai Tham (Lanna)" */
-        TAI_THAM,
-        /** ISO 15924 English name "Tai Viet" */
-        TAI_VIET,
-        /** ISO 15924 English name "Tamil" */
-        TAMIL,
-        /** ISO 15924 English name "Telugu" */
-        TELUGU,
-        /** ISO 15924 English name "Thaana" */
-        THAANA,
-        /** ISO 15924 English name "Thai" */
-        THAI,
-        /** ISO 15924 English name "Tibetan" */
-        TIBETAN,
-        /** ISO 15924 English name "Tifinagh" */
-        TIFINAGH,
-        /** ISO 15924 English name "Ugaritic" */
-        UGARITIC,
-        /** ISO 15924 English name "Unknown" */
-        UNKNOWN,
-        /** ISO 15924 English name "Vai" */
-        VAI,
-        /** ISO 15924 English name "Yi" */
-        YI;
-
-        private static final UnicodeScript[] SCRIPTS = {
-                COMMON,
-                INHERITED,
-                ARABIC,
-                ARMENIAN,
-                BENGALI,
-                BOPOMOFO,
-                CHEROKEE,
-                COPTIC,
-                CYRILLIC,
-                DESERET,
-                DEVANAGARI,
-                ETHIOPIC,
-                GEORGIAN,
-                GOTHIC,
-                GREEK,
-                GUJARATI,
-                GURMUKHI,
-                HAN,
-                HANGUL,
-                HEBREW,
-                HIRAGANA,
-                KANNADA,
-                KATAKANA,
-                KHMER,
-                LAO,
-                LATIN,
-                MALAYALAM,
-                MONGOLIAN,
-                MYANMAR,
-                OGHAM,
-                OLD_ITALIC,
-                ORIYA,
-                RUNIC,
-                SINHALA,
-                SYRIAC,
-                TAMIL,
-                TELUGU,
-                THAANA,
-                THAI,
-                TIBETAN,
-                CANADIAN_ABORIGINAL,
-                YI,
-                TAGALOG,
-                HANUNOO,
-                BUHID,
-                TAGBANWA,
-                BRAILLE,
-                CYPRIOT,
-                LIMBU,
-                LINEAR_B,
-                OSMANYA,
-                SHAVIAN,
-                TAI_LE,
-                UGARITIC,
-                null,  // USCRIPT_KATAKANA_OR_HIRAGANA
-                BUGINESE,
-                GLAGOLITIC,
-                KHAROSHTHI,
-                SYLOTI_NAGRI,
-                NEW_TAI_LUE,
-                TIFINAGH,
-                OLD_PERSIAN,
-                BALINESE,
-                BATAK,
-                null, // USCRIPT_BLISSYMBOLS,
-                BRAHMI,
-                CHAM,
-                null,  // USCRIPT_CIRTH,
-                null,  // USCRIPT_OLD_CHURCH_SLAVONIC_CYRILLIC,
-                null,  // USCRIPT_DEMOTIC_EGYPTIAN,
-                null,  // USCRIPT_HIERATIC_EGYPTIAN,
-                EGYPTIAN_HIEROGLYPHS,
-                null,  // USCRIPT_USCRIPT_KHUTSURI,
-                null,  // USCRIPT_SIMPLIFIED_HAN,
-                null,  // USCRIPT_TRADITIONAL_HAN,
-                null,  // USCRIPT_PAHAWH_HMONG,
-                null,  // USCRIPT_OLD_HUNGARIAN,
-                null,  // USCRIPT_HARAPPAN_INDUS,
-                JAVANESE,
-                KAYAH_LI,
-                null,  // USCRIPT_LATIN_FRAKTUR,
-                null,  // USCRIPT_LATIN_GAELIC,
-                LEPCHA,
-                null,  // USCRIPT_LINEAR_A,
-                MANDAIC, // == MANDAEAN
-                null,  // USCRIPT_MAYAN_HIEROGLYPHS,
-                null,  // USCRIPT_MEROITIC_HIEROGLYPHS == USCRIPT_MEROITIC
-                null,  // USCRIPT_NKO,
-                OLD_TURKIC,  // USCRIPT_ORKHON == OLD_TURKIC,
-                null,  // USCRIPT_OLD_PERMIC,
-                PHAGS_PA,
-                PHOENICIAN,
-                null,  // USCRIPT_PHONETIC_POLLARD === MIAO,
-                null,  // USCRIPT_RONGORONGO,
-                null,  // USCRIPT_SARATI,
-                null,  // USCRIPT_ESTRANGELO_SYRIAC,
-                null,  // USCRIPT_WESTERN_SYRIAC,
-                null,  // USCRIPT_EASTERN_SYRIAC,
-                null,  // USCRIPT_TENGWAR,
-                VAI,
-                null,  // USCRIPT_VISIBLE_SPEECH,
-                CUNEIFORM,
-                null,  // USCRIPT_UNWRITTEN_LANGUAGES,
-                UNKNOWN,
-                CARIAN,
-                null,  // USCRIPT_JAPANESE,
-                TAI_THAM,  // USCRIPT_LANNA (aka TAI_THAM),
-                LYCIAN,
-                LYDIAN,
-                OL_CHIKI,
-                REJANG,
-                SAURASHTRA,
-                null,  // USCRIPT_SIGN_WRITING,
-                SUNDANESE,
-                null,  // USCRIPT_MOON,
-                MEETEI_MAYEK,  // USCRIPT_MEITEI_MAYEK (aka MEETEI, MEITHEI),
-                IMPERIAL_ARAMAIC,
-                AVESTAN,
-                null,  // USCRIPT_CHAKMA,
-                null,  // USCRIPT_KOREAN,
-                KAITHI,
-                null,  // USCRIPT_MANICHAEAN,
-                INSCRIPTIONAL_PAHLAVI,
-                null,  // USCRIPT_PSALTER_PAHLAVI,
-                null,  // USCRIPT_BOOK_PAHLAVI,
-                INSCRIPTIONAL_PARTHIAN,
-                SAMARITAN,
-                TAI_VIET,
-                null,  // USCRIPT_MATHEMATICAL_NOTATION,
-                null,  // USCRIPT_SYMBOLS,
-                BAMUM,
-                LISU,
-                null,  // USCRIPT_NAKHI_GEBA,
-                OLD_SOUTH_ARABIAN,
-                null,  // USCRIPT_BASSA_VAH,
-                null,  // USCRIPT_DUPLOYAN_SHORTAND,
-                null,  // USCRIPT_ELBASAN,
-                null,  // USCRIPT_GRANTHA,
-                null,  // USCRIPT_KPELLE,
-                null,  // USCRIPT_LOMA,
-                null,  // USCRIPT_MENDE,
-                null,  // USCRIPT_MEROITIC_CURSIVE,
-                null,  // USCRIPT_OLD_NORTH_ARABIAN,
-                null,  // USCRIPT_NABATAEAN,
-                null,  // USCRIPT_PALMYRENE,
-                null,  // USCRIPT_SINDHI,
-                null,  // USCRIPT_WARANG_CITI,
-                null,  // USCRIPT_AFAKA,
-                null,  // USCRIPT_JURCHEN,
-                null,  // USCRIPT_MRO,
-                null,  // USCRIPT_NUSHU,
-                null,  // USCRIPT_SHARADA,
-                null,  // USCRIPT_SORA_SOMPENG,
-                null,  // USCRIPT_TAKRI,
-                null,  // USCRIPT_TANGUT,
-                null,  // USCRIPT_WOLEAI,
-                null,  // USCRIPT_ANATOLIAN_HIEROGLYPHS,
-                null,  // USCRIPT_KHOJKI,
-                null,  // USCRIPT_TIRHUTA,
-        };
-
-        /**
-         * Returns the {@link UnicodeScript} value identified by {@code scriptName}.
-         * {@code scriptName} can be a ISO-15924 English script name
-         * or an alias (ISO-15924 script code) for that name.
-         * {@see http://www.unicode.org/iso15924/iso15924-codes.html}
-         * Lookups are case insensitive.
-         *
-         * @throws NullPointerException if {@code scriptName} is null.
-         * @throws IllegalAccessException if {@code scriptName} in invalid.
-         *
-         * @since 1.7
-         */
-        public static UnicodeScript forName(String scriptName) {
-            if (scriptName == null) {
-                throw new NullPointerException("scriptName == null");
-            }
-
-            final int script = unicodeScriptForName(scriptName);
-            if (script == -1 || script >= SCRIPTS.length ||
-                    SCRIPTS[script] == null) {
-                throw new IllegalArgumentException("Unknown script: " + scriptName);
-            }
-
-            return SCRIPTS[script];
-        }
-
-        /**
-         * Returns the {@link UnicodeScript} value that the given Unicode code
-         * point is assigned to.
-         *
-         * @throws IllegalArgumentException if {@code Point} is not a valid Unicode code point.
-         *
-         * @since 1.7
-         */
-        public static UnicodeScript of(int codePoint) {
-            checkValidCodePoint(codePoint);
-            int script = unicodeScriptForCodePoint(codePoint);
-            if (script == -1 || script >= SCRIPTS.length) {
-                // This signifies an ICU error. Complain loudly instead of swallowing
-                // the error up.
-                throw new IllegalArgumentException("Invalid codePoint: " + codePoint);
-            }
-
-            // This happens when ICU maps the code point to a script known to ICU but
-            // not the Java API.
-            if (SCRIPTS[script] == null) {
-                return UNKNOWN;
-            }
-
-            return SCRIPTS[script];
-        }
-    }
-
     private static native int unicodeScriptForName(String blockName);
 
     private static native int unicodeScriptForCodePoint(int codePoint);
diff --git a/luni/src/main/java/java/lang/System.java b/luni/src/main/java/java/lang/System.java
index 185701e..2c5d634 100644
--- a/luni/src/main/java/java/lang/System.java
+++ b/luni/src/main/java/java/lang/System.java
@@ -171,14 +171,16 @@
      * @param length
      *            the number of elements to be copied.
      */
-    public static native void arraycopy(Object src, int srcPos, Object dst, int dstPos, int length);
+
+    public static native void arraycopy(Object src, int srcPos,
+        Object dst, int dstPos, int length);
 
     /**
      * The char array length threshold below which to use a Java
      * (non-native) version of arraycopy() instead of the native
      * version. See b/7103825.
      */
-    private static final int ARRAYCOPY_SHORT_CHAR_ARRAY_THRESHOLD = 64;
+    private static final int ARRAYCOPY_SHORT_CHAR_ARRAY_THRESHOLD = 16;
 
     /**
      * The char[] specialized version of arraycopy().
@@ -227,6 +229,377 @@
         char[] dst, int dstPos, int length);
 
     /**
+     * The byte array length threshold below which to use a Java
+     * (non-native) version of arraycopy() instead of the native
+     * version. See b/7103825.
+     */
+    private static final int ARRAYCOPY_SHORT_BYTE_ARRAY_THRESHOLD = 16;
+
+    /**
+     * The byte[] specialized version of arraycopy().
+     *
+     * @hide internal use only
+     */
+    public static void arraycopy(byte[] src, int srcPos, byte[] dst, int dstPos, int length) {
+        if (src == null) {
+            throw new NullPointerException("src == null");
+        }
+        if (dst == null) {
+            throw new NullPointerException("dst == null");
+        }
+        if (srcPos < 0 || dstPos < 0 || length < 0 ||
+            srcPos > src.length - length || dstPos > dst.length - length) {
+            throw new ArrayIndexOutOfBoundsException(
+                "src.length=" + src.length + " srcPos=" + srcPos +
+                " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+        }
+        if (length <= ARRAYCOPY_SHORT_BYTE_ARRAY_THRESHOLD) {
+            // Copy byte by byte for shorter arrays.
+            if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+                // Copy backward (to avoid overwriting elements before
+                // they are copied in case of an overlap on the same
+                // array.)
+                for (int i = length - 1; i >= 0; --i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            } else {
+                // Copy forward.
+                for (int i = 0; i < length; ++i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            }
+        } else {
+            // Call the native version for longer arrays.
+            arraycopyByteUnchecked(src, srcPos, dst, dstPos, length);
+        }
+    }
+
+    /**
+     * The byte[] specialized, unchecked, native version of
+     * arraycopy(). This assumes error checking has been done.
+     */
+    private static native void arraycopyByteUnchecked(byte[] src, int srcPos,
+        byte[] dst, int dstPos, int length);
+
+    /**
+     * The short array length threshold below which to use a Java
+     * (non-native) version of arraycopy() instead of the native
+     * version. See b/7103825.
+     */
+    private static final int ARRAYCOPY_SHORT_SHORT_ARRAY_THRESHOLD = 16;
+
+    /**
+     * The short[] specialized version of arraycopy().
+     *
+     * @hide internal use only
+     */
+    public static void arraycopy(short[] src, int srcPos, short[] dst, int dstPos, int length) {
+        if (src == null) {
+            throw new NullPointerException("src == null");
+        }
+        if (dst == null) {
+            throw new NullPointerException("dst == null");
+        }
+        if (srcPos < 0 || dstPos < 0 || length < 0 ||
+            srcPos > src.length - length || dstPos > dst.length - length) {
+            throw new ArrayIndexOutOfBoundsException(
+                "src.length=" + src.length + " srcPos=" + srcPos +
+                " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+        }
+        if (length <= ARRAYCOPY_SHORT_SHORT_ARRAY_THRESHOLD) {
+            // Copy short by short for shorter arrays.
+            if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+                // Copy backward (to avoid overwriting elements before
+                // they are copied in case of an overlap on the same
+                // array.)
+                for (int i = length - 1; i >= 0; --i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            } else {
+                // Copy forward.
+                for (int i = 0; i < length; ++i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            }
+        } else {
+            // Call the native version for longer arrays.
+            arraycopyShortUnchecked(src, srcPos, dst, dstPos, length);
+        }
+    }
+
+    /**
+     * The short[] specialized, unchecked, native version of
+     * arraycopy(). This assumes error checking has been done.
+     */
+    private static native void arraycopyShortUnchecked(short[] src, int srcPos,
+        short[] dst, int dstPos, int length);
+
+    /**
+     * The short array length threshold below which to use a Java
+     * (non-native) version of arraycopy() instead of the native
+     * version. See b/7103825.
+     */
+    private static final int ARRAYCOPY_SHORT_INT_ARRAY_THRESHOLD = 32;
+
+    /**
+     * The int[] specialized version of arraycopy().
+     *
+     * @hide internal use only
+     */
+    public static void arraycopy(int[] src, int srcPos, int[] dst, int dstPos, int length) {
+        if (src == null) {
+            throw new NullPointerException("src == null");
+        }
+        if (dst == null) {
+            throw new NullPointerException("dst == null");
+        }
+        if (srcPos < 0 || dstPos < 0 || length < 0 ||
+            srcPos > src.length - length || dstPos > dst.length - length) {
+            throw new ArrayIndexOutOfBoundsException(
+                "src.length=" + src.length + " srcPos=" + srcPos +
+                " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+        }
+        if (length <= ARRAYCOPY_SHORT_INT_ARRAY_THRESHOLD) {
+            // Copy int by int for shorter arrays.
+            if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+                // Copy backward (to avoid overwriting elements before
+                // they are copied in case of an overlap on the same
+                // array.)
+                for (int i = length - 1; i >= 0; --i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            } else {
+                // Copy forward.
+                for (int i = 0; i < length; ++i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            }
+        } else {
+            // Call the native version for longer arrays.
+            arraycopyIntUnchecked(src, srcPos, dst, dstPos, length);
+        }
+    }
+
+    /**
+     * The int[] specialized, unchecked, native version of
+     * arraycopy(). This assumes error checking has been done.
+     */
+    private static native void arraycopyIntUnchecked(int[] src, int srcPos,
+        int[] dst, int dstPos, int length);
+
+    /**
+     * The short array length threshold below which to use a Java
+     * (non-native) version of arraycopy() instead of the native
+     * version. See b/7103825.
+     */
+    private static final int ARRAYCOPY_SHORT_LONG_ARRAY_THRESHOLD = 32;
+
+    /**
+     * The long[] specialized version of arraycopy().
+     *
+     * @hide internal use only
+     */
+    public static void arraycopy(long[] src, int srcPos, long[] dst, int dstPos, int length) {
+        if (src == null) {
+            throw new NullPointerException("src == null");
+        }
+        if (dst == null) {
+            throw new NullPointerException("dst == null");
+        }
+        if (srcPos < 0 || dstPos < 0 || length < 0 ||
+            srcPos > src.length - length || dstPos > dst.length - length) {
+            throw new ArrayIndexOutOfBoundsException(
+                "src.length=" + src.length + " srcPos=" + srcPos +
+                " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+        }
+        if (length <= ARRAYCOPY_SHORT_LONG_ARRAY_THRESHOLD) {
+            // Copy long by long for shorter arrays.
+            if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+                // Copy backward (to avoid overwriting elements before
+                // they are copied in case of an overlap on the same
+                // array.)
+                for (int i = length - 1; i >= 0; --i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            } else {
+                // Copy forward.
+                for (int i = 0; i < length; ++i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            }
+        } else {
+            // Call the native version for longer arrays.
+            arraycopyLongUnchecked(src, srcPos, dst, dstPos, length);
+        }
+    }
+
+    /**
+     * The long[] specialized, unchecked, native version of
+     * arraycopy(). This assumes error checking has been done.
+     */
+    private static native void arraycopyLongUnchecked(long[] src, int srcPos,
+        long[] dst, int dstPos, int length);
+
+    /**
+     * The short array length threshold below which to use a Java
+     * (non-native) version of arraycopy() instead of the native
+     * version. See b/7103825.
+     */
+    private static final int ARRAYCOPY_SHORT_FLOAT_ARRAY_THRESHOLD = 16;
+
+    /**
+     * The float[] specialized version of arraycopy().
+     *
+     * @hide internal use only
+     */
+    public static void arraycopy(float[] src, int srcPos, float[] dst, int dstPos, int length) {
+        if (src == null) {
+            throw new NullPointerException("src == null");
+        }
+        if (dst == null) {
+            throw new NullPointerException("dst == null");
+        }
+        if (srcPos < 0 || dstPos < 0 || length < 0 ||
+            srcPos > src.length - length || dstPos > dst.length - length) {
+            throw new ArrayIndexOutOfBoundsException(
+                "src.length=" + src.length + " srcPos=" + srcPos +
+                " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+        }
+        if (length <= ARRAYCOPY_SHORT_FLOAT_ARRAY_THRESHOLD) {
+            // Copy float by float for shorter arrays.
+            if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+                // Copy backward (to avoid overwriting elements before
+                // they are copied in case of an overlap on the same
+                // array.)
+                for (int i = length - 1; i >= 0; --i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            } else {
+                // Copy forward.
+                for (int i = 0; i < length; ++i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            }
+        } else {
+            // Call the native version for floater arrays.
+            arraycopyFloatUnchecked(src, srcPos, dst, dstPos, length);
+        }
+    }
+
+    /**
+     * The float[] specialized, unchecked, native version of
+     * arraycopy(). This assumes error checking has been done.
+     */
+    private static native void arraycopyFloatUnchecked(float[] src, int srcPos,
+        float[] dst, int dstPos, int length);
+
+    /**
+     * The short array length threshold below which to use a Java
+     * (non-native) version of arraycopy() instead of the native
+     * version. See b/7103825.
+     */
+    private static final int ARRAYCOPY_SHORT_DOUBLE_ARRAY_THRESHOLD = 64;
+
+    /**
+     * The double[] specialized version of arraycopy().
+     *
+     * @hide internal use only
+     */
+    public static void arraycopy(double[] src, int srcPos, double[] dst, int dstPos, int length) {
+        if (src == null) {
+            throw new NullPointerException("src == null");
+        }
+        if (dst == null) {
+            throw new NullPointerException("dst == null");
+        }
+        if (srcPos < 0 || dstPos < 0 || length < 0 ||
+            srcPos > src.length - length || dstPos > dst.length - length) {
+            throw new ArrayIndexOutOfBoundsException(
+                "src.length=" + src.length + " srcPos=" + srcPos +
+                " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+        }
+        if (length <= ARRAYCOPY_SHORT_DOUBLE_ARRAY_THRESHOLD) {
+            // Copy double by double for shorter arrays.
+            if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+                // Copy backward (to avoid overwriting elements before
+                // they are copied in case of an overlap on the same
+                // array.)
+                for (int i = length - 1; i >= 0; --i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            } else {
+                // Copy forward.
+                for (int i = 0; i < length; ++i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            }
+        } else {
+            // Call the native version for floater arrays.
+            arraycopyDoubleUnchecked(src, srcPos, dst, dstPos, length);
+        }
+    }
+
+    /**
+     * The double[] specialized, unchecked, native version of
+     * arraycopy(). This assumes error checking has been done.
+     */
+    private static native void arraycopyDoubleUnchecked(double[] src, int srcPos,
+        double[] dst, int dstPos, int length);
+
+    /**
+     * The short array length threshold below which to use a Java
+     * (non-native) version of arraycopy() instead of the native
+     * version. See b/7103825.
+     */
+    private static final int ARRAYCOPY_SHORT_BOOLEAN_ARRAY_THRESHOLD = 128;
+
+    /**
+     * The boolean[] specialized version of arraycopy().
+     *
+     * @hide internal use only
+     */
+    public static void arraycopy(boolean[] src, int srcPos, boolean[] dst, int dstPos, int length) {
+        if (src == null) {
+            throw new NullPointerException("src == null");
+        }
+        if (dst == null) {
+            throw new NullPointerException("dst == null");
+        }
+        if (srcPos < 0 || dstPos < 0 || length < 0 ||
+            srcPos > src.length - length || dstPos > dst.length - length) {
+            throw new ArrayIndexOutOfBoundsException(
+                "src.length=" + src.length + " srcPos=" + srcPos +
+                " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+        }
+        if (length <= ARRAYCOPY_SHORT_BOOLEAN_ARRAY_THRESHOLD) {
+            // Copy boolean by boolean for shorter arrays.
+            if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+                // Copy backward (to avoid overwriting elements before
+                // they are copied in case of an overlap on the same
+                // array.)
+                for (int i = length - 1; i >= 0; --i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            } else {
+                // Copy forward.
+                for (int i = 0; i < length; ++i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            }
+        } else {
+            // Call the native version for floater arrays.
+            arraycopyBooleanUnchecked(src, srcPos, dst, dstPos, length);
+        }
+    }
+
+    /**
+     * The boolean[] specialized, unchecked, native version of
+     * arraycopy(). This assumes error checking has been done.
+     */
+    private static native void arraycopyBooleanUnchecked(boolean[] src, int srcPos,
+        boolean[] dst, int dstPos, int length);
+
+    /**
      * Returns the current time in milliseconds since January 1, 1970 00:00:00.0 UTC.
      *
      * <p>This method always returns UTC times, regardless of the system's time zone.
diff --git a/luni/src/main/java/java/net/HttpCookie.java b/luni/src/main/java/java/net/HttpCookie.java
index 04121f7..dd81fd6 100644
--- a/luni/src/main/java/java/net/HttpCookie.java
+++ b/luni/src/main/java/java/net/HttpCookie.java
@@ -560,28 +560,6 @@
     }
 
     /**
-     * Returns the {@code HttpOnly} attribute. If {@code true} the cookie should not be accessible
-     * to scripts in a browser.
-     *
-     * @since 1.7
-     * @hide Until ready for an API update
-     */
-    public boolean isHttpOnly() {
-        return httpOnly;
-    }
-
-    /**
-     * Returns the {@code HttpOnly} attribute. If {@code true} the cookie should not be accessible
-     * to scripts in a browser.
-     *
-     * @since 1.7
-     * @hide Until ready for an API update
-     */
-    public void setHttpOnly(boolean httpOnly) {
-        this.httpOnly = httpOnly;
-    }
-
-    /**
      * Returns the value of this cookie.
      */
     public String getValue() {
diff --git a/luni/src/main/java/java/net/SocketOption.java b/luni/src/main/java/java/net/SocketOption.java
deleted file mode 100644
index 3f65494..0000000
--- a/luni/src/main/java/java/net/SocketOption.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.net;
-
-/**
- * An option associated with a socket.
- *
- * <p>See {@link java.nio.channels.NetworkChannel#setOption},
- * {@link java.nio.channels.NetworkChannel#getOption} and
- * {@link java.nio.channels.NetworkChannel#supportedOptions} for methods that use SocketOption.
- *
- * <p>See {@link StandardSocketOptions} for valid SocketOptions.
- *
- * @param <T> the type of the value
- * @since 1.7
- * @hide Until ready for a public API change
- */
-public interface SocketOption<T> {
-
-  /**
-   * Returns the name of the option.
-   */
-  String name();
-
-  /**
-   * Returns the type of the value of the option.
-   */
-  Class<T> type();
-}
diff --git a/luni/src/main/java/java/net/StandardSocketOptions.java b/luni/src/main/java/java/net/StandardSocketOptions.java
deleted file mode 100644
index 3d10caf..0000000
--- a/luni/src/main/java/java/net/StandardSocketOptions.java
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.net;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import libcore.io.IoBridge;
-
-/**
- * Defines the set standard of socket options that can be supported by network channels.
- *
- * <p>See {@link java.nio.channels.NetworkChannel} for more information, particularly
- * {@link java.nio.channels.NetworkChannel#supportedOptions()} for the options that are supported
- * for each type of socket.
- *
- * @since 1.7
- * @hide Until ready for a public API change
- */
-public final class StandardSocketOptions {
-
-  /**
-   * The outgoing interface for multicast packets.
-   *
-   * <p>See {@link SocketOptions#IP_MULTICAST_IF2} for further documentation.
-   */
-  public static final SocketOption<NetworkInterface> IP_MULTICAST_IF =
-      new NetworkInterfaceSocketOption("IP_MULTICAST_IF", SocketOptions.IP_MULTICAST_IF2);
-
-  /**
-   * Whether the local loopback of multicast packets is enabled (true) or disabled (false). This
-   * option is enabled by default.
-   *
-   * <p>See {@link SocketOptions#IP_MULTICAST_LOOP} for further documentation.
-   */
-  public static final SocketOption<Boolean> IP_MULTICAST_LOOP =
-      new BooleanSocketOption("IP_MULTICAST_LOOP", SocketOptions.IP_MULTICAST_LOOP);
-
-  /**
-   * The time-to-live (TTL) for multicast packets. The value must be between 0 and 255 inclusive.
-   * A 0 value restricts the packet to the originating host. See also {@link #IP_MULTICAST_LOOP}.
-   * The default value is 1.
-   *
-   * <p>See <a href="http://tools.ietf.org/rfc/rfc1112.txt">RFC 1112: Host Extensions for IP
-   * Multicasting</a> for more information about IP multicast.
-   */
-  public static final SocketOption<Integer> IP_MULTICAST_TTL =
-      new ByteRangeSocketOption("IP_MULTICAST_TTL", IoBridge.JAVA_IP_MULTICAST_TTL);
-
-  /**
-   * The value for the type-of-service field of the IPv4 header, or the traffic class field of the
-   * IPv6 header. These correspond to the IP_TOS and IPV6_TCLASS socket options. These may be
-   * ignored by the underlying OS. Values must be between 0 and 255 inclusive.
-   *
-   * <p>See {@link SocketOptions#IP_TOS} for further documentation.
-   */
-  public static final SocketOption<Integer> IP_TOS =
-      new ByteRangeSocketOption("IP_TOS", SocketOptions.IP_TOS);
-
-  /**
-   * Whether broadcasting on datagram sockets is enabled or disabled. This option must be enabled to
-   * send broadcast messages. The default value is false.
-   *
-   * <p>See {@link SocketOptions#SO_BROADCAST} for further documentation.
-   */
-  public static final SocketOption<Boolean> SO_BROADCAST =
-      new BooleanSocketOption("SO_BROADCAST", SocketOptions.SO_BROADCAST);
-
-  /**
-   * Whether the kernel sends keepalive messages on connection-oriented sockets.
-   *
-   * <p>See {@link SocketOptions#SO_KEEPALIVE} for further documentation.
-   */
-  public static final SocketOption<Boolean> SO_KEEPALIVE =
-      new BooleanSocketOption("SO_KEEPALIVE", SocketOptions.SO_KEEPALIVE);
-
-  /**
-   * Number of seconds to wait when closing a socket if there is still some buffered data to be
-   * sent.
-   *
-   * <p>If this option is negative this option is disabled. This is the default value. If the value
-   * is 0 or positive it is enabled.
-   *
-   * <p>See {@link SocketOptions#SO_LINGER} for further documentation.
-   *
-   */
-  public static final SocketOption<Integer> SO_LINGER =
-      new SocketOptionImpl<Integer>("SO_LINGER", Integer.class, SocketOptions.SO_LINGER) {
-        @Override
-        protected Object validateAndConvertValueBeforeSet(
-            FileDescriptor fd, Integer value) {
-          Object objectValue = super.validateAndConvertValueBeforeSet(fd, value);
-          if (value != null && value < 0) {
-            // IoBridge requires a "false" object to disable linger.
-            objectValue = Boolean.FALSE;
-          }
-          return objectValue;
-        }
-
-        @Override
-        protected Integer validateAndConvertValueAfterGet(FileDescriptor fd, Object value) {
-          // IoBridge returns a "false" object to indicate that linger is disabled.
-          if (value != null && value instanceof Boolean) {
-            value = -1;
-          }
-          return super.validateAndConvertValueAfterGet(fd, value);
-        }
-      };
-
-  /**
-   * The size in bytes of a socket's receive buffer. This must be an integer greater than 0.
-   * This is a hint to the kernel; the kernel may use a larger buffer.
-   *
-   * <p>See {@link SocketOptions#SO_RCVBUF} for further documentation.
-   */
-  public static final SocketOption<Integer> SO_RCVBUF =
-      new PositiveIntegerSocketOption("SO_RCVBUF", SocketOptions.SO_RCVBUF);
-
-  /**
-   * Whether a reuse of a local address is allowed when another socket has not yet been removed by
-   * the operating system.
-   *
-   * <p>See {@link SocketOptions#SO_REUSEADDR} for further documentation.
-   */
-  public static final SocketOption<Boolean> SO_REUSEADDR =
-      new BooleanSocketOption("SO_REUSEADDR", SocketOptions.SO_REUSEADDR);
-
-  /**
-   * The size in bytes of a socket's send buffer. This must be an integer greater than 0.
-   * This is a hint to the kernel; the kernel may use a larger buffer.
-   *
-   * <p>See {@link SocketOptions#SO_SNDBUF} for further documentation.
-   */
-  public static final SocketOption<Integer> SO_SNDBUF =
-      new PositiveIntegerSocketOption("SO_SNDBUF", SocketOptions.SO_SNDBUF);
-
-  /**
-   * Specifies whether data is sent immediately on this socket or buffered.
-   *
-   * <p>See {@link SocketOptions#TCP_NODELAY} for further documentation.
-   */
-  public static final SocketOption<Boolean> TCP_NODELAY =
-      new BooleanSocketOption("TCP_NODELAY", SocketOptions.TCP_NODELAY);
-
-  /**
-   * The set of supported options for UDP sockets.
-   *
-   * @hide internal use only
-   */
-  public static final Set<SocketOption<?>> DATAGRAM_SOCKET_OPTIONS;
-
-  static {
-    HashSet<SocketOption<?>> mutableSet = new HashSet<SocketOption<?>>(8);
-    mutableSet.add(IP_MULTICAST_IF);
-    mutableSet.add(IP_MULTICAST_LOOP);
-    mutableSet.add(IP_MULTICAST_TTL);
-    mutableSet.add(IP_TOS);
-    mutableSet.add(SO_BROADCAST);
-    mutableSet.add(SO_REUSEADDR);
-    mutableSet.add(SO_RCVBUF);
-    mutableSet.add(SO_SNDBUF);
-    DATAGRAM_SOCKET_OPTIONS = Collections.unmodifiableSet(mutableSet);
-  }
-
-  /**
-   * The set of supported options for TCP sockets.
-   *
-   * @hide internal use only
-   */
-  public static final Set<SocketOption<?>> SOCKET_OPTIONS;
-
-  static {
-    HashSet<SocketOption<?>> mutableSet = new HashSet<SocketOption<?>>(7);
-    mutableSet.add(IP_TOS);
-    mutableSet.add(SO_KEEPALIVE);
-    mutableSet.add(SO_LINGER);
-    mutableSet.add(TCP_NODELAY);
-    mutableSet.add(SO_RCVBUF);
-    mutableSet.add(SO_REUSEADDR);
-    mutableSet.add(SO_SNDBUF);
-    SOCKET_OPTIONS = Collections.unmodifiableSet(mutableSet);
-  }
-
-  /**
-   * The set of supported options for TCP server sockets.
-   *
-   * @hide internal use only
-   */
-  public static final Set<SocketOption<?>> SERVER_SOCKET_OPTIONS;
-
-  static {
-    HashSet<SocketOption<?>> mutableSet = new HashSet<SocketOption<?>>(2);
-    mutableSet.add(SO_RCVBUF);
-    mutableSet.add(SO_REUSEADDR);
-    SERVER_SOCKET_OPTIONS = Collections.unmodifiableSet(mutableSet);
-  }
-
-  /**
-   * A base class for SocketOption objects that passes the values to/from {@link IoBridge} as they
-   * are. For use with simple types like Integer and Boolean, and can be extended for more
-   * validation / type conversion.
-   *
-   * @hide internal use only
-   */
-  public static class SocketOptionImpl<T> implements SocketOption<T> {
-
-    protected final String name;
-
-    private final Class<T> type;
-
-    protected final int socketOption;
-
-    public SocketOptionImpl(String name, Class<T> type, int socketOption) {
-      this.name = name;
-      this.type = type;
-      this.socketOption = socketOption;
-    }
-
-    @Override
-    public String name() {
-      return name;
-    }
-
-    @Override
-    public Class<T> type() {
-      return type;
-    }
-
-    /**
-     * Sets the socket option of the file descriptor to value using IoBridge.
-     *
-     * @hide internal method
-     */
-    public final void setValue(FileDescriptor fd, T value) throws IOException {
-      // Sanity check required because of type erasure.
-      if (value != null && !type.isAssignableFrom(value.getClass())) {
-        throw new AssertionError("Invalid type " + value + " of value for " + name);
-      }
-      Object objectValue = validateAndConvertValueBeforeSet(fd, value);
-      IoBridge.setSocketOption(fd, socketOption, objectValue);
-    }
-
-    /**
-     * Throws IllegalArgumentException if the value is outside of the acceptable range.
-     * Subclasses can override to apply option-specific validate, and may also convert the value
-     * to a different type or value. The default implementation prevents null values and returns
-     * the value unchanged.
-     */
-    protected Object validateAndConvertValueBeforeSet(FileDescriptor fd, T value) {
-      if (value == null) {
-        throw new IllegalArgumentException("value for " + name + " must not be null");
-      }
-      return value;
-    }
-
-    /**
-     * Gets the value of the socket option.
-     *
-     * @hide internal method
-     */
-    public final T getValue(FileDescriptor fd) throws IOException {
-      Object value = IoBridge.getSocketOption(fd, socketOption);
-      T typedValue = validateAndConvertValueAfterGet(fd, value);
-      if (typedValue != null && !type.isAssignableFrom(typedValue.getClass())) {
-        // Sanity check required because of type erasure.
-        throw new AssertionError("Unexpected type of value returned for " + name);
-      }
-      return typedValue;
-    }
-
-    /**
-     * Throws AssertionError if the value is outside of the acceptable range.
-     * Implementations may also convert the value to a different type or
-     * value. The default implementation does nothing.
-     */
-    @SuppressWarnings("unchecked")
-    protected T validateAndConvertValueAfterGet(FileDescriptor fd, Object value) {
-      return (T) value;
-    }
-  }
-
-  /**
-   * A SocketOption capable of setting / getting an boolean value.
-   */
-  private static class BooleanSocketOption extends SocketOptionImpl<Boolean> {
-
-    public BooleanSocketOption(String name, int socketOption) {
-      super(name, Boolean.class, socketOption);
-    }
-  }
-
-  /**
-   * A SocketOption capable of setting / getting an network interface value.
-   */
-  private static class NetworkInterfaceSocketOption extends SocketOptionImpl<NetworkInterface> {
-
-    public NetworkInterfaceSocketOption(String name, int socketOption) {
-      super(name, NetworkInterface.class, socketOption);
-    }
-
-    @Override
-    public Integer validateAndConvertValueBeforeSet(FileDescriptor fd, NetworkInterface value) {
-      if (value == null) {
-        throw new IllegalArgumentException("value for " + name + " must not be null");
-      }
-      int nicIndex = value.getIndex();
-      if (nicIndex == -1) {
-        throw new IllegalArgumentException("The NetworkInterface must have a valid index");
-      }
-      return nicIndex;
-    }
-
-    @Override
-    public NetworkInterface validateAndConvertValueAfterGet(FileDescriptor fd, Object value) {
-      if (value == null) {
-        return null;
-      } else if (!(value instanceof Integer)) {
-        throw new AssertionError("Unexpected type of value returned for " + name);
-      }
-
-      int nicIndex = (Integer) value;
-      try {
-        return NetworkInterface.getByIndex(nicIndex);
-      } catch (SocketException e) {
-        throw new IllegalArgumentException(
-            "Unable to resolve NetworkInterface index: " + nicIndex, e);
-      }
-    }
-  }
-
-  /**
-   * A SocketOption capable of setting / getting an integer in the range 0-255.
-   */
-  private static class ByteRangeSocketOption extends SocketOptionImpl<Integer> {
-
-    public ByteRangeSocketOption(String name, int socketOption) {
-      super(name, Integer.class, socketOption);
-    }
-
-    @Override
-    protected Object validateAndConvertValueBeforeSet(FileDescriptor fd, Integer value) {
-      if (value == null || value < 0 || value > 255) {
-        throw new IllegalArgumentException(name + " must be >= 0 and <= 255, is " + value);
-      }
-      return value;
-    }
-
-    @Override
-    protected Integer validateAndConvertValueAfterGet(FileDescriptor fd, Object value) {
-      if (!(value instanceof Integer)) {
-        throw new AssertionError("Unexpected value for option " + name + ": " + value);
-      }
-      int intValue = (Integer) value;
-      if (intValue < 0 || intValue > 255) {
-        throw new AssertionError("Unexpected value for option " + name + ": " + value);
-      }
-      return intValue;
-    }
-  }
-
-  /**
-   * A SocketOption capable of setting / getting an integer in the range 1..
-   */
-  private static class PositiveIntegerSocketOption extends SocketOptionImpl<Integer> {
-
-    public PositiveIntegerSocketOption(String name, int socketOption) {
-      super(name, Integer.class, socketOption);
-    }
-
-    @Override
-    protected Integer validateAndConvertValueBeforeSet(FileDescriptor fd, Integer value) {
-      if (value < 1) {
-        throw new IllegalArgumentException(name + " value must be > 0");
-      }
-      return value;
-    }
-
-    @Override
-    protected Integer validateAndConvertValueAfterGet(FileDescriptor fd, Object value) {
-      if (!(value instanceof Integer)) {
-        throw new AssertionError("Unexpected value for option " + name + ": " + value);
-      }
-      int intValue = (Integer) value;
-      if (intValue < 1) {
-        throw new AssertionError("Unexpected value for option " + name + ": " + value);
-      }
-      return intValue;
-    }
-  }
-}
diff --git a/luni/src/main/java/java/net/URLConnection.java b/luni/src/main/java/java/net/URLConnection.java
index cc7de90..2fb3f45 100644
--- a/luni/src/main/java/java/net/URLConnection.java
+++ b/luni/src/main/java/java/net/URLConnection.java
@@ -316,17 +316,6 @@
     }
 
     /**
-     * Returns the content length in bytes specified by the response header field
-     * {@code content-length} or {@code -1} if this field is not set.
-     *
-     * @since 1.7
-     * @hide Until ready for a public API change
-     */
-    public long getContentLengthLong() {
-        return getHeaderFieldLong("Content-Length", -1);
-    }
-
-    /**
      * Returns the MIME-type of the content specified by the response header field
      * {@code content-type} or {@code null} if type is unknown.
      *
@@ -558,27 +547,6 @@
     }
 
     /**
-     * Returns the specified header value as a number. Returns the {@code
-     * defaultValue} if no such header field could be found or the value could
-     * not be parsed as a {@code long}.
-     *
-     * @param field
-     *            the header field name whose value is needed.
-     * @param defaultValue
-     *            the default value if no field has been found.
-     * @return the value of the specified header field as a number.
-     * @since 1.7
-     * @hide Until ready for a public API change
-     */
-    public long getHeaderFieldLong(String field, long defaultValue) {
-        try {
-            return Long.parseLong(getHeaderField(field));
-        } catch (NumberFormatException e) {
-            return defaultValue;
-        }
-    }
-
-    /**
      * Returns the name of the header field at the given position {@code posn} or
      * {@code null} if there are fewer than {@code posn} fields. The base
      * implementation of this method returns always {@code null}.
diff --git a/luni/src/main/java/java/nio/DatagramChannelImpl.java b/luni/src/main/java/java/nio/DatagramChannelImpl.java
index 8a5dbb6..e736c40 100644
--- a/luni/src/main/java/java/nio/DatagramChannelImpl.java
+++ b/luni/src/main/java/java/nio/DatagramChannelImpl.java
@@ -32,14 +32,10 @@
 import java.net.PlainDatagramSocketImpl;
 import java.net.SocketAddress;
 import java.net.SocketException;
-import java.net.SocketOption;
-import java.net.StandardSocketOptions;
-import java.nio.channels.AlreadyBoundException;
 import java.nio.channels.AlreadyConnectedException;
 import java.nio.channels.ClosedChannelException;
 import java.nio.channels.DatagramChannel;
 import java.nio.channels.IllegalBlockingModeException;
-import java.nio.channels.MembershipKey;
 import java.nio.channels.NotYetConnectedException;
 import java.nio.channels.spi.SelectorProvider;
 import java.nio.channels.UnresolvedAddressException;
@@ -79,9 +75,6 @@
     private final Object readLock = new Object();
     private final Object writeLock = new Object();
 
-    // A helper to manage multicast group membership. Created as required.
-    private MulticastMembershipHandler multicastMembershipHandler;
-
     /*
      * Constructor
      */
@@ -112,29 +105,6 @@
         return socket;
     }
 
-    /** @hide Until ready for a public API change */
-    @Override
-    synchronized public DatagramChannel bind(SocketAddress local) throws IOException {
-        checkOpen();
-        if (isBound) {
-            throw new AlreadyBoundException();
-        }
-
-        if (local == null) {
-            local = new InetSocketAddress(Inet4Address.ANY, 0);
-        } else if (!(local instanceof InetSocketAddress)) {
-            throw new UnsupportedAddressTypeException();
-        }
-
-        InetSocketAddress localAddress = (InetSocketAddress) local;
-        if (localAddress.isUnresolved()) {
-            throw new UnresolvedAddressException();
-        }
-        IoBridge.bind(fd, localAddress.getAddress(), localAddress.getPort());
-        onBind(true /* updateSocketState */);
-        return this;
-    }
-
     /**
      * Initialise the isBound, localAddress and localPort state from the file descriptor. Used when
      * some or all of the bound state has been left to the OS to decide, or when the Socket handled
@@ -162,34 +132,6 @@
 
     /** @hide Until ready for a public API change */
     @Override
-    synchronized public SocketAddress getLocalAddress() throws IOException {
-        checkOpen();
-        return isBound ? new InetSocketAddress(localAddress, localPort) : null;
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public <T> T getOption(SocketOption<T> option) throws IOException {
-        return NioUtils.getSocketOption(
-                this, StandardSocketOptions.DATAGRAM_SOCKET_OPTIONS, option);
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public <T> DatagramChannel setOption(SocketOption<T> option, T value) throws IOException {
-        checkOpen();
-        NioUtils.setSocketOption(
-                this, StandardSocketOptions.DATAGRAM_SOCKET_OPTIONS, option, value);
-        return this;
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public Set<SocketOption<?>> supportedOptions() {
-        return StandardSocketOptions.DATAGRAM_SOCKET_OPTIONS;
-    }
-
-    @Override
     synchronized public boolean isConnected() {
         return connected;
     }
@@ -524,7 +466,6 @@
         // A closed channel is not connected.
         onDisconnect(true /* updateSocketState */);
         IoBridge.closeAndSignalBlockedThreads(fd);
-        multicastMembershipHandler = null;
 
         if (socket != null && !socket.isClosed()) {
             socket.onClose();
@@ -570,52 +511,6 @@
         return fd;
     }
 
-    @Override
-    synchronized public MembershipKey join(InetAddress groupAddress,
-        NetworkInterface networkInterface) throws IOException {
-
-        checkOpen();
-        ensureMembershipHandlerExists();
-        return multicastMembershipHandler.addAnySourceMembership(networkInterface, groupAddress);
-    }
-
-    @Override
-    synchronized public MembershipKey join(
-            InetAddress groupAddress, NetworkInterface networkInterface, InetAddress sourceAddress)
-            throws IOException {
-        checkOpen();
-        ensureMembershipHandlerExists();
-        return multicastMembershipHandler.addSourceSpecificMembership(
-                networkInterface, groupAddress, sourceAddress);
-    }
-
-    synchronized void multicastDrop(MembershipKeyImpl membershipKey) {
-        ensureMembershipHandlerExists();
-        multicastMembershipHandler.dropMembership(membershipKey);
-    }
-
-    synchronized void multicastBlock(MembershipKeyImpl membershipKey, InetAddress sourceAddress)
-            throws SocketException {
-
-        ensureMembershipHandlerExists();
-        multicastMembershipHandler.block(membershipKey, sourceAddress);
-    }
-
-    synchronized void multicastUnblock(MembershipKeyImpl membershipKey, InetAddress sourceAddress) {
-        ensureMembershipHandlerExists();
-        multicastMembershipHandler.unblock(membershipKey, sourceAddress);
-    }
-
-    /**
-     * Creates the {@code multicastMembershipHandler} if one doesn't already exist. Callers must
-     * handle synchronization.
-     */
-    private void ensureMembershipHandlerExists() {
-        if (multicastMembershipHandler == null) {
-            multicastMembershipHandler = new MulticastMembershipHandler(this);
-        }
-    }
-
     /*
      * The adapter class of DatagramSocket
      */
diff --git a/luni/src/main/java/java/nio/MembershipKeyImpl.java b/luni/src/main/java/java/nio/MembershipKeyImpl.java
deleted file mode 100644
index 3d7e957..0000000
--- a/luni/src/main/java/java/nio/MembershipKeyImpl.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.nio;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.nio.channels.MembershipKey;
-import java.nio.channels.MulticastChannel;
-
-/**
- * An implementation of {@link MembershipKey}.
- *
- * To keep this class simple and keep all mutation operations in one place and easily synchronized,
- * most socket logic is held in {@link java.nio.DatagramChannelImpl}.
- */
-final class MembershipKeyImpl extends MembershipKey {
-
-  private final DatagramChannelImpl channel;
-  private final InetAddress groupAddress;
-  private final NetworkInterface networkInterface;
-  private final InetAddress sourceAddress;
-  private volatile boolean isValid;
-
-  public MembershipKeyImpl(DatagramChannelImpl channel, NetworkInterface networkInterface,
-      InetAddress groupAddress, InetAddress sourceAddress) {
-
-    this.channel = channel;
-    this.networkInterface = networkInterface;
-    this.groupAddress = groupAddress;
-    this.sourceAddress = sourceAddress;
-    this.isValid = true;
-  }
-
-  @Override
-  public boolean isValid() {
-    // invalidate() is called if the key is dropped, but for simplicity it is not
-    // invalidated when the channel is closed. Therefore, the channel must also be checked to see
-    // if it is still open.
-    return isValid && channel.isOpen();
-  }
-
-  void invalidate() {
-    this.isValid = false;
-  }
-
-  @Override
-  public void drop() {
-    channel.multicastDrop(this);
-  }
-
-  @Override
-  public MembershipKey block(InetAddress source) throws IOException {
-    channel.multicastBlock(this, source);
-    return this;
-  }
-
-  @Override
-  synchronized public MembershipKey unblock(InetAddress source) {
-    channel.multicastUnblock(this, source);
-    return this;
-  }
-
-  @Override
-  public MulticastChannel channel() {
-    return channel;
-  }
-
-  @Override
-  public InetAddress group() {
-    return groupAddress;
-  }
-
-  @Override
-  public NetworkInterface networkInterface() {
-    return networkInterface;
-  }
-
-  @Override
-  public InetAddress sourceAddress() {
-    return sourceAddress;
-  }
-
-  @Override
-  public String toString() {
-    return "MembershipKeyImpl{" +
-      "groupAddress=" + groupAddress +
-      ", networkInterface=" + networkInterface +
-      ", sourceAddress=" + sourceAddress +
-      '}';
-    }
-}
diff --git a/luni/src/main/java/java/nio/MulticastMembershipHandler.java b/luni/src/main/java/java/nio/MulticastMembershipHandler.java
deleted file mode 100644
index 2fe8130..0000000
--- a/luni/src/main/java/java/nio/MulticastMembershipHandler.java
+++ /dev/null
@@ -1,495 +0,0 @@
-package java.nio;
-
-import android.system.StructGroupReq;
-import android.system.StructGroupSourceReq;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.nio.channels.MembershipKey;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import libcore.io.IoBridge;
-
-/**
- * A helper class for {@link DatagramChannelImpl} that keeps track of multicast group
- * memberships. This class is not threadsafe, and relies on the DatagramChannelImpl to synchronize.
- *
- * <p>See <a href="http://tools.ietf.org/html/rfc3678">RFC 3678</a> for context and terminology.
- */
-final class MulticastMembershipHandler {
-
-  private final DatagramChannelImpl channel;
-  private final Map<Id, Membership> memberships = new HashMap<Id, Membership>();
-
-  MulticastMembershipHandler(DatagramChannelImpl channel) {
-    this.channel = channel;
-  }
-
-  /**
-   * The implementation for
-   * {@link java.nio.channels.MulticastChannel#join(InetAddress, NetworkInterface)}.
-   */
-  public MembershipKeyImpl addAnySourceMembership(
-      NetworkInterface networkInterface, InetAddress groupAddress) throws SocketException {
-
-    validateMulticastGroupArgs(groupAddress, networkInterface);
-    assertChannelOpen();
-
-    Id id = new Id(networkInterface, groupAddress);
-    Membership membership = memberships.get(id);
-    if (membership != null) {
-      return membership.getAnySourceMembershipKey();
-    }
-
-    // No existing membership found. Attempt to join.
-    StructGroupReq groupReq = makeGroupReq(groupAddress, networkInterface);
-    IoBridge.setSocketOption(channel.getFD(), IoBridge.JAVA_MCAST_JOIN_GROUP, groupReq);
-
-    // Record the membership and return the key.
-    membership = Membership.createAnySource(channel, networkInterface, groupAddress);
-    memberships.put(id, membership);
-    return membership.getAnySourceMembershipKey();
-  }
-
-  /**
-   * The implementation for
-   * {@link java.nio.channels.MulticastChannel#join(InetAddress, NetworkInterface, InetAddress)}.
-   */
-  public MembershipKeyImpl addSourceSpecificMembership(
-      NetworkInterface networkInterface, InetAddress groupAddress, InetAddress sourceAddress)
-      throws SocketException {
-
-    validateMulticastGroupArgs(groupAddress, networkInterface);
-    validateSourceAddress(sourceAddress);
-    validateAddressProtocolTheSame(groupAddress, sourceAddress);
-    assertChannelOpen();
-
-    Id id = new Id(networkInterface, groupAddress);
-    Membership membership = memberships.get(id);
-    if (membership != null) {
-      MembershipKeyImpl existingMembershipKey =
-          membership.getSourceSpecificMembershipKey(sourceAddress);
-      if (existingMembershipKey != null) {
-        return existingMembershipKey;
-      }
-    }
-
-    // No existing membership found. Attempt to join.
-    IoBridge.setSocketOption(channel.getFD(), IoBridge.JAVA_MCAST_JOIN_SOURCE_GROUP,
-        makeGroupSourceReq(groupAddress, networkInterface, sourceAddress));
-
-    if (membership == null) {
-      // Record the membership and return the key.
-      membership = Membership.createSourceSpecific(
-          channel, networkInterface, groupAddress, sourceAddress);
-      memberships.put(id, membership);
-      return membership.getSourceSpecificMembershipKey(sourceAddress);
-    } else {
-      // Add a new source to the existing membership.
-      return membership.addSource(sourceAddress);
-    }
-  }
-
-  /**
-   * The implementation for {@link MembershipKey#drop()}.
-   */
-  public void dropMembership(MembershipKeyImpl membershipKey) {
-    // For compatibility with the RI, this is one case where the membershipKey can no longer be
-    // valid.
-    if (!membershipKey.isValid()) {
-      return;
-    }
-    if (membershipKey.channel() != this.channel) {
-      throw new AssertionError("Bad membership key");
-    }
-    assertChannelOpen();
-
-    Id id = createId(membershipKey);
-    Membership membership = memberships.get(id);
-    if (membership == null) {
-      throw new AssertionError("Bad membership key" + membershipKey);
-    }
-
-    if (!membership.isSourceSpecific()) {
-      try {
-        StructGroupReq groupReq =
-            makeGroupReq(membershipKey.group(), membershipKey.networkInterface());
-        IoBridge.setSocketOption(channel.getFD(), IoBridge.JAVA_MCAST_LEAVE_GROUP, groupReq);
-      } catch (SocketException e) {
-        // TODO: Obtain opinion on how to report this, throw this or if it is safe to ignore.
-        throw new IllegalStateException(e);
-      }
-      memberships.remove(id);
-    } else {
-      StructGroupSourceReq groupSourceReq = makeGroupSourceReq(membershipKey.group(),
-          membershipKey.networkInterface(), membershipKey.sourceAddress());
-
-      try {
-        IoBridge.setSocketOption(
-            channel.getFD(), IoBridge.JAVA_MCAST_LEAVE_SOURCE_GROUP,
-            groupSourceReq);
-      } catch (SocketException e) {
-        // TODO: Obtain opinion on how to report this, throw this or if it is safe to ignore.
-        throw new IllegalStateException(e);
-      }
-
-      boolean isLast = membership.removeSource(membershipKey.sourceAddress());
-      if (isLast) {
-        memberships.remove(id);
-      }
-    }
-    membershipKey.invalidate();
-  }
-
-  /**
-   * The implementation for {@link MembershipKey#block(java.net.InetAddress)}.
-   */
-  public void block(MembershipKeyImpl membershipKey, InetAddress sourceAddress)
-      throws SocketException {
-    validateMembershipKey(membershipKey);
-    validateSourceAddress(sourceAddress);
-    validateAddressProtocolTheSame(membershipKey.group(), sourceAddress);
-    assertChannelOpen();
-
-    Membership membership = getMembershipForKey(membershipKey);
-    if (membership == null) {
-      throw new AssertionError("Bad membership key" + membershipKey);
-    }
-
-    if (membership.isBlocked(sourceAddress)) {
-      return;
-    }
-
-    IoBridge.setSocketOption(channel.getFD(), IoBridge.JAVA_MCAST_BLOCK_SOURCE,
-        makeGroupSourceReq(
-            membershipKey.group(), membershipKey.networkInterface(), sourceAddress));
-
-    membership.block(sourceAddress);
-  }
-
-  /**
-   * The implementation for {@link MembershipKey#unblock(java.net.InetAddress)}.
-   */
-  public void unblock(MembershipKeyImpl membershipKey, InetAddress sourceAddress) {
-    validateMembershipKey(membershipKey);
-    validateSourceAddress(sourceAddress);
-    validateAddressProtocolTheSame(membershipKey.group(), sourceAddress);
-    assertChannelOpen();
-
-    Membership membership = getMembershipForKey(membershipKey);
-    if (membership == null) {
-      throw new AssertionError("Bad membership key" + membershipKey);
-    }
-
-    if (!membership.isBlocked(sourceAddress)) {
-      throw new IllegalStateException(
-          "sourceAddress " + sourceAddress + " is not blocked for " + membership.debugId());
-    }
-
-    try {
-      IoBridge.setSocketOption(channel.getFD(), IoBridge.JAVA_MCAST_UNBLOCK_SOURCE,
-          makeGroupSourceReq(membershipKey.group(), membershipKey.networkInterface(),
-              sourceAddress));
-    } catch (SocketException e) {
-      throw new IllegalStateException(e);
-    }
-
-    membership.unblock(sourceAddress);
-  }
-
-  private Membership getMembershipForKey(MembershipKey membershipKey) {
-    Id id = createId(membershipKey);
-    Membership membership = memberships.get(id);
-    if (membership == null) {
-      throw new AssertionError("No membership found for id " + id);
-    }
-    return membership;
-  }
-
-  private void assertChannelOpen() {
-    if (!channel.isOpen()) {
-      throw new AssertionError("Channel is closed");
-    }
-  }
-
-  private void validateMembershipKey(MembershipKeyImpl membershipKey) {
-    if (membershipKey.channel() != this.channel) {
-      throw new AssertionError("Invalid or bad membership key");
-    }
-    if (!membershipKey.isValid()) {
-      throw new IllegalStateException("Membership key is no longer valid: " + membershipKey);
-    }
-  }
-
-  private static Id createId(MembershipKey membershipKey) {
-    return new Id(membershipKey.networkInterface(), membershipKey.group());
-  }
-
-  private static void validateSourceAddress(InetAddress sourceAddress) {
-    if (sourceAddress.isAnyLocalAddress()) {
-      throw new IllegalArgumentException(
-          "sourceAddress must not be a wildcard address, is " + sourceAddress);
-    }
-    if (sourceAddress.isMulticastAddress()) {
-      throw new IllegalArgumentException(
-          "sourceAddress must be a unicast address, is " + sourceAddress);
-    }
-  }
-
-  private static void validateMulticastGroupArgs(
-      InetAddress groupAddress, NetworkInterface networkInterface) throws SocketException {
-
-    if (groupAddress == null) {
-      // RI throws NullPointerException.
-      throw new NullPointerException("groupAddress == null");
-    }
-    if (networkInterface == null) {
-      // RI throws NullPointerException.
-      throw new NullPointerException("networkInterface == null");
-    }
-    if (!networkInterface.isLoopback() && !networkInterface.supportsMulticast()) {
-      throw new IllegalArgumentException(
-          "networkInterface " + networkInterface + " does not support multicast");
-    }
-    if (!groupAddress.isMulticastAddress()) {
-      throw new IllegalArgumentException("Not a multicast group: " + groupAddress);
-    }
-  }
-
-  private static void validateAddressProtocolTheSame(
-      InetAddress groupAddress, InetAddress sourceAddress) {
-
-    if (groupAddress.getClass() != sourceAddress.getClass()) {
-      throw new IllegalArgumentException("Mixed address types not permitted: groupAddress: " +
-          groupAddress + ", sourceAddress: " + sourceAddress);
-    }
-  }
-
-  private static StructGroupSourceReq makeGroupSourceReq(
-      InetAddress gsr_group, NetworkInterface networkInterface, InetAddress gsr_source) {
-    int gsr_interface = (networkInterface != null) ? networkInterface.getIndex() : 0;
-    return new StructGroupSourceReq(gsr_interface, gsr_group, gsr_source);
-  }
-
-  private static StructGroupReq makeGroupReq(InetAddress gr_group,
-      NetworkInterface networkInterface) {
-    int gr_interface = (networkInterface != null) ? networkInterface.getIndex() : 0;
-    return new StructGroupReq(gr_interface, gr_group);
-  }
-
-  /**
-   * Membership information associated with an {@link Id}. A membership can be one of two types:
-   * "source-specific" and "any-source". The two types a mutually exclusive for a given Id.
-   */
-  static final class Membership {
-
-    private final DatagramChannelImpl channel;
-    private final InetAddress groupAddress;
-    private final NetworkInterface networkInterface;
-
-    // Any-source membership key. Mutually exclusive with sourceSpecificMembershipKeys.
-    private final MembershipKeyImpl anySourceMembershipKey;
-    // Blocked source addresses for any-source memberships. Assigned when required.
-    private Set<InetAddress> blockedSourceAddresses;
-
-    // Source-specific membership keys. Mutually exclusive with anySourceMembershipKey.
-    private final Map<InetAddress, MembershipKeyImpl> sourceSpecificMembershipKeys;
-
-    /** Use {@link #createSourceSpecific} or {@link #createAnySource} to construct. */
-    private Membership(
-        DatagramChannelImpl channel,
-        InetAddress groupAddress,
-        NetworkInterface networkInterface,
-        MembershipKeyImpl anySourceMembershipKey,
-        Map<InetAddress, MembershipKeyImpl> sourceSpecificMembershipKeys) {
-
-      this.channel = channel;
-      this.groupAddress = groupAddress;
-      this.networkInterface = networkInterface;
-      this.anySourceMembershipKey = anySourceMembershipKey;
-      this.sourceSpecificMembershipKeys = sourceSpecificMembershipKeys;
-    }
-
-    /** Creates an any-source membership. */
-    public static Membership createAnySource(DatagramChannelImpl channel,
-        NetworkInterface networkInterface, InetAddress groupAddress) {
-
-      MembershipKeyImpl withoutSourceAddressKey =
-          new MembershipKeyImpl(channel, networkInterface, groupAddress, null /* sourceAddress */);
-      return new Membership(
-          channel, groupAddress, networkInterface, withoutSourceAddressKey,
-          null /* sourceSpecificMembershipKeys */);
-    }
-
-    /**
-     * Creates a source-specific membership. See {@link #addSource} to add additional source
-     * addresses.
-     */
-    public static Membership createSourceSpecific(DatagramChannelImpl channel,
-        NetworkInterface networkInterface, InetAddress groupAddress, InetAddress sourceAddress) {
-
-      Map<InetAddress, MembershipKeyImpl> withSourceKeys =
-          new HashMap<InetAddress, MembershipKeyImpl>();
-      Membership membership = new Membership(
-          channel, groupAddress, networkInterface, null /* anySourceMembershipKey */,
-          withSourceKeys);
-      membership.addSource(sourceAddress);
-      return membership;
-    }
-
-    /**
-     * Adds a new source address filter to an existing membership, returning the associated
-     * {@link MembershipKeyImpl}. Throws an {@code IllegalStateException} if this is an
-     * any-source membership.
-     */
-    public MembershipKeyImpl addSource(InetAddress sourceAddress) {
-      if (sourceSpecificMembershipKeys == null) {
-        throw new IllegalStateException(
-            "Can only add sources to source-specific memberships: " + debugId());
-      }
-
-      MembershipKeyImpl membershipKey =
-          new MembershipKeyImpl(channel, networkInterface, groupAddress, sourceAddress);
-      sourceSpecificMembershipKeys.put(sourceAddress, membershipKey);
-      return membershipKey;
-    }
-
-    /**
-     * Removes the specified {@code sourceAddress} from the set of filters. Returns {@code true} if
-     * the set of filters is now empty. Throws an {@code IllegalStateException} if this is an
-     * any-source membership.
-     */
-    public boolean removeSource(InetAddress sourceAddress) {
-      if (sourceSpecificMembershipKeys == null) {
-        throw new IllegalStateException(
-            "Can only remove sources from source-specific memberships: " + debugId());
-      }
-      sourceSpecificMembershipKeys.remove(sourceAddress);
-      return sourceSpecificMembershipKeys.isEmpty();
-    }
-
-    /**
-     * Returns {@code true} if the membership source-specific, false if it is any-source.
-     */
-    public boolean isSourceSpecific() {
-      return sourceSpecificMembershipKeys != null;
-    }
-
-    /**
-     * Returns the {@link MembershipKeyImpl} for this membership. Throws an
-     * {@code IllegalStateException} if this is not an any-source membership.
-     */
-    public MembershipKeyImpl getAnySourceMembershipKey() {
-      if (sourceSpecificMembershipKeys != null) {
-        throw new IllegalStateException(
-            "There an existing source-specific membership for " + debugId());
-      }
-      return anySourceMembershipKey;
-    }
-
-    /**
-     * Returns the {@link MembershipKeyImpl} for the specified {@code sourceAddress}. Throws an
-     * {@code IllegalStateException} if this is not a source-specific membership.
-     */
-    public MembershipKeyImpl getSourceSpecificMembershipKey(InetAddress sourceAddress) {
-      if (anySourceMembershipKey != null) {
-        throw new IllegalStateException("There an existing any-source membership for " + debugId());
-      }
-      return sourceSpecificMembershipKeys.get(sourceAddress);
-    }
-
-    /**
-     * Returns {@code true} if there is an existing block for the specified address. Throws an
-     * {@code IllegalStateException} if this is not an any-source membership.
-     */
-    public boolean isBlocked(InetAddress sourceAddress) {
-      if (anySourceMembershipKey == null) {
-        throw new IllegalStateException(
-            "block()/unblock() are only applicable for any-source memberships: " + debugId());
-      }
-      return blockedSourceAddresses != null && blockedSourceAddresses.contains(sourceAddress);
-    }
-
-    /**
-     * Adds a blocked address to this membership. Throws an {@code IllegalStateException} if
-     * the address is already blocked. Throws an {@code IllegalStateException} if this is not an
-     * any-source membership.
-     */
-    public void block(InetAddress sourceAddress) {
-      if (anySourceMembershipKey == null) {
-        throw new IllegalStateException(
-            "block() is not supported for source-specific group memberships: " + debugId());
-      }
-      if (blockedSourceAddresses == null) {
-        blockedSourceAddresses = new HashSet<InetAddress>();
-      }
-      if (!blockedSourceAddresses.add(sourceAddress)) {
-        throw new IllegalStateException(
-            "Could not block " + sourceAddress + ": it was already blocked for " + debugId());
-      }
-    }
-
-    /**
-     * Removes a blocked address from this membership. Throws an {@code IllegalStateException} if
-     * the address is not blocked. Throws an {@code IllegalStateException} if this is not an
-     * any-source membership.
-     */
-    public void unblock(InetAddress sourceAddress) {
-      if (anySourceMembershipKey == null) {
-        throw new IllegalStateException(
-            "unblock() is not supported for source-specific group memberships: " + debugId());
-      }
-      if (blockedSourceAddresses == null || !blockedSourceAddresses.remove(sourceAddress)) {
-        throw new IllegalStateException(
-            "Could not unblock " + sourceAddress + ": it was not blocked for " + debugId());
-      }
-    }
-
-    public String debugId() {
-      return "<" + networkInterface + ":" + groupAddress + ">";
-    }
-
-  }
-
-  /** An identifier for a multicast group membership, independent of membership type. */
-  private static final class Id {
-
-    private final InetAddress groupAddress;
-    private final NetworkInterface networkInterface;
-
-    public Id(NetworkInterface networkInterface, InetAddress groupAddress) {
-      this.groupAddress = groupAddress;
-      this.networkInterface = networkInterface;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-      if (this == o) {
-        return true;
-      }
-      if (!(o instanceof Id)) {
-        return false;
-      }
-
-      Id id = (Id) o;
-
-      if (!groupAddress.equals(id.groupAddress)) {
-        return false;
-      }
-      if (!networkInterface.equals(id.networkInterface)) {
-        return false;
-      }
-
-      return true;
-    }
-
-    @Override
-    public int hashCode() {
-      int result = groupAddress.hashCode();
-      result = 31 * result + networkInterface.hashCode();
-      return result;
-    }
-  }
-}
diff --git a/luni/src/main/java/java/nio/NioUtils.java b/luni/src/main/java/java/nio/NioUtils.java
index 51adddb..f2a0b10 100644
--- a/luni/src/main/java/java/nio/NioUtils.java
+++ b/luni/src/main/java/java/nio/NioUtils.java
@@ -19,8 +19,6 @@
 import java.io.Closeable;
 import java.io.FileDescriptor;
 import java.io.IOException;
-import java.net.SocketOption;
-import java.net.StandardSocketOptions;
 import java.nio.channels.ClosedChannelException;
 import java.nio.channels.FileChannel;
 import java.util.Set;
@@ -68,66 +66,4 @@
     public static int unsafeArrayOffset(ByteBuffer b) {
         return ((ByteArrayBuffer) b).arrayOffset;
     }
-
-    /**
-     * Sets the supplied option on the channel to have the value if option is a member of
-     * allowedOptions.
-     *
-     * @throws IOException
-     *          if the value could not be set due to IO errors.
-     * @throws IllegalArgumentException
-     *          if the socket option or the value is invalid.
-     * @throws UnsupportedOperationException
-     *          if the option is not a member of allowedOptions.
-     * @throws ClosedChannelException
-     *          if the channel is closed
-     */
-    public static <T> void setSocketOption(
-            FileDescriptorChannel channel, Set<SocketOption<?>> allowedOptions,
-            SocketOption<T> option, T value)
-            throws IOException {
-
-        if (!(option instanceof StandardSocketOptions.SocketOptionImpl)) {
-            throw new IllegalArgumentException("SocketOption must come from StandardSocketOptions");
-        }
-        if (!allowedOptions.contains(option)) {
-            throw new UnsupportedOperationException(
-                    option + " is not supported for this type of socket");
-        }
-        if (!channel.getFD().valid()) {
-            throw new ClosedChannelException();
-        }
-        ((StandardSocketOptions.SocketOptionImpl<T>) option).setValue(channel.getFD(), value);
-    }
-
-    /**
-     * Gets the supplied option from the channel if option is a member of allowedOptions.
-     *
-     * @throws IOException
-     *          if the value could not be read due to IO errors.
-     * @throws IllegalArgumentException
-     *          if the socket option is invalid.
-     * @throws UnsupportedOperationException
-     *          if the option is not a member of allowedOptions.
-     * @throws ClosedChannelException
-     *          if the channel is closed
-     */
-    public static <T> T getSocketOption(
-            FileDescriptorChannel channel, Set<SocketOption<?>> allowedOptions,
-            SocketOption<T> option)
-            throws IOException {
-
-        if (!(option instanceof StandardSocketOptions.SocketOptionImpl)) {
-            throw new IllegalArgumentException("SocketOption must come from StandardSocketOptions");
-        }
-        if (!allowedOptions.contains(option)) {
-            throw new UnsupportedOperationException(
-                    option + " is not supported for this type of socket");
-        }
-        if (!channel.getFD().valid()) {
-            throw new ClosedChannelException();
-        }
-        return ((StandardSocketOptions.SocketOptionImpl<T>) option).getValue(channel.getFD());
-    }
-
 }
diff --git a/luni/src/main/java/java/nio/ServerSocketChannelImpl.java b/luni/src/main/java/java/nio/ServerSocketChannelImpl.java
index d2cbf36..7185c32 100644
--- a/luni/src/main/java/java/nio/ServerSocketChannelImpl.java
+++ b/luni/src/main/java/java/nio/ServerSocketChannelImpl.java
@@ -24,10 +24,7 @@
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.net.SocketAddress;
-import java.net.SocketOption;
 import java.net.SocketTimeoutException;
-import java.net.StandardSocketOptions;
-import java.nio.channels.AlreadyBoundException;
 import java.nio.channels.ClosedChannelException;
 import java.nio.channels.IllegalBlockingModeException;
 import java.nio.channels.NotYetBoundException;
@@ -60,56 +57,6 @@
 
     /** @hide Until ready for a public API change */
     @Override
-    public final ServerSocketChannel bind(SocketAddress localAddr, int backlog) throws IOException {
-        if (!isOpen()) {
-            throw new ClosedChannelException();
-        }
-        if (socket.isBound()) {
-            throw new AlreadyBoundException();
-        }
-        if (localAddr != null) {
-            if (!(localAddr instanceof InetSocketAddress)) {
-                throw new UnsupportedAddressTypeException();
-            }
-            InetSocketAddress localInetAddress = (InetSocketAddress) localAddr;
-            if (localInetAddress.isUnresolved()) {
-                throw new UnresolvedAddressException();
-            }
-        }
-
-        socket.bind(localAddr, backlog);
-        return this;
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public SocketAddress getLocalAddress() throws IOException {
-        if (!isOpen()) {
-            throw new ClosedChannelException();
-        }
-        return socket.getLocalSocketAddress();
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public <T> T getOption(SocketOption<T> option) throws IOException {
-        return NioUtils.getSocketOption(this, StandardSocketOptions.SERVER_SOCKET_OPTIONS, option);
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public <T> ServerSocketChannel setOption(SocketOption<T> option, T value) throws IOException {
-        NioUtils.setSocketOption(this, StandardSocketOptions.SERVER_SOCKET_OPTIONS, option, value);
-        return this;
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public Set<SocketOption<?>> supportedOptions() {
-        return StandardSocketOptions.SERVER_SOCKET_OPTIONS;
-    }
-
-    @Override
     public SocketChannel accept() throws IOException {
         if (!isOpen()) {
             throw new ClosedChannelException();
diff --git a/luni/src/main/java/java/nio/SocketChannelImpl.java b/luni/src/main/java/java/nio/SocketChannelImpl.java
index 7c3cd78..d5cb716c 100644
--- a/luni/src/main/java/java/nio/SocketChannelImpl.java
+++ b/luni/src/main/java/java/nio/SocketChannelImpl.java
@@ -32,10 +32,7 @@
 import java.net.Socket;
 import java.net.SocketAddress;
 import java.net.SocketException;
-import java.net.SocketOption;
 import java.net.SocketUtils;
-import java.net.StandardSocketOptions;
-import java.nio.channels.AlreadyBoundException;
 import java.nio.channels.AlreadyConnectedException;
 import java.nio.channels.ClosedChannelException;
 import java.nio.channels.ConnectionPendingException;
@@ -139,31 +136,6 @@
         return socket;
     }
 
-    /** @hide Until ready for a public API change */
-    @Override
-    synchronized public final SocketChannel bind(SocketAddress local) throws IOException {
-        if (!isOpen()) {
-            throw new ClosedChannelException();
-        }
-        if (isBound) {
-            throw new AlreadyBoundException();
-        }
-
-        if (local == null) {
-            local = new InetSocketAddress(Inet4Address.ANY, 0);
-        } else if (!(local instanceof InetSocketAddress)) {
-            throw new UnsupportedAddressTypeException();
-        }
-
-        InetSocketAddress localAddress = (InetSocketAddress) local;
-        if (localAddress.isUnresolved()) {
-            throw new UnresolvedAddressException();
-        }
-        IoBridge.bind(fd, localAddress.getAddress(), localAddress.getPort());
-        onBind(true /* updateSocketState */);
-        return this;
-    }
-
     /**
      * Initialise the isBound, localAddress and localPort state from the file descriptor. Used when
      * some or all of the bound state has been left to the OS to decide, or when the Socket handled
@@ -189,34 +161,6 @@
         }
     }
 
-    /** @hide Until ready for a public API change */
-    @Override
-    synchronized public SocketAddress getLocalAddress() throws IOException {
-        if (!isOpen()) {
-            throw new ClosedChannelException();
-        }
-        return isBound ? new InetSocketAddress(localAddress, localPort) : null;
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public <T> T getOption(SocketOption<T> option) throws IOException {
-        return NioUtils.getSocketOption(this, StandardSocketOptions.SOCKET_OPTIONS, option);
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public <T> SocketChannel setOption(SocketOption<T> option, T value) throws IOException {
-        NioUtils.setSocketOption(this, StandardSocketOptions.SOCKET_OPTIONS, option, value);
-        return this;
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public Set<SocketOption<?>> supportedOptions() {
-        return StandardSocketOptions.SOCKET_OPTIONS;
-    }
-
     @Override
     synchronized public boolean isConnected() {
         return status == SOCKET_STATUS_CONNECTED;
diff --git a/luni/src/main/java/java/nio/channels/AlreadyBoundException.java b/luni/src/main/java/java/nio/channels/AlreadyBoundException.java
deleted file mode 100644
index 0a35fc3..0000000
--- a/luni/src/main/java/java/nio/channels/AlreadyBoundException.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.nio.channels;
-
-/**
- * An {@code AlreadyBoundException} is thrown when an attempt is made to bind a NetworkChannel that
- * is already bound.
- *
- * @hide Until ready for a public API change
- */
-public class AlreadyBoundException extends IllegalStateException {
-
-  private static final long serialVersionUID = 6796072983322737592L;
-
-  public AlreadyBoundException() {
-  }
-}
diff --git a/luni/src/main/java/java/nio/channels/DatagramChannel.java b/luni/src/main/java/java/nio/channels/DatagramChannel.java
index 3a5d1cc..2cff7f0 100644
--- a/luni/src/main/java/java/nio/channels/DatagramChannel.java
+++ b/luni/src/main/java/java/nio/channels/DatagramChannel.java
@@ -22,7 +22,6 @@
 import java.net.InetAddress;
 import java.net.NetworkInterface;
 import java.net.SocketAddress;
-import java.net.SocketOption;
 import java.nio.ByteBuffer;
 import java.nio.channels.spi.AbstractSelectableChannel;
 import java.nio.channels.spi.SelectorProvider;
@@ -44,7 +43,7 @@
  * same time.
  */
 public abstract class DatagramChannel extends AbstractSelectableChannel
-        implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, MulticastChannel {
+        implements ByteChannel, ScatteringByteChannel, GatheringByteChannel {
 
     /**
      * Constructs a new {@code DatagramChannel}.
@@ -92,64 +91,6 @@
      */
     public abstract DatagramSocket socket();
 
-    /** @hide Until ready for a public API change */
-    @Override
-    public DatagramChannel bind(SocketAddress local) throws IOException {
-        // This method was added for interoperability with Java 7, where it is abstract. It is
-        // concrete here to avoid breaking existing Android applications that extend this class.
-        throw new UnsupportedOperationException("Subclasses must override this method");
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public SocketAddress getLocalAddress() throws IOException {
-        // This method was added for interoperability with Java 7, where it is abstract. It is
-        // concrete here to avoid breaking existing Android applications that extend this class.
-        throw new UnsupportedOperationException("Subclasses must override this method");
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public <T> T getOption(SocketOption<T> option) throws IOException {
-        // This method was added for interoperability with Java 7, where it is abstract. It is
-        // concrete here to avoid breaking existing Android applications that extend this class.
-        throw new UnsupportedOperationException("Subclasses must override this method");
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public <T> DatagramChannel setOption(SocketOption<T> option, T value) throws IOException {
-        // This method was added for interoperability with Java 7, where it is abstract. It is
-        // concrete here to avoid breaking existing Android applications that extend this class.
-        throw new UnsupportedOperationException("Subclasses must override this method");
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public Set<SocketOption<?>> supportedOptions() {
-        // This method was added for interoperability with Java 7, where it is abstract. It is
-        // concrete here to avoid breaking existing Android applications that extend this class.
-        throw new UnsupportedOperationException("Subclasses must override this method");
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public MembershipKey join(InetAddress groupAddress, NetworkInterface networkInterface)
-            throws IOException {
-        // This method was added for interoperability with Java 7, where it is abstract. It is
-        // concrete here to avoid breaking existing Android applications that extend this class.
-        throw new UnsupportedOperationException("Subclasses must override this method");
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public MembershipKey join(InetAddress groupAddress, NetworkInterface networkInterface,
-            InetAddress sourceAddress) throws IOException {
-        // This method was added for interoperability with Java 7, where it is abstract. It is
-        // concrete here to avoid breaking existing Android applications that extend this class.
-        throw new UnsupportedOperationException("Subclasses must override this method");
-    }
-
     /**
      * Returns whether this channel's socket is connected or not.
      *
diff --git a/luni/src/main/java/java/nio/channels/FileChannel.java b/luni/src/main/java/java/nio/channels/FileChannel.java
index e5f2862c..d6c140b 100644
--- a/luni/src/main/java/java/nio/channels/FileChannel.java
+++ b/luni/src/main/java/java/nio/channels/FileChannel.java
@@ -76,9 +76,8 @@
  * stream and vice versa; this includes modifications to the file position,
  * content, size, etc.
  */
-// TODO: Remove ByteChannel when SeekableByteChannel is unhidden.
 public abstract class FileChannel extends AbstractInterruptibleChannel
-        implements GatheringByteChannel, ScatteringByteChannel, ByteChannel, SeekableByteChannel {
+        implements ByteChannel, GatheringByteChannel, ScatteringByteChannel {
 
     /**
      * {@code MapMode} defines file mapping mode constants.
@@ -282,21 +281,65 @@
             long position, long size) throws IOException;
 
     /**
-     * {@inheritDoc}
+     * Returns the current position as a positive integer number of bytes from
+     * the start of the file.
+     *
+     * @throws ClosedChannelException
+     *             if this channel is closed.
+     * @throws IOException
+     *             if another I/O error occurs.
      */
-    @Override
     public abstract long position() throws IOException;
 
     /**
-     * {@inheritDoc}
+     * Sets the file position pointer to a new value.
+     * <p>
+     * The argument is the number of bytes counted from the start of the file.
+     * The position cannot be set to a value that is negative. The new position
+     * can be set beyond the current file size. If set beyond the current file
+     * size, attempts to read will return end of file. Write operations will
+     * succeed but they will fill the bytes between the current end of file and
+     * the new position with the required number of (unspecified) byte values.
+     *
+     * @return this.
+     * @throws IllegalArgumentException
+     *             if the new position is negative.
+     * @throws ClosedChannelException
+     *             if this channel is closed.
+     * @throws IOException
+     *             if another I/O error occurs.
      */
-    @Override
     public abstract FileChannel position(long newPosition) throws IOException;
 
     /**
-     * {@inheritDoc}
+     * Reads bytes from this file channel into the given buffer.
+     * <p>
+     * The maximum number of bytes that will be read is the remaining number of
+     * bytes in the buffer when the method is invoked. The bytes will be copied
+     * into the buffer starting at the buffer's current position.
+     * <p>
+     * The call may block if other threads are also attempting to read from this
+     * channel.
+     * <p>
+     * Upon completion, the buffer's position is set to the end of the bytes
+     * that have been read. The buffer's limit is not changed.
+     *
+     * @param buffer
+     *            the byte buffer to receive the bytes.
+     * @return the number of bytes actually read.
+     * @throws AsynchronousCloseException
+     *             if another thread closes the channel during the read.
+     * @throws ClosedByInterruptException
+     *             if another thread interrupts the calling thread during the
+     *             read.
+     * @throws ClosedChannelException
+     *             if this channel is closed.
+     * @throws IOException
+     *             if another I/O error occurs, details are in the message.
+     * @throws NonReadableChannelException
+     *             if the channel has not been opened in a mode that permits
+     *             reading.
      */
-    @Override
     public abstract int read(ByteBuffer buffer) throws IOException;
 
     /**
@@ -411,9 +454,13 @@
             throws IOException;
 
     /**
-     * {@inheritDoc}
+     * Returns the size of the file underlying this channel in bytes.
+     *
+     * @throws ClosedChannelException
+     *             if this channel is closed.
+     * @throws IOException
+     *             if an I/O error occurs while getting the size of the file.
      */
-    @Override
     public abstract long size() throws IOException;
 
     /**
@@ -491,9 +538,25 @@
             WritableByteChannel target) throws IOException;
 
     /**
-     * {@inheritDoc}
+     * Truncates the file underlying this channel to a given size. Any bytes
+     * beyond the given size are removed from the file. If there are no bytes
+     * beyond the given size then the file contents are unmodified.
+     * <p>
+     * If the file position is currently greater than the given size, then it is
+     * set to the new size.
+     *
+     * @param size
+     *            the maximum size of the underlying file.
+     * @throws IllegalArgumentException
+     *             if the requested size is negative.
+     * @throws ClosedChannelException
+     *             if this channel is closed.
+     * @throws NonWritableChannelException
+     *             if the channel cannot be written to.
+     * @throws IOException
+     *             if another I/O error occurs.
+     * @return this channel.
      */
-    @Override
     public abstract FileChannel truncate(long size) throws IOException;
 
     /**
@@ -554,9 +617,30 @@
             throws IOException;
 
     /**
-     * {@inheritDoc}
+     * Writes bytes from the given byte buffer to this file channel.
+     * <p>
+     * The bytes are written starting at the current file position, and after
+     * some number of bytes are written (up to the remaining number of bytes in
+     * the buffer) the file position is increased by the number of bytes
+     * actually written.
+     *
+     * @param src
+     *            the byte buffer containing the bytes to be written.
+     * @return the number of bytes actually written.
+     * @throws NonWritableChannelException
+     *             if the channel was not opened for writing.
+     * @throws ClosedChannelException
+     *             if the channel was already closed.
+     * @throws AsynchronousCloseException
+     *             if another thread closes the channel during the write.
+     * @throws ClosedByInterruptException
+     *             if another thread interrupts the calling thread while this
+     *             operation is in progress. The interrupt state of the calling
+     *             thread is set and the channel is closed.
+     * @throws IOException
+     *             if another I/O error occurs, details are in the message.
+     * @see java.nio.channels.WritableByteChannel#write(java.nio.ByteBuffer)
      */
-    @Override
     public abstract int write(ByteBuffer src) throws IOException;
 
     /**
diff --git a/luni/src/main/java/java/nio/channels/FileLock.java b/luni/src/main/java/java/nio/channels/FileLock.java
index 037537c..5b26475 100644
--- a/luni/src/main/java/java/nio/channels/FileLock.java
+++ b/luni/src/main/java/java/nio/channels/FileLock.java
@@ -114,17 +114,6 @@
     }
 
     /**
-     * Returns the {@link Channel} that holds this lock.
-     *
-     * @since 1.7
-     * @hide Until ready for an API update
-     */
-    // TODO: unhiding, add to channel():  This method has been superseded by {@link #acquiredBy()}.
-    public Channel acquiredBy() {
-        return channel;
-    }
-
-    /**
      * Returns the lock's starting position in the file.
      *
      * @return the lock position.
diff --git a/luni/src/main/java/java/nio/channels/MembershipKey.java b/luni/src/main/java/java/nio/channels/MembershipKey.java
deleted file mode 100644
index 18ff92d..0000000
--- a/luni/src/main/java/java/nio/channels/MembershipKey.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.nio.channels;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-
-/**
- * A token produced as the result of joining a multicast group with
- * {@link DatagramChannel#join(java.net.InetAddress, java.net.NetworkInterface)} or
- * {@link DatagramChannel#join(java.net.InetAddress, java.net.NetworkInterface,
- * java.net.InetAddress)}.
- *
- * <p>A multicast group membership can be source-specific or any-source. Source-specific memberships
- * only allow datagrams from a single source address to be received. Any-source memberships
- * initially allow datagrams from any source address to be received, but may have individual unicast
- * IP addresses blocked via {@link #block(java.net.InetAddress)}. Any-source membership keys return
- * {@code null} from {@link #sourceAddress()}.
- *
- * <p>See <a href="http://tools.ietf.org/html/rfc3678">RFC 3678: Socket Interface Extensions for
- * Multicast Source Filters</a> for concepts and terminology associated with multicast membership.
- *
- * @since 1.7
- * @hide Until ready for a public API change
- */
-public abstract class MembershipKey {
-
-  protected MembershipKey() {}
-
-  /**
-   * Returns {@code true} until the membership is dropped with {@link #drop()} or the associated
-   * channel is closed.
-   */
-  public abstract boolean isValid();
-
-  /**
-   * Drops this membership from the multicast group, invalidating this key.
-   */
-  public abstract void drop();
-
-  /**
-   * Blocks datagrams from the specified source address; after this call any datagrams received from
-   * the address will be discarded. Blocking an already-blocked source address has no effect. A
-   * blocked address can be unblocked by calling {@link #unblock(java.net.InetAddress)}.
-   *
-   * <p>The block may not take effect instantaneously: datagrams that are already buffered by the
-   * underlying OS may still be delivered.
-   *
-   * <p>There is an OS-level limit on the number of source addresses that can be block for a given
-   * {@code groupAddress}, {@code networkInterface} pair. This is typically 10. Attempts to add
-   * more than this result in a {@code SocketException}.
-   *
-   * <p>If this membership key is source-specific an {@link IllegalStateException} is thrown.
-   *
-   * @throws IllegalStateException
-   *         if this membership key is no longer valid or is of the wrong type
-   * @throws IllegalArgumentException
-   *         if the source address is not unicast address of the same type as the multicast group
-   *         address supplied when the group was joined
-   * @throws IOException
-   *         if an I/O error occurs.
-   */
-  public abstract MembershipKey block(InetAddress source) throws IOException;
-
-  /**
-   * Unblocks datagrams from the specified source address that were previously blocked with a call
-   * to {@link #block(java.net.InetAddress)}; after this call any datagrams received from the
-   * address will be received. Unblocking an address that is not currently blocked throws an
-   * {@code IllegalStateException}.
-   *
-   * <p>If this membership key is source-specific an {@link IllegalStateException} is thrown.
-   *
-   * @throws IllegalStateException
-   *         if this membership key is no longer valid or is of the wrong type, or the address is
-   *         not currently blocked
-   * @throws IllegalArgumentException
-   *         if the source address is not unicast address of the same type as the multicast group
-   *         address supplied when the group was joined
-   */
-  public abstract MembershipKey unblock(InetAddress source);
-
-  /**
-   * Returns the {@code MulticastChannel} associated with this key. Continues returning the value
-   * even when the key has been invalidated.
-   */
-  public abstract MulticastChannel channel();
-
-  /**
-   * Returns the multicast group address associated with this key. Continues returning the value
-   * even when the key has been invalidated.
-   */
-  public abstract InetAddress group();
-
-  /**
-   * Returns the network interface associated with this key. Continues returning the value
-   * even when the key has been invalidated.
-   */
-  public abstract NetworkInterface networkInterface();
-
-  /**
-   * Returns the source address associated with this key if the membership is source-specific.
-   * Returns {@code null} if the membership is any-source. Continues returning the value
-   * even when the key has been invalidated.
-   */
-  public abstract InetAddress sourceAddress();
-}
diff --git a/luni/src/main/java/java/nio/channels/MulticastChannel.java b/luni/src/main/java/java/nio/channels/MulticastChannel.java
deleted file mode 100644
index 41ef501..0000000
--- a/luni/src/main/java/java/nio/channels/MulticastChannel.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.nio.channels;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-
-/**
- * A type of {@link NetworkChannel} that supports IP multicasting. IP multicasting allows for
- * efficient routing of an IP datagram to multiple hosts. Hosts wishing to receive multicast
- * datagrams join a multicast group identified by a multicast IP address.
- *
- * <p>Any datagram socket can be used to <em>send</em> to a multicast group: senders <em>do not</em>
- * have to be a member of the group.
- *
- * <p>See <a href="http://www.ietf.org/rfc/rfc2236.txt">RFC 2236: Internet Group Management
- * Protocol, Version 2</a> and <a href="http://www.ietf.org/rfc/rfc3376.txt">RFC 3376: Internet
- * Group Management Protocol, Version 3</a> for network-level information regarding IPv4 group
- * membership. See <a href="http://www.ietf.org/rfc/rfc2710.txt">RFC 2710: Multicast Listener
- * Discovery (MLD) for IPv6</a> and <a href="http://www.ietf.org/rfc/rfc3810.txt">RFC 3810:
- * Multicast Listener Discovery Version 2 (MLDv2) for IPv6</a> for equivalent IPv6 information.
- *
- * <p>See <a href="http://tools.ietf.org/html/rfc3678">RFC 3678: Socket Interface Extensions for
- * Multicast Source Filters</a> for concepts and terminology associated with multicast membership.
- *
- * <p>IP multicast requires support from network infrastructure; networks may not support
- * all features of IP multicast.
- *
- * <p>A channel can be restricted to send multicast datagrams through a specific
- * {@link NetworkInterface} by using {@link #setOption(java.net.SocketOption, Object)} with
- * {@link java.net.StandardSocketOptions#IP_MULTICAST_IF}.
- *
- * <p>A channel may or may not receive multicast datagrams sent from this host, determined by the
- * {@link java.net.StandardSocketOptions#IP_MULTICAST_LOOP} option.
- *
- * <p>The time-to-live for multicast datagrams can be set using the
- * {@link java.net.StandardSocketOptions#IP_MULTICAST_TTL} option.
- *
- * <p>Usually multicast channels should have {@link java.net.StandardSocketOptions#SO_REUSEADDR}
- * set to {@code true} before binding to enable multiple sockets on this host to be members of
- * the same multicast group.
- *
- * <p>Typically multicast channels are {@link NetworkChannel#bind bound} to a wildcard address
- * such as "0.0.0.0" (IPv4) or "::" (IPv6). They may also be bound to a multicast group address.
- * Binding to a multicast group address restricts datagrams received to only those sent to the
- * multicast group. When the wildcard address is used the socket may join multiple groups and also
- * receive non-multicast datagrams sent directly to the host. The port the channel is bound to is
- * important: only datagrams sent to the group on that port will be received.
- *
- * <p>Having bound a channel, the group can be joined. Memberships are either "any-source" or
- * "source-specific". The type of membership is determined by the variant of {@code join} that is
- * used. See {@link #join(java.net.InetAddress, java.net.NetworkInterface)} and
- * {@link #join(java.net.InetAddress, java.net.NetworkInterface, java.net.InetAddress)} for more
- * information.
- *
- * @since 1.7
- * @hide Until ready for a public API change
- */
-public interface MulticastChannel extends NetworkChannel {
-
-  // @hide Until ready for a public API change
-  // /**
-  //  * {@inheritDoc}
-  //  *
-  //  * If the channel is currently part of one or more multicast groups then the memberships are
-  // * dropped and any associated {@code MembershipKey} objects are invalidated.
-  // */
-  void close() throws IOException;
-
-  /**
-   * Creates an any-source membership to the {@code groupAddress} on the specified
-   * {@code networkInterface}. Returns a {@code MembershipKey} that can be used to modify or
-   * {@link MembershipKey#drop()} the membership. See {@link MembershipKey#block(InetAddress)} and
-   * {@link MembershipKey#unblock(InetAddress)} for methods to modify source-address
-   * filtering.
-   *
-   * <p>A channel may join several groups. Each membership is network interface-specific: an
-   * application must join the group for each applicable network interface to receive datagrams.
-   *
-   * <p>Any-source and source-specific memberships cannot be mixed for a group address on a given
-   * network interface. An {@code IllegalStateException} will be thrown if joins of different types
-   * are attempted for a given {@code groupAddress}, {@code networkInterface} pair. Joining a
-   * multicast group with the same arguments as an existing, valid membership returns the same
-   * {@code MembershipKey}.
-   *
-   * <p>There is an OS-level limit on the number of multicast groups a process can join.
-   * This is typically 20. Attempts to join more than this result in a {@code SocketException}.
-   *
-   * @param groupAddress the multicast group address to join
-   * @param networkInterface the network address to join with
-   * @throws IllegalArgumentException
-   *         if the group address is not a multicast address or the network interface does not
-   *         support multicast
-   * @throws IllegalStateException
-   *         if the channel already has a source-specific membership for the group/network interface
-   * @throws ClosedChannelException
-   *         if the channel is closed
-   * @throws IOException
-   *         if some other I/O error occurs
-   * @hide Until ready for a public API change
-   */
-  MembershipKey join(InetAddress groupAddress, NetworkInterface networkInterface)
-      throws IOException;
-
-  /**
-   * Creates a source-specific membership to the {@code groupAddress} on the specified
-   * {@code networkInterface} filtered by the {@code sourceAddress}. Returns a
-   * {@code MembershipKey} that can be used to {@link MembershipKey#drop()} the membership.
-   *
-   * <p>A channel may join several groups. Each membership is network interface-specific: an
-   * application must join the group for each applicable network interface to receive datagrams.
-   *
-   * <p>Any-source and source-specific memberships cannot be mixed for a group address on a given
-   * network interface. An {@code IllegalStateException} will be thrown if joins of different types
-   * are attempted for a given {@code groupAddress}, {@code networkInterface} pair. Joining a
-   * multicast group with the same arguments as an existing, valid membership returns the same
-   * {@code MembershipKey}.
-   *
-   * <p>There is an OS-level limit on the number of multicast groups a process can join.
-   * This is typically 20. Attempts to join more than this result in a {@code SocketException}.
-   *
-   * <p>There is an OS-level limit on the number of source addresses that can be joined for a given
-   * {@code groupAddress}, {@code networkInterface} pair. This is typically 10. Attempts to add
-   * more than this result in a {@code SocketException}.
-   *
-   * @param groupAddress the multicast group address to join
-   * @param networkInterface the network address to join with
-   * @param sourceAddress the source address to restrict datagrams to
-   * @throws IllegalArgumentException
-   *         if the group address is not a multicast address, the network interface does not
-   *         support multicast, or the {@code groupAddress} and {@code sourceAddress} are not of
-   *         compatible types
-   * @throws IllegalStateException
-   *         if the channel already has a source-specific membership for the group/network interface
-   * @throws ClosedChannelException
-   *         if the channel is closed
-   * @throws IOException
-   *         if some other I/O error occurs
-   * @hide Until ready for a public API change
-   */
-  MembershipKey join(
-      InetAddress groupAddress, NetworkInterface networkInterface, InetAddress sourceAddress)
-      throws IOException;
-
-}
diff --git a/luni/src/main/java/java/nio/channels/NetworkChannel.java b/luni/src/main/java/java/nio/channels/NetworkChannel.java
deleted file mode 100644
index 9b46e30..0000000
--- a/luni/src/main/java/java/nio/channels/NetworkChannel.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.nio.channels;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.net.SocketAddress;
-import java.net.SocketOption;
-import java.util.Set;
-
-/**
- * A common interface for channels that are backed by network sockets.
- *
- * @since 1.7
- * @hide Until ready for a public API change
- */
-public interface NetworkChannel extends AutoCloseable, Channel, Closeable {
-
-  /**
-   * Binds this channel to the given local socket address. If the {@code localAddr} is set
-   * to {@code null} the socket will be bound to an available local address on any free port of
-   * the system.
-   *
-   * @param local
-   *     the local machine address and port to bind on.
-   * @return this channel.
-   * @throws UnsupportedAddressTypeException
-   *     if the {@code SocketAddress} is not supported.
-   * @throws ClosedChannelException
-   *     if the channel is closed.
-   * @throws AlreadyBoundException
-   *     if the channel is already bound.
-   * @throws IOException
-   *     if another I/O error occurs.
-   * @hide Until ready for a public API change
-   */
-  NetworkChannel bind(SocketAddress local) throws IOException;
-
-  /**
-   * Returns the local socket address the channel is bound to. The socket may be bound explicitly
-   * via {@link #bind(java.net.SocketAddress)} or similar methods, or as a side-effect when other
-   * methods are called, depending on the implementation. If the channel is not bound {@code null}
-   * is returned.
-   *
-   * <p>If IP is being used, the returned object will be a subclass of
-   * {@link java.net.InetSocketAddress}
-   *
-   * @return the local socket address, or {@code null} if the socket is not bound
-   * @throws ClosedChannelException
-   *     if the channel is closed.
-   * @throws IOException
-   *     if another I/O error occurs.
-   * @hide Until ready for a public API change
-   */
-  SocketAddress getLocalAddress() throws IOException;
-
-  /**
-   * Returns the value for the socket option.
-   *
-   * @throws UnsupportedOperationException
-   *     if the option is not supported by the socket.
-   * @throws java.nio.channels.ClosedChannelException
-   *     if the socket is closed
-   * @throws IOException
-   *     if the value cannot be read.
-   * @hide Until ready for a public API change
-   * @see java.net.StandardSocketOptions
-   */
-  <T> T getOption(SocketOption<T> option) throws IOException;
-
-  /**
-   * Sets the value for the socket option.
-   *
-   * @return this NetworkChannel
-   * @throws UnsupportedOperationException
-   *     if the option is not supported by the socket.
-   * @throws IllegalArgumentException
-   *     if the value is not valid for the option.
-   * @throws java.nio.channels.ClosedChannelException
-   *     if the socket is closed
-   * @throws IOException
-   *     if the value cannot be written.
-   * @hide Until ready for a public API change
-   * @see java.net.StandardSocketOptions
-   */
-  <T> NetworkChannel setOption(SocketOption<T> option, T value) throws IOException;
-
-  /**
-   * Returns the set of socket options supported by this channel.
-   *
-   * @hide Until ready for a public API change
-   */
-  Set<SocketOption<?>> supportedOptions();
-}
diff --git a/luni/src/main/java/java/nio/channels/SeekableByteChannel.java b/luni/src/main/java/java/nio/channels/SeekableByteChannel.java
deleted file mode 100644
index f4d6beb..0000000
--- a/luni/src/main/java/java/nio/channels/SeekableByteChannel.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.nio.channels;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-/**
- * An interface for channels that keep a pointer to a current position within an underlying
- * byte-based data source such as a file.
- *
- * <p>SeekableByteChannels have a pointer into the underlying data source which is referred to as a
- * <em>position</em>. The position can be manipulated by moving it within the data source, and the
- * current position can be queried.
- *
- * <p>SeekableByteChannels also have an associated <em>size</em>. The size of the channel is the
- * number of bytes that the data source currently contains. The size of the data source can be
- * manipulated by adding more bytes to the end or by removing bytes from the end. See
- * {@link #truncate}, {@link #position} and {@link #write} for details. The current size can also
- * be queried.
- *
- * @hide Until ready for a public API change
- * @since 1.7
- */
-public interface SeekableByteChannel extends ByteChannel {
-
-  /**
-   * Returns the current position as a positive number of bytes from the start of the underlying
-   * data source.
-   *
-   * @throws ClosedChannelException
-   *     if this channel is closed.
-   * @throws IOException
-   *     if another I/O error occurs.
-   */
-  long position() throws IOException;
-
-  /**
-   * Sets the channel's position to {@code newPosition}.
-   *
-   * <p>The argument is the number of bytes counted from the start of the data source. The position
-   * cannot be set to a value that is negative. The new position can be set beyond the current
-   * size. If set beyond the current size, attempts to read will return end-of-file. Write
-   * operations will succeed but they will fill the bytes between the current end of the data
-   * source
-   * and the new position with the required number of (unspecified) byte values.
-   *
-   * @return the channel.
-   * @throws IllegalArgumentException
-   *     if the new position is negative.
-   * @throws ClosedChannelException
-   *     if this channel is closed.
-   * @throws IOException
-   *     if another I/O error occurs.
-   */
-  SeekableByteChannel position(long newPosition) throws IOException;
-
-  /**
-   * Returns the size of the data source underlying this channel in bytes.
-   *
-   * @throws ClosedChannelException
-   *     if this channel is closed.
-   * @throws IOException
-   *     if an I/O error occurs.
-   */
-  long size() throws IOException;
-
-  /**
-   * Truncates the data source underlying this channel to a given size. Any bytes beyond the given
-   * size are removed. If there are no bytes beyond the given size then the contents are
-   * unmodified.
-   *
-   * <p>If the position is currently greater than the given size, then it is set to the new size.
-   *
-   * @return this channel.
-   * @throws IllegalArgumentException
-   *     if the requested size is negative.
-   * @throws ClosedChannelException
-   *     if this channel is closed.
-   * @throws NonWritableChannelException
-   *     if the channel cannot be written to.
-   * @throws IOException
-   *     if another I/O error occurs.
-   */
-  SeekableByteChannel truncate(long size) throws IOException;
-
-  /**
-   * Writes bytes from the given byte buffer to this channel.
-   *
-   * <p>The bytes are written starting at the channel's current position, and after some number of
-   * bytes are written (up to the {@link java.nio.Buffer#remaining() remaining} number of bytes in
-   * the buffer) the channel's position is increased by the number of bytes actually written.
-   *
-   * <p>If the channel's position is beyond the current end of the underlying data source, then the
-   * data source is first extended up to the given position by the required number of unspecified
-   * byte values.
-   *
-   * @param buffer
-   *     the byte buffer containing the bytes to be written.
-   * @return the number of bytes actually written.
-   * @throws NonWritableChannelException
-   *     if the channel was not opened for writing.
-   * @throws ClosedChannelException
-   *     if the channel was already closed.
-   * @throws AsynchronousCloseException
-   *     if another thread closes the channel during the write.
-   * @throws ClosedByInterruptException
-   *     if another thread interrupts the calling thread while this operation is in progress. The
-   *     interrupt state of the calling thread is set and the channel is closed.
-   * @throws IOException
-   *     if another I/O error occurs, details are in the message.
-   */
-  @Override
-  int write(ByteBuffer buffer) throws IOException;
-
-  /**
-   * Reads bytes from this channel into the given buffer.
-   *
-   * <p>If the channels position is beyond the current end of the underlying data source then
-   * end-of-file (-1) is returned.
-   *
-   * <p>The bytes are read starting at the channel's current position, and after some number of
-   * bytes are read (up to the {@link java.nio.Buffer#remaining() remaining} number of bytes in the
-   * buffer) the channel's position is increased by the number of bytes actually read. The bytes
-   * will be read into the buffer starting at the buffer's current
-   * {@link java.nio.Buffer#position() position}. The buffer's {@link java.nio.Buffer#limit()
-   * limit} is not changed.
-   *
-   * <p>The call may block if other threads are also attempting to read from the same channel.
-   *
-   * @param buffer
-   *     the byte buffer to receive the bytes.
-   * @return the number of bytes actually read, or -1 if the end of the data has been reached
-   * @throws AsynchronousCloseException
-   *     if another thread closes the channel during the read.
-   * @throws ClosedByInterruptException
-   *     if another thread interrupts the calling thread while the operation is in progress. The
-   *     interrupt state of the calling thread is set and the channel is closed.
-   * @throws ClosedChannelException
-   *     if the channel is closed.
-   * @throws IOException
-   *     another I/O error occurs, details are in the message.
-   * @throws NonReadableChannelException
-   *     if the channel was not opened for reading.
-   */
-  @Override
-  int read(ByteBuffer buffer) throws IOException;
-
-}
diff --git a/luni/src/main/java/java/nio/channels/ServerSocketChannel.java b/luni/src/main/java/java/nio/channels/ServerSocketChannel.java
index c720451..ef50155 100644
--- a/luni/src/main/java/java/nio/channels/ServerSocketChannel.java
+++ b/luni/src/main/java/java/nio/channels/ServerSocketChannel.java
@@ -20,7 +20,6 @@
 import java.io.IOException;
 import java.net.ServerSocket;
 import java.net.SocketAddress;
-import java.net.SocketOption;
 import java.nio.channels.spi.AbstractSelectableChannel;
 import java.nio.channels.spi.SelectorProvider;
 import java.util.Set;
@@ -37,9 +36,7 @@
  * {@link NotYetBoundException}. It can be bound by calling the bind method of a
  * related {@code ServerSocket} instance.
  */
-public abstract class ServerSocketChannel extends AbstractSelectableChannel
-        implements NetworkChannel {
-
+public abstract class ServerSocketChannel extends AbstractSelectableChannel {
     /**
      * Constructs a new {@link ServerSocketChannel}.
      *
@@ -86,76 +83,6 @@
     public abstract ServerSocket socket();
 
     /**
-     * {@inheritDoc}
-     *
-     * <p>This is equivalent to {@code bind(local, 0)}.
-     * @hide Until ready for a public API change
-     */
-    @Override
-    public final ServerSocketChannel bind(SocketAddress local) throws IOException {
-        return bind(local, 0);
-    }
-
-    /**
-     * Binds this server channel to the given local socket address. If the {@code localAddr} is set
-     * to {@code null} the socket will be bound to an available local address on any free port of
-     * the system.
-     *
-     * @param localAddr
-     *             the local machine address and port to bind on.
-     * @param backlog the maximum number of unaccepted connections. Passing 0 or
-     *             a negative value yields the default backlog of 50.
-     * @return this {@code ServerSocketChannel}.
-     * @throws UnsupportedAddressTypeException
-     *             if the {@code SocketAddress} is not supported.
-     * @throws ClosedChannelException
-     *             if the channel is closed.
-     * @throws AlreadyBoundException
-     *             if the channel is already bound.
-     * @throws IOException
-     *             if another I/O error occurs.
-     * @since 1.7
-     * @hide Until ready for a public API change
-     */
-    public ServerSocketChannel bind(SocketAddress localAddr, int backlog) throws IOException {
-        // This method was added for interoperability with Java 7, where it is abstract. It is
-        // concrete here to avoid breaking existing Android applications that extend this class.
-        throw new UnsupportedOperationException("Subclasses must override this method");
-    }
-
-    /** @hide Until ready for a public API change */
-     @Override
-    public SocketAddress getLocalAddress() throws IOException {
-        // This method was added for interoperability with Java 7, where it is abstract. It is
-        // concrete here to avoid breaking existing Android applications that extend this class.
-        throw new UnsupportedOperationException("Subclasses must override this method");
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public <T> T getOption(SocketOption<T> option) throws IOException {
-        // This method was added for interoperability with Java 7, where it is abstract. It is
-        // concrete here to avoid breaking existing Android applications that extend this class.
-        throw new UnsupportedOperationException("Subclasses must override this method");
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public <T> ServerSocketChannel setOption(SocketOption<T> option, T value) throws IOException {
-        // This method was added for interoperability with Java 7, where it is abstract. It is
-        // concrete here to avoid breaking existing Android applications that extend this class.
-        throw new UnsupportedOperationException("Subclasses must override this method");
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public Set<SocketOption<?>> supportedOptions() {
-        // This method was added for interoperability with Java 7, where it is abstract. It is
-        // concrete here to avoid breaking existing Android applications that extend this class.
-        throw new UnsupportedOperationException("Subclasses must override this method");
-    }
-
-    /**
      * Accepts a connection to this server-socket channel.
      * <p>
      * This method returns {@code null} when this channel is non-blocking and no
diff --git a/luni/src/main/java/java/nio/channels/SocketChannel.java b/luni/src/main/java/java/nio/channels/SocketChannel.java
index a6d1551..a91fccd 100644
--- a/luni/src/main/java/java/nio/channels/SocketChannel.java
+++ b/luni/src/main/java/java/nio/channels/SocketChannel.java
@@ -20,7 +20,6 @@
 import java.io.IOException;
 import java.net.Socket;
 import java.net.SocketAddress;
-import java.net.SocketOption;
 import java.nio.ByteBuffer;
 import java.nio.channels.spi.AbstractSelectableChannel;
 import java.nio.channels.spi.SelectorProvider;
@@ -64,7 +63,7 @@
  * processing, calls to {@link #read} and {@link #write} will block.
  */
 public abstract class SocketChannel extends AbstractSelectableChannel implements
-        ByteChannel, ScatteringByteChannel, GatheringByteChannel, NetworkChannel {
+        ByteChannel, ScatteringByteChannel, GatheringByteChannel {
 
     /**
      * Constructs a new {@code SocketChannel}.
@@ -142,46 +141,6 @@
      */
     public abstract Socket socket();
 
-    /** @hide Until ready for a public API change */
-    @Override
-    public SocketChannel bind(SocketAddress local) throws IOException {
-        // This method was added for interoperability with Java 7, where it is abstract. It is
-        // concrete here to avoid breaking existing Android applications that extend this class.
-        throw new UnsupportedOperationException("Subclasses must override this method");
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public SocketAddress getLocalAddress() throws IOException {
-        // This method was added for interoperability with Java 7, where it is abstract. It is
-        // concrete here to avoid breaking existing Android applications that extend this class.
-        throw new UnsupportedOperationException("Subclasses must override this method");
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public <T> T getOption(SocketOption<T> option) throws IOException {
-        // This method was added for interoperability with Java 7, where it is abstract. It is
-        // concrete here to avoid breaking existing Android applications that extend this class.
-        throw new UnsupportedOperationException("Subclasses must override this method");
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public <T> SocketChannel setOption(SocketOption<T> option, T value) throws IOException {
-        // This method was added for interoperability with Java 7, where it is abstract. It is
-        // concrete here to avoid breaking existing Android applications that extend this class.
-        throw new UnsupportedOperationException("Subclasses must override this method");
-    }
-
-    /** @hide Until ready for a public API change */
-    @Override
-    public Set<SocketOption<?>> supportedOptions() {
-        // This method was added for interoperability with Java 7, where it is abstract. It is
-        // concrete here to avoid breaking existing Android applications that extend this class.
-        throw new UnsupportedOperationException("Subclasses must override this method");
-    }
-
     /**
      * Indicates whether this channel's socket is connected.
      *
diff --git a/luni/src/main/java/java/security/Security.java b/luni/src/main/java/java/security/Security.java
index 81bafbd..b859f9a 100644
--- a/luni/src/main/java/java/security/Security.java
+++ b/luni/src/main/java/java/security/Security.java
@@ -348,6 +348,7 @@
      * Sets the value of the specified security property.
      */
     public static void setProperty(String key, String value) {
+        Services.setNeedRefresh();
         secprops.put(key, value);
     }
 
diff --git a/luni/src/main/java/java/text/DecimalFormat.java b/luni/src/main/java/java/text/DecimalFormat.java
index fbbc172..dc70886 100644
--- a/luni/src/main/java/java/text/DecimalFormat.java
+++ b/luni/src/main/java/java/text/DecimalFormat.java
@@ -900,8 +900,9 @@
      */
     @Override
     public void setCurrency(Currency currency) {
-        ndf.setCurrency(Currency.getInstance(currency.getCurrencyCode()));
-        symbols.setCurrency(currency);
+        Currency instance = Currency.getInstance(currency.getCurrencyCode());
+        symbols.setCurrency(instance);
+        ndf.setCurrency(symbols.getCurrencySymbol(), currency.getCurrencyCode());
     }
 
     /**
diff --git a/luni/src/main/java/java/util/Calendar.java b/luni/src/main/java/java/util/Calendar.java
index 4ed2ad19..e15641f 100644
--- a/luni/src/main/java/java/util/Calendar.java
+++ b/luni/src/main/java/java/util/Calendar.java
@@ -642,13 +642,24 @@
 
     /**
      * Field number for {@code get} and {@code set} indicating the
-     * raw offset from GMT in milliseconds.
+     * raw (non-DST) offset from GMT in milliseconds.
+     * Equivalent to {@link java.util.TimeZone#getRawOffset}.
+     *
+     * <p>To determine the total offset from GMT at the time represented
+     * by this calendar, you will need to add the {@code ZONE_OFFSET} and
+     * {@code DST_OFFSET} fields.
      */
     public static final int ZONE_OFFSET = 15;
 
     /**
      * Field number for {@code get} and {@code set} indicating the
-     * daylight savings offset in milliseconds.
+     * daylight savings offset from the {@code ZONE_OFFSET} in milliseconds.
+     * Equivalent to {@link java.util.TimeZone#getDSTSavings} if the represented time
+     * falls inside DST, or 0 otherwise.
+     *
+     * <p>To determine the total offset from GMT at the time represented
+     * by this calendar, you will need to add the {@code ZONE_OFFSET} and
+     * {@code DST_OFFSET} fields.
      */
     public static final int DST_OFFSET = 16;
 
diff --git a/luni/src/main/java/java/util/Currency.java b/luni/src/main/java/java/util/Currency.java
index a535bc7..8cfb68f 100644
--- a/luni/src/main/java/java/util/Currency.java
+++ b/luni/src/main/java/java/util/Currency.java
@@ -127,17 +127,6 @@
     }
 
     /**
-     * Returns the ISO 4217 numeric code for this currency. If there is no standard numeric code a
-     * zero is returned.
-     *
-     * @since 1.7
-     * @hide Until ready for an API update
-     */
-    public int getNumericCode() {
-        return ICU.getCurrencyNumericCode(currencyCode);
-    }
-
-    /**
      * Equivalent to {@code getSymbol(Locale.getDefault())}.
      * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      */
@@ -157,10 +146,6 @@
      * <p>If there is no locale-specific currency symbol, the ISO 4217 currency code is returned.
      */
     public String getSymbol(Locale locale) {
-        if (locale.getCountry().length() == 0) {
-            return currencyCode;
-        }
-
         // Check the locale first, in case the locale has the same currency.
         LocaleData localeData = LocaleData.get(locale);
         if (localeData.internationalCurrencySymbol.equals(currencyCode)) {
diff --git a/luni/src/main/java/java/util/GregorianCalendar.java b/luni/src/main/java/java/util/GregorianCalendar.java
index be3e5c9..71b79dd 100644
--- a/luni/src/main/java/java/util/GregorianCalendar.java
+++ b/luni/src/main/java/java/util/GregorianCalendar.java
@@ -571,7 +571,7 @@
 
         // We unconditionally overwrite DST_OFFSET and ZONE_OFFSET with
         // values from the timezone that's currently in use. This gives us
-        // much more consistent behaviour, and matches ICU4J behaviour (though
+        // much more consistent behavior, and matches ICU4J behavior (though
         // it is inconsistent with the RI).
         //
         // Anything callers can do with ZONE_OFFSET they can do by constructing
diff --git a/luni/src/main/java/java/util/TimeZone.java b/luni/src/main/java/java/util/TimeZone.java
index c024e8d..e4c68c5 100644
--- a/luni/src/main/java/java/util/TimeZone.java
+++ b/luni/src/main/java/java/util/TimeZone.java
@@ -329,7 +329,6 @@
         }
 
         // Special cases? These can clone an existing instance.
-        // TODO: should we just add a cache to ZoneInfoDB instead?
         if (id.length() == 3) {
             if (id.equals("GMT")) {
                 return (TimeZone) GMT.clone();
diff --git a/luni/src/main/java/java/util/zip/ZipFile.java b/luni/src/main/java/java/util/zip/ZipFile.java
index 43e8567..b44156e 100644
--- a/luni/src/main/java/java/util/zip/ZipFile.java
+++ b/luni/src/main/java/java/util/zip/ZipFile.java
@@ -26,7 +26,6 @@
 import java.io.InputStream;
 import java.io.RandomAccessFile;
 import java.nio.ByteOrder;
-import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.util.Enumeration;
 import java.util.Iterator;
@@ -98,8 +97,6 @@
 
     private final String filename;
 
-    private final Charset charset;
-
     private File fileToDeleteOnClose;
 
     private RandomAccessFile raf;
@@ -119,23 +116,7 @@
      * @throws IOException if an {@code IOException} occurs.
      */
     public ZipFile(File file) throws ZipException, IOException {
-        this(file, OPEN_READ, StandardCharsets.UTF_8);
-    }
-
-    /**
-     * Constructs a new {@code ZipFile} allowing read access to the contents of the given file.
-     *
-     * <p>The {@code charset} is used to decode the file comment if one exists. If the character
-     * encoding for entry names and comments is not explicitly marked as UTF-8 by the zip file
-     * then {@code charset} is used to decode them.
-     *
-     * @throws ZipException if a zip error occurs.
-     * @throws IOException if an {@code IOException} occurs.
-     * @since 1.7
-     * @hide Until ready for an API update
-     */
-    public ZipFile(File file, Charset charset) throws ZipException, IOException {
-        this(file, OPEN_READ, charset);
+        this(file, OPEN_READ);
     }
 
     /**
@@ -146,7 +127,7 @@
      * @throws IOException if an IOException occurs.
      */
     public ZipFile(String name) throws IOException {
-        this(new File(name), OPEN_READ, StandardCharsets.UTF_8);
+        this(new File(name), OPEN_READ);
     }
 
     /**
@@ -162,31 +143,7 @@
      * @throws IOException if an {@code IOException} occurs.
      */
     public ZipFile(File file, int mode) throws IOException {
-        this(file, mode, StandardCharsets.UTF_8);
-    }
-
-    /**
-     * Constructs a new {@code ZipFile} allowing access to the given file.
-     *
-     * <p>The {@code mode} must be either {@code OPEN_READ} or {@code OPEN_READ|OPEN_DELETE}.
-     * If the {@code OPEN_DELETE} flag is supplied, the file will be deleted at or before the
-     * time that the {@code ZipFile} is closed (the contents will remain accessible until
-     * this {@code ZipFile} is closed); it also calls {@code File.deleteOnExit}.
-     *
-     * <p>The {@code charset} is used to decode the file comment if one exists. If the character
-     * encoding for entry names and comments is not explicitly marked as UTF-8 by the zip file
-     * then {@code charset} is used to decode them.
-     *
-     * @throws IOException if an {@code IOException} occurs.
-     * @since 1.7
-     * @hide Until ready for an API update
-     */
-    public ZipFile(File file, int mode, Charset charset) throws IOException {
         filename = file.getPath();
-        if (charset == null) {
-            throw new NullPointerException("charset == null");
-        }
-        this.charset = charset;
         if (mode != OPEN_READ && mode != (OPEN_READ | OPEN_DELETE)) {
             throw new IllegalArgumentException("Bad mode: " + mode);
         }
@@ -467,7 +424,7 @@
         if (commentLength > 0) {
             byte[] commentBytes = new byte[commentLength];
             raf.readFully(commentBytes);
-            comment = new String(commentBytes, 0, commentBytes.length, charset);
+            comment = new String(commentBytes, 0, commentBytes.length, StandardCharsets.UTF_8);
         }
 
         // Seek to the first CDE and read all entries.
@@ -478,7 +435,7 @@
         BufferedInputStream bufferedStream = new BufferedInputStream(rafStream, 4096);
         byte[] hdrBuf = new byte[CENHDR]; // Reuse the same buffer for each entry.
         for (int i = 0; i < numEntries; ++i) {
-            ZipEntry newEntry = new ZipEntry(hdrBuf, bufferedStream, charset);
+            ZipEntry newEntry = new ZipEntry(hdrBuf, bufferedStream, StandardCharsets.UTF_8);
             if (newEntry.localHeaderRelOffset >= centralDirOffset) {
                 throw new ZipException("Local file header offset is after central directory");
             }
diff --git a/luni/src/main/java/java/util/zip/ZipInputStream.java b/luni/src/main/java/java/util/zip/ZipInputStream.java
index 5a73619..4c0034e 100644
--- a/luni/src/main/java/java/util/zip/ZipInputStream.java
+++ b/luni/src/main/java/java/util/zip/ZipInputStream.java
@@ -21,7 +21,6 @@
 import java.io.InputStream;
 import java.io.PushbackInputStream;
 import java.nio.ByteOrder;
-import java.nio.charset.Charset;
 import java.nio.charset.ModifiedUtf8;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
@@ -90,35 +89,16 @@
 
     private char[] stringCharBuf = new char[256];
 
-    private final Charset charset;
-
     /**
      * Constructs a new {@code ZipInputStream} to read zip entries from the given input stream.
      *
      * <p>UTF-8 is used to decode all strings in the file.
      */
     public ZipInputStream(InputStream stream) {
-        this(stream, StandardCharsets.UTF_8);
-    }
-
-    /**
-     * Constructs a new {@code ZipInputStream} to read zip entries from the given input stream.
-     *
-     * <p>If the character encoding for entry names and comments is not explicitly marked as UTF-8
-     * by the zip file then {@code charset} is used to decode them.
-     *
-     * @since 1.7
-     * @hide Until ready for an API update
-     */
-    public ZipInputStream(InputStream stream, Charset charset) {
         super(new PushbackInputStream(stream, BUF_SIZE), new Inflater(true));
         if (stream == null) {
             throw new NullPointerException("stream == null");
         }
-        if (charset == null) {
-            throw new NullPointerException("charset == null");
-        }
-        this.charset = charset;
     }
 
     /**
@@ -272,12 +252,7 @@
         }
         int extraLength = peekShort(LOCEXT - LOCVER);
 
-        // Determine the character set to use to decode strings.
-        Charset charset = this.charset;
-        if ((flags & ZipFile.GPBF_UTF8_FLAG) != 0) {
-            charset = StandardCharsets.UTF_8;
-        }
-        String name = readString(nameLength, charset);
+        String name = readString(nameLength);
         currentEntry = createZipEntry(name);
         currentEntry.time = ceLastModifiedTime;
         currentEntry.modDate = ceLastModifiedDate;
@@ -298,21 +273,17 @@
     /**
      * Reads bytes from the current stream position returning the string representation.
      */
-    private String readString(int byteLength, Charset charset) throws IOException {
+    private String readString(int byteLength) throws IOException {
         if (byteLength > stringBytesBuf.length) {
             stringBytesBuf = new byte[byteLength];
         }
         Streams.readFully(in, stringBytesBuf, 0, byteLength);
-        if (charset == StandardCharsets.UTF_8) {
-            // The number of chars will always be less than or equal to the number of bytes. It's
-            // fine if this buffer is too long.
-            if (byteLength > stringCharBuf.length) {
-                stringCharBuf = new char[byteLength];
-            }
-            return ModifiedUtf8.decode(stringBytesBuf, stringCharBuf, 0, byteLength);
-        } else {
-            return new String(stringBytesBuf, 0, byteLength, charset);
+        // The number of chars will always be less than or equal to the number of bytes. It's
+        // fine if this buffer is too long.
+        if (byteLength > stringCharBuf.length) {
+            stringCharBuf = new char[byteLength];
         }
+        return ModifiedUtf8.decode(stringBytesBuf, stringCharBuf, 0, byteLength);
     }
 
     private int peekShort(int offset) {
diff --git a/luni/src/main/java/java/util/zip/ZipOutputStream.java b/luni/src/main/java/java/util/zip/ZipOutputStream.java
index ac6bdf2..8278355 100644
--- a/luni/src/main/java/java/util/zip/ZipOutputStream.java
+++ b/luni/src/main/java/java/util/zip/ZipOutputStream.java
@@ -20,7 +20,6 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -76,8 +75,6 @@
 
     private final HashSet<String> entries = new HashSet<String>();
 
-    private final Charset charset;
-
     private int defaultCompressionMethod = DEFLATED;
 
     private int compressionLevel = Deflater.DEFAULT_COMPRESSION;
@@ -103,25 +100,7 @@
      * <p>UTF-8 will be used to encode the file comment, entry names and comments.
      */
     public ZipOutputStream(OutputStream os) {
-        this(os, StandardCharsets.UTF_8);
-    }
-
-    /**
-     * Constructs a new {@code ZipOutputStream} that writes a zip file to the given
-     * {@code OutputStream}.
-     *
-     * <p>The specified character set will be used to encode the file comment, entry names and
-     * comments.
-     *
-     * @since 1.7
-     * @hide Until ready for an API update
-     */
-    public ZipOutputStream(OutputStream os, Charset charset) {
         super(os, new Deflater(Deflater.DEFAULT_COMPRESSION, true));
-        if (charset == null) {
-            throw new NullPointerException("charset == null");
-        }
-        this.charset = charset;
     }
 
     /**
@@ -183,9 +162,7 @@
         // Since gingerbread, we always set the UTF-8 flag on individual files if appropriate.
         // Some tools insist that the central directory have the UTF-8 flag.
         // http://code.google.com/p/android/issues/detail?id=20214
-        if (charset == StandardCharsets.UTF_8) {
-            flags |= ZipFile.GPBF_UTF8_FLAG;
-        }
+        flags |= ZipFile.GPBF_UTF8_FLAG;
         writeLong(cDir, CENSIG);
         writeShort(cDir, ZIP_VERSION_2_0); // Version this file was made by.
         writeShort(cDir, ZIP_VERSION_2_0); // Minimum version needed to extract.
@@ -319,11 +296,11 @@
             // TODO: support Zip64.
             throw new ZipException("Too many entries for the zip file format's 16-bit entry count");
         }
-        nameBytes = ze.name.getBytes(charset);
+        nameBytes = ze.name.getBytes(StandardCharsets.UTF_8);
         checkSizeIsWithinShort("Name", nameBytes);
         entryCommentBytes = EmptyArray.BYTE;
         if (ze.comment != null) {
-            entryCommentBytes = ze.comment.getBytes(charset);
+            entryCommentBytes = ze.comment.getBytes(StandardCharsets.UTF_8);
             // The comment is not written out until the entry is finished, but it is validated here
             // to fail-fast.
             checkSizeIsWithinShort("Comment", entryCommentBytes);
@@ -340,9 +317,7 @@
         int flags = (method == STORED) ? 0 : ZipFile.GPBF_DATA_DESCRIPTOR_FLAG;
         // Java always outputs UTF-8 filenames. (Before Java 7, the RI didn't set this flag and used
         // modified UTF-8. From Java 7, when using UTF_8 it sets this flag and uses normal UTF-8.)
-        if (charset == StandardCharsets.UTF_8) {
-            flags |= ZipFile.GPBF_UTF8_FLAG;
-        }
+        flags |= ZipFile.GPBF_UTF8_FLAG;
         writeLong(out, LOCSIG); // Entry header
         writeShort(out, ZIP_VERSION_2_0); // Minimum version needed to extract.
         writeShort(out, flags);
@@ -384,7 +359,7 @@
             return;
         }
 
-        byte[] newCommentBytes = comment.getBytes(charset);
+        byte[] newCommentBytes = comment.getBytes(StandardCharsets.UTF_8);
         checkSizeIsWithinShort("Comment", newCommentBytes);
         this.commentBytes = newCommentBytes;
     }
@@ -455,8 +430,8 @@
 
     private void checkSizeIsWithinShort(String property, byte[] bytes) {
         if (bytes.length > 0xffff) {
-            throw new IllegalArgumentException(
-                    property + " too long in " + charset + ":" + bytes.length + " bytes");
+            throw new IllegalArgumentException(property + " too long in UTF-8:" + bytes.length +
+                                               " bytes");
         }
     }
 }
diff --git a/luni/src/main/java/javax/net/ssl/SSLEngine.java b/luni/src/main/java/javax/net/ssl/SSLEngine.java
index d63ee94..3ba3450 100644
--- a/luni/src/main/java/javax/net/ssl/SSLEngine.java
+++ b/luni/src/main/java/javax/net/ssl/SSLEngine.java
@@ -542,14 +542,14 @@
  *             <td>20+</td>
  *         </tr>
  *         <tr>
- *             <td>TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256</td>
- *             <td>20+</td>
- *             <td></td>
+ *             <td>TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA</td>
+ *             <td>21+</td>
+ *             <td>21+</td>
  *         </tr>
  *         <tr>
- *             <td>TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384</td>
- *             <td>20+</td>
- *             <td></td>
+ *             <td>TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA</td>
+ *             <td>21+</td>
+ *             <td>21+</td>
  *         </tr>
  *         <tr>
  *             <td>TLS_NULL_WITH_NULL_NULL</td>
@@ -558,22 +558,22 @@
  *         </tr>
  *         <tr>
  *             <td>TLS_PSK_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>20+</td>
+ *             <td>21+</td>
  *             <td></td>
  *         </tr>
  *         <tr>
  *             <td>TLS_PSK_WITH_AES_128_CBC_SHA</td>
- *             <td>20+</td>
- *             <td></td>
+ *             <td>21+</td>
+ *             <td>21+</td>
  *         </tr>
  *         <tr>
  *             <td>TLS_PSK_WITH_AES_256_CBC_SHA</td>
- *             <td>20+</td>
- *             <td></td>
+ *             <td>21+</td>
+ *             <td>21+</td>
  *         </tr>
  *         <tr>
  *             <td>TLS_PSK_WITH_RC4_128_SHA</td>
- *             <td>20+</td>
+ *             <td>21+</td>
  *             <td></td>
  *         </tr>
  *         <tr>
@@ -639,6 +639,9 @@
  *     </tbody>
  * </table>
  *
+ * <p><em>NOTE</em>: PSK cipher suites are enabled by default only if the {@code SSLContext} through
+ * which the engine was created has been initialized with a {@code PSKKeyManager}.
+ *
  * @since 1.5
  */
 public abstract class SSLEngine {
@@ -778,18 +781,6 @@
     public abstract SSLSession getSession();
 
     /**
-     * Returns the SSL session for this engine instance. Does not cause the
-     * handshake to start if it has not already started.
-     *
-     * @return the SSL session for this engine instance.
-     * @since 1.7
-     * @hide
-     */
-    public SSLSession getHandshakeSession() {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
      * Returns the SSL cipher suite names that are supported by this engine.
      * These cipher suites can be enabled using
      * {@link #setEnabledCipherSuites(String[])}.
diff --git a/luni/src/main/java/javax/net/ssl/SSLParameters.java b/luni/src/main/java/javax/net/ssl/SSLParameters.java
index b8fdc38..054abe2 100644
--- a/luni/src/main/java/javax/net/ssl/SSLParameters.java
+++ b/luni/src/main/java/javax/net/ssl/SSLParameters.java
@@ -139,28 +139,4 @@
         this.wantClientAuth = wantClientAuth;
         this.needClientAuth = false;
     }
-
-    /**
-     * Returns a string indicating the endpoint identification algorithm to be
-     * used to identify the remote endpoint.
-     *
-     * @see #setEndpointIdentificationAlgorithm(String)
-     * @since 1.7
-     * @hide
-     */
-    public String getEndpointIdentificationAlgorithm() {
-        return endpointIdentificationAlgorithm;
-    }
-
-    /**
-     * Sets the endpoint identification algorithm to be used to identify the
-     * remote endpoint.
-     *
-     * @see #getEndpointIdentificationAlgorithm()
-     * @since 1.7
-     * @hide
-     */
-    public void setEndpointIdentificationAlgorithm(String endpointIdentificationAlgorithm) {
-        this.endpointIdentificationAlgorithm = endpointIdentificationAlgorithm;
-    }
 }
diff --git a/luni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java b/luni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java
index cce72cd..03b8828 100644
--- a/luni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java
+++ b/luni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java
@@ -20,6 +20,7 @@
 import java.security.NoSuchAlgorithmException;
 import java.security.Security;
 import javax.net.ServerSocketFactory;
+import org.apache.harmony.security.fortress.Services;
 
 /**
  * The factory for SSL server sockets.
@@ -32,6 +33,8 @@
 
     private static String defaultName;
 
+    private static int lastCacheVersion = -1;
+
     /**
      * Returns the default {@code SSLServerSocketFactory} instance. The default
      * implementation is defined by the security property
@@ -40,6 +43,12 @@
      * @return the default {@code SSLServerSocketFactory} instance.
      */
     public static synchronized ServerSocketFactory getDefault() {
+        int newCacheVersion = Services.getCacheVersion();
+        if (lastCacheVersion != newCacheVersion) {
+            defaultServerSocketFactory = null;
+            defaultName = null;
+            lastCacheVersion = newCacheVersion;
+        }
         if (defaultServerSocketFactory != null) {
             return defaultServerSocketFactory;
         }
diff --git a/luni/src/main/java/javax/net/ssl/SSLSocket.java b/luni/src/main/java/javax/net/ssl/SSLSocket.java
index f681681..33a88b6 100644
--- a/luni/src/main/java/javax/net/ssl/SSLSocket.java
+++ b/luni/src/main/java/javax/net/ssl/SSLSocket.java
@@ -346,14 +346,14 @@
  *             <td>11+</td>
  *         </tr>
  *         <tr>
- *             <td>TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256</td>
- *             <td>20+</td>
- *             <td></td>
+ *             <td>TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA</td>
+ *             <td>21+</td>
+ *             <td>21+</td>
  *         </tr>
  *         <tr>
- *             <td>TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384</td>
- *             <td>20+</td>
- *             <td></td>
+ *             <td>TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA</td>
+ *             <td>21+</td>
+ *             <td>21+</td>
  *         </tr>
  *         <tr>
  *             <td>TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA</td>
@@ -522,22 +522,22 @@
  *         </tr>
  *         <tr>
  *             <td>TLS_PSK_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>20+</td>
+ *             <td>21+</td>
  *             <td></td>
  *         </tr>
  *         <tr>
  *             <td>TLS_PSK_WITH_AES_128_CBC_SHA</td>
- *             <td>20+</td>
- *             <td></td>
+ *             <td>21+</td>
+ *             <td>21+</td>
  *         </tr>
  *         <tr>
  *             <td>TLS_PSK_WITH_AES_256_CBC_SHA</td>
- *             <td>20+</td>
- *             <td></td>
+ *             <td>21+</td>
+ *             <td>21+</td>
  *         </tr>
  *         <tr>
  *             <td>TLS_PSK_WITH_RC4_128_SHA</td>
- *             <td>20+</td>
+ *             <td>21+</td>
  *             <td></td>
  *         </tr>
  *         <tr>
@@ -578,6 +578,9 @@
  *     </tbody>
  * </table>
  *
+ * <p><em>NOTE</em>: PSK cipher suites are enabled by default only if the {@code SSLContext} through
+ * which the socket was created has been initialized with a {@code PSKKeyManager}.
+ *
  * <p>API Levels 1 to 8 use OpenSSL names for cipher suites. The table below
  * lists these OpenSSL names and their corresponding standard names used in API
  * Levels 9 and newer.
@@ -889,19 +892,6 @@
     public abstract SSLSession getSession();
 
     /**
-     * Returns the {@code SSLSession} for this connection. It will not initiate
-     * the handshake and thus will not block until the handshake has been
-     * established.
-     *
-     * @return the session object.
-     * @since 1.7
-     * @hide
-     */
-    public SSLSession getHandshakeSession() {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
      * Registers the specified listener to receive notification on completion of
      * a handshake on this connection.
      *
diff --git a/luni/src/main/java/javax/net/ssl/SSLSocketFactory.java b/luni/src/main/java/javax/net/ssl/SSLSocketFactory.java
index b07d0fd..5c0f15d 100644
--- a/luni/src/main/java/javax/net/ssl/SSLSocketFactory.java
+++ b/luni/src/main/java/javax/net/ssl/SSLSocketFactory.java
@@ -22,6 +22,7 @@
 import java.security.NoSuchAlgorithmException;
 import java.security.Security;
 import javax.net.SocketFactory;
+import org.apache.harmony.security.fortress.Services;
 
 /**
  * The abstract factory implementation to create {@code SSLSocket}s.
@@ -34,6 +35,8 @@
 
     private static String defaultName;
 
+    private static int lastCacheVersion = -1;
+
     /**
      * Returns the default {@code SSLSocketFactory} instance. The default is
      * defined by the security property {@code 'ssl.SocketFactory.provider'}.
@@ -41,6 +44,12 @@
      * @return the default ssl socket factory instance.
      */
     public static synchronized SocketFactory getDefault() {
+        int newCacheVersion = Services.getCacheVersion();
+        if (lastCacheVersion != newCacheVersion) {
+            defaultSocketFactory = null;
+            defaultName = null;
+            lastCacheVersion = newCacheVersion;
+        }
         if (defaultSocketFactory != null) {
             return defaultSocketFactory;
         }
diff --git a/luni/src/main/java/javax/net/ssl/X509ExtendedTrustManager.java b/luni/src/main/java/javax/net/ssl/X509ExtendedTrustManager.java
deleted file mode 100644
index 8b398ce..0000000
--- a/luni/src/main/java/javax/net/ssl/X509ExtendedTrustManager.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.net.ssl;
-
-import java.net.Socket;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-
-/**
- * Allows the connection constraints such as hostname verification and algorithm
- * constraints to be checked along with the checks done in
- * {@link X509TrustManager}.
- *
- * @see SSLParameters#setEndpointIdentificationAlgorithm(String)
- * @since 1.7
- * @hide
- */
-public abstract class X509ExtendedTrustManager implements X509TrustManager {
-    /**
-     * Checks whether the specified certificate chain (partial or complete) can
-     * be validated and is trusted for client authentication for the specified
-     * authentication type.
-     * <p>
-     * If the {@code socket} is supplied, its {@link SSLParameters} will be
-     * checked for endpoint identification.
-     *
-     * @param chain the certificate chain to validate.
-     * @param authType the authentication type used.
-     * @param socket the socket from which to check the {@link SSLParameters}
-     * @throws CertificateException if the certificate chain can't be validated
-     *             or isn't trusted.
-     * @throws IllegalArgumentException if the specified certificate chain is
-     *             empty or {@code null}, or if the specified authentication
-     *             type is {@code null} or an empty string.
-     */
-    public abstract void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket)
-            throws CertificateException;
-
-    /**
-     * Checks whether the specified certificate chain (partial or complete) can
-     * be validated and is trusted for server authentication for the specified
-     * key exchange algorithm.
-     * <p>
-     * If the {@code socket} is supplied, its {@link SSLParameters} will be
-     * checked for endpoint identification.
-     *
-     * @param chain the certificate chain to validate.
-     * @param authType the authentication type used.
-     * @param socket the socket from which to check the {@link SSLParameters}
-     * @throws CertificateException if the certificate chain can't be validated
-     *             or isn't trusted.
-     * @throws IllegalArgumentException if the specified certificate chain is
-     *             empty or {@code null}, or if the specified authentication
-     *             type is {@code null} or an empty string.
-     */
-    public abstract void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket)
-            throws CertificateException;
-
-    /**
-     * Checks whether the specified certificate chain (partial or complete) can
-     * be validated and is trusted for client authentication for the specified
-     * authentication type.
-     * <p>
-     * If the {@code engine} is supplied, its {@link SSLParameters} will be
-     * checked for endpoint identification.
-     *
-     * @param chain the certificate chain to validate.
-     * @param authType the authentication type used.
-     * @param engine the engine from which to check the {@link SSLParameters}
-     * @throws CertificateException if the certificate chain can't be validated
-     *             or isn't trusted.
-     * @throws IllegalArgumentException if the specified certificate chain is
-     *             empty or {@code null}, or if the specified authentication
-     *             type is {@code null} or an empty string.
-     */
-    public abstract void checkClientTrusted(X509Certificate[] chain, String authType,
-            SSLEngine engine) throws CertificateException;
-
-    /**
-     * Checks whether the specified certificate chain (partial or complete) can
-     * be validated and is trusted for server authentication for the specified
-     * key exchange algorithm.
-     * <p>
-     * If the {@code engine} is supplied, its {@link SSLParameters} will be
-     * checked for endpoint identification.
-     *
-     * @param chain the certificate chain to validate.
-     * @param authType the authentication type used.
-     * @param engine the engine from which to check the {@link SSLParameters}
-     * @throws CertificateException if the certificate chain can't be validated
-     *             or isn't trusted.
-     * @throws IllegalArgumentException if the specified certificate chain is
-     *             empty or {@code null}, or if the specified authentication
-     *             type is {@code null} or an empty string.
-     */
-    public abstract void checkServerTrusted(X509Certificate[] chain, String authType,
-            SSLEngine engine) throws CertificateException;
-}
diff --git a/luni/src/main/java/libcore/icu/DateIntervalFormat.java b/luni/src/main/java/libcore/icu/DateIntervalFormat.java
index ab9085f..3855654 100644
--- a/luni/src/main/java/libcore/icu/DateIntervalFormat.java
+++ b/luni/src/main/java/libcore/icu/DateIntervalFormat.java
@@ -92,7 +92,7 @@
     // This is not the behavior of icu4c's DateIntervalFormat, but it's the historical behavior
     // of Android's DateUtils.formatDateRange.
     if (startMs != endMs && endsAtMidnight &&
-        ((flags & FORMAT_SHOW_TIME) == 0 || julianDay(startCalendar) == julianDay(endCalendar))) {
+        ((flags & FORMAT_SHOW_TIME) == 0 || dayDistance(startCalendar, endCalendar) <= 1)) {
       endCalendar.roll(Calendar.DAY_OF_MONTH, false);
       endMs -= DAY_IN_MS;
     }
@@ -224,8 +224,12 @@
     return c.get(Calendar.YEAR) == now.get(Calendar.YEAR);
   }
 
+  private static int dayDistance(Calendar c1, Calendar c2) {
+    return julianDay(c2) - julianDay(c1);
+  }
+
   private static int julianDay(Calendar c) {
-    long utcMs = c.get(Calendar.MILLISECOND) + c.get(Calendar.ZONE_OFFSET);
+    long utcMs = c.getTimeInMillis() + c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET);
     return (int) (utcMs / DAY_IN_MS) + EPOCH_JULIAN_DAY;
   }
 
diff --git a/luni/src/main/java/libcore/icu/NativeDecimalFormat.java b/luni/src/main/java/libcore/icu/NativeDecimalFormat.java
index f512002..fd179c1 100644
--- a/luni/src/main/java/libcore/icu/NativeDecimalFormat.java
+++ b/luni/src/main/java/libcore/icu/NativeDecimalFormat.java
@@ -475,9 +475,9 @@
         setAttribute(this.address, UNUM_DECIMAL_ALWAYS_SHOWN, i);
     }
 
-    public void setCurrency(Currency currency) {
-        setSymbol(this.address, UNUM_CURRENCY_SYMBOL, currency.getSymbol());
-        setSymbol(this.address, UNUM_INTL_CURRENCY_SYMBOL, currency.getCurrencyCode());
+    public void setCurrency(String currencySymbol, String currencyCode) {
+        setSymbol(this.address, UNUM_CURRENCY_SYMBOL, currencySymbol);
+        setSymbol(this.address, UNUM_INTL_CURRENCY_SYMBOL, currencyCode);
     }
 
     public void setGroupingSize(int value) {
diff --git a/luni/src/main/java/libcore/net/url/FileURLConnection.java b/luni/src/main/java/libcore/net/url/FileURLConnection.java
index 94fe1d6..43eaa7d 100644
--- a/luni/src/main/java/libcore/net/url/FileURLConnection.java
+++ b/luni/src/main/java/libcore/net/url/FileURLConnection.java
@@ -225,13 +225,8 @@
 
     /**
      * Returns the length of the file in bytes.
-     *
-     * @return the length of the file
-     * @since 1.7
-     * @hide Until ready for a public API change
      */
-    @Override
-    public long getContentLengthLong() {
+    private long getContentLengthLong() {
         try {
             if (!connected) {
                 connect();
diff --git a/luni/src/main/java/libcore/net/url/JarURLConnectionImpl.java b/luni/src/main/java/libcore/net/url/JarURLConnectionImpl.java
index e00bcab..b01a20a 100644
--- a/luni/src/main/java/libcore/net/url/JarURLConnectionImpl.java
+++ b/luni/src/main/java/libcore/net/url/JarURLConnectionImpl.java
@@ -265,25 +265,12 @@
      */
     @Override
     public int getContentLength() {
-        long length = getContentLengthLong();
-        return length > Integer.MAX_VALUE ? -1 : (int) length;
-    }
-
-    /**
-     * Returns the content length of the resource. Test cases reveal that if the URL is referring to
-     * a Jar file, this method answers a content-length returned by URLConnection. For a jar entry
-     * it should return the entry's size. Otherwise, it will return -1.
-     *
-     * @hide Until ready for a public API change
-     */
-    @Override
-    public long getContentLengthLong() {
         try {
             connect();
             if (jarEntry == null) {
-                return jarFileURLConnection.getContentLengthLong();
+                return jarFileURLConnection.getContentLength();
             }
-            return getJarEntry().getSize();
+            return (int) getJarEntry().getSize();
         } catch (IOException e) {
             // Ignored
         }
diff --git a/luni/src/main/java/libcore/util/ZoneInfo.java b/luni/src/main/java/libcore/util/ZoneInfo.java
index 54ee667..ed7ab64 100644
--- a/luni/src/main/java/libcore/util/ZoneInfo.java
+++ b/luni/src/main/java/libcore/util/ZoneInfo.java
@@ -51,7 +51,7 @@
     private final byte[] mTypes;
     private final byte[] mIsDsts;
 
-    public static TimeZone makeTimeZone(String id, BufferIterator it) {
+    public static ZoneInfo makeTimeZone(String id, BufferIterator it) {
         // Variable names beginning tzh_ correspond to those in "tzfile.h".
 
         // Check tzh_magic.
@@ -301,4 +301,13 @@
             ",transitions=" + mTransitions.length +
             "]";
     }
+
+    @Override
+    public Object clone() {
+        // Overridden for documentation. The default clone() behavior is exactly what we want.
+        // Though mutable, the arrays of offset data are treated as immutable. Only ID and
+        // mRawOffset are mutable in this class, and those are an immutable object and a primitive
+        // respectively.
+        return super.clone();
+    }
 }
diff --git a/luni/src/main/java/libcore/util/ZoneInfoDB.java b/luni/src/main/java/libcore/util/ZoneInfoDB.java
index 7ff377c..3464ad6 100644
--- a/luni/src/main/java/libcore/util/ZoneInfoDB.java
+++ b/luni/src/main/java/libcore/util/ZoneInfoDB.java
@@ -68,6 +68,28 @@
     private int[] byteOffsets;
     private int[] rawUtcOffsets;
 
+    /**
+     * ZoneInfo objects are worth caching because they are expensive to create.
+     * See http://b/8270865 for context.
+     */
+    private final static int CACHE_SIZE = 1;
+    private final BasicLruCache<String, ZoneInfo> cache =
+        new BasicLruCache<String, ZoneInfo>(CACHE_SIZE) {
+      @Override
+      protected ZoneInfo create(String id) {
+          // Work out where in the big data file this time zone is.
+          int index = Arrays.binarySearch(ids, id);
+          if (index < 0) {
+              return null;
+          }
+
+          BufferIterator it = mappedFile.bigEndianIterator();
+          it.skip(byteOffsets[index]);
+
+          return ZoneInfo.makeTimeZone(id, it);
+      }
+    };
+
     public TzData(String... paths) {
       for (String path : paths) {
         if (loadData(path)) {
@@ -206,17 +228,9 @@
       return zoneTab;
     }
 
-    public TimeZone makeTimeZone(String id) throws IOException {
-      // Work out where in the big data file this time zone is.
-      int index = Arrays.binarySearch(ids, id);
-      if (index < 0) {
-        return null;
-      }
-
-      BufferIterator it = mappedFile.bigEndianIterator();
-      it.skip(byteOffsets[index]);
-
-      return ZoneInfo.makeTimeZone(id, it);
+    public ZoneInfo makeTimeZone(String id) throws IOException {
+      // The object from the cache is cloned because TimeZone / ZoneInfo are mutable.
+      return (ZoneInfo) cache.get(id).clone();
     }
   }
 
diff --git a/luni/src/main/native/Register.cpp b/luni/src/main/native/Register.cpp
index 5db47b5..4aaa905 100644
--- a/luni/src/main/native/Register.cpp
+++ b/luni/src/main/native/Register.cpp
@@ -34,7 +34,6 @@
 
 #define REGISTER(FN) extern void FN(JNIEnv*); FN(env)
     REGISTER(register_android_system_OsConstants);
-    REGISTER(register_java_io_Console);
     REGISTER(register_java_io_File);
     REGISTER(register_java_io_ObjectStreamClass);
     REGISTER(register_java_lang_Character);
diff --git a/luni/src/main/native/java_io_Console.cpp b/luni/src/main/native/java_io_Console.cpp
deleted file mode 100644
index 512bc72..0000000
--- a/luni/src/main/native/java_io_Console.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#define LOG_TAG "Console"
-
-#include "JNIHelp.h"
-#include "JniConstants.h"
-
-#include <errno.h>
-#include <termios.h>
-#include <unistd.h>
-
-static jint Console_setEchoImpl(JNIEnv* env, jclass, jboolean on, jint previousState) {
-    termios state;
-    if (TEMP_FAILURE_RETRY(tcgetattr(STDIN_FILENO, &state)) == -1) {
-        jniThrowIOException(env, errno);
-        return 0;
-    }
-    if (on) {
-        state.c_lflag = previousState;
-    } else {
-        previousState = state.c_lflag;
-        state.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
-    }
-    if (TEMP_FAILURE_RETRY(tcsetattr(STDIN_FILENO, TCSAFLUSH, &state)) == -1){
-        jniThrowIOException(env, errno);
-        return 0;
-    }
-    return previousState;
-}
-
-static JNINativeMethod gMethods[] = {
-    NATIVE_METHOD(Console, setEchoImpl, "(ZI)I"),
-};
-void register_java_io_Console(JNIEnv* env) {
-    jniRegisterNativeMethods(env, "java/io/Console", gMethods, NELEM(gMethods));
-}
diff --git a/luni/src/main/native/libcore_io_Posix.cpp b/luni/src/main/native/libcore_io_Posix.cpp
index 2592fe7..51dd8a1 100644
--- a/luni/src/main/native/libcore_io_Posix.cpp
+++ b/luni/src/main/native/libcore_io_Posix.cpp
@@ -868,7 +868,7 @@
   int rc = pthread_threadid_np(NULL, &owner);  // Requires Mac OS 10.6
   if (rc != 0) {
     throwErrnoException(env, "gettid");
-    return NULL;
+    return 0;
   }
   return static_cast<jint>(owner);
 #else
diff --git a/luni/src/main/native/sub.mk b/luni/src/main/native/sub.mk
index 9ca5054..5b581f3 100644
--- a/luni/src/main/native/sub.mk
+++ b/luni/src/main/native/sub.mk
@@ -14,7 +14,6 @@
     android_system_OsConstants.cpp \
     canonicalize_path.cpp \
     cbigint.cpp \
-    java_io_Console.cpp \
     java_io_File.cpp \
     java_io_ObjectStreamClass.cpp \
     java_lang_Character.cpp \
@@ -58,8 +57,8 @@
     valueOf.cpp \
 
 LOCAL_C_INCLUDES += \
-    external/icu4c/common \
-    external/icu4c/i18n \
+    external/icu/icu4c/source/common \
+    external/icu/icu4c/source/i18n \
     external/openssl/include \
     external/zlib \
     system/core/include \
diff --git a/luni/src/test/java/libcore/icu/DateIntervalFormatTest.java b/luni/src/test/java/libcore/icu/DateIntervalFormatTest.java
index 18228f9..bac8138 100644
--- a/luni/src/test/java/libcore/icu/DateIntervalFormatTest.java
+++ b/luni/src/test/java/libcore/icu/DateIntervalFormatTest.java
@@ -38,6 +38,7 @@
     c.set(Calendar.HOUR_OF_DAY, 3);
     c.set(Calendar.MINUTE, 30);
     c.set(Calendar.SECOND, 15);
+    c.set(Calendar.MILLISECOND, 0);
     long timeWithCurrentYear = c.getTimeInMillis();
 
     c.set(Calendar.YEAR, 2009);
@@ -169,6 +170,7 @@
     Locale l = Locale.US;
     TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
     Calendar c = Calendar.getInstance(tz, l);
+    c.clear();
     c.set(2042, Calendar.JANUARY, 19, 3, 30);
     long jan_19_2042 = c.getTimeInMillis();
     c.set(2046, Calendar.OCTOBER, 4, 3, 30);
@@ -261,6 +263,45 @@
     assertEquals("January 1, 1970, 22:00 – January 2, 1970, 00:30", formatDateRange(l, utc, 22 * HOUR, 24 * HOUR + 30 * MINUTE, flags));
   }
 
+  // The fix for http://b/10560853 didn't work except for the day around the epoch, which was
+  // all the unit test checked!
+  public void test_single_day_events_later_than_epoch() throws Exception {
+    Locale l = Locale.US;
+    TimeZone utc = TimeZone.getTimeZone("UTC");
+
+    int flags = FORMAT_SHOW_TIME | FORMAT_24HOUR | FORMAT_SHOW_DATE;
+
+    Calendar c = Calendar.getInstance(utc, l);
+    c.clear();
+    c.set(1980, Calendar.JANUARY, 1, 0, 0);
+    long jan_1_1980 = c.getTimeInMillis();
+    assertEquals("January 1, 1980, 22:00 – 00:00",
+                 formatDateRange(l, utc, jan_1_1980 + 22 * HOUR, jan_1_1980 + 24 * HOUR, flags));
+    assertEquals("January 1, 1980, 22:00 – January 2, 1980, 00:30",
+                 formatDateRange(l, utc, jan_1_1980 + 22 * HOUR, jan_1_1980 + 24 * HOUR + 30 * MINUTE, flags));
+  }
+
+  // The fix for http://b/10560853 didn't work except for UTC, which was
+  // all the unit test checked!
+  public void test_single_day_events_not_in_UTC() throws Exception {
+    Locale l = Locale.US;
+    TimeZone pacific = TimeZone.getTimeZone("America/Los_Angeles");
+
+    int flags = FORMAT_SHOW_TIME | FORMAT_24HOUR | FORMAT_SHOW_DATE;
+
+    Calendar c = Calendar.getInstance(pacific, l);
+    c.clear();
+    c.set(1980, Calendar.JANUARY, 1, 0, 0);
+    long jan_1_1980 = c.getTimeInMillis();
+    assertEquals("January 1, 1980, 22:00 – 00:00",
+                 formatDateRange(l, pacific, jan_1_1980 + 22 * HOUR, jan_1_1980 + 24 * HOUR, flags));
+
+    c.set(1980, Calendar.JULY, 1, 0, 0);
+    long jul_1_1980 = c.getTimeInMillis();
+    assertEquals("July 1, 1980, 22:00 – 00:00",
+                 formatDateRange(l, pacific, jul_1_1980 + 22 * HOUR, jul_1_1980 + 24 * HOUR, flags));
+  }
+
   // http://b/10209343 - even if the caller didn't explicitly ask us to include the year,
   // we should do so for years other than the current year.
   public void test10209343_when_not_this_year() {
@@ -343,6 +384,7 @@
   public void test12004664() throws Exception {
     TimeZone utc = TimeZone.getTimeZone("UTC");
     Calendar c = Calendar.getInstance(utc, Locale.US);
+    c.clear();
     c.set(Calendar.YEAR, 1980);
     c.set(Calendar.MONTH, Calendar.FEBRUARY);
     c.set(Calendar.DAY_OF_MONTH, 10);
diff --git a/luni/src/test/java/libcore/java/lang/CharacterTest.java b/luni/src/test/java/libcore/java/lang/CharacterTest.java
index 0028521..94e3b96 100644
--- a/luni/src/test/java/libcore/java/lang/CharacterTest.java
+++ b/luni/src/test/java/libcore/java/lang/CharacterTest.java
@@ -277,66 +277,4 @@
       }
     }
   }
-
-  public void test_UnicodeScript_forName() throws Exception {
-    try {
-      Character.UnicodeScript.forName(null);
-      fail();
-    } catch (NullPointerException expected) {
-    }
-
-    try {
-      Character.UnicodeScript.forName("existential_dilemmas");
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-
-    // Note that ICU is pretty lenient about block names and their abbreviations.
-    assertSame(Character.UnicodeScript.MALAYALAM, Character.UnicodeScript.forName("Malayalam"));
-    assertSame(Character.UnicodeScript.MALAYALAM, Character.UnicodeScript.forName("MalayaLAM"));
-    assertSame(Character.UnicodeScript.MALAYALAM, Character.UnicodeScript.forName("Mlym"));
-    assertSame(Character.UnicodeScript.MALAYALAM, Character.UnicodeScript.forName("MlYM"));
-
-    assertSame(Character.UnicodeScript.OLD_SOUTH_ARABIAN, Character.UnicodeScript.forName("Old_south_arabian"));
-
-    // NOTE: This test fails on the RI because they're much stricter in
-    // their matching. Strict enough that they fail on "Old south arabian", despite
-    // it being the official name AND the alias for this script.
-    assertSame(Character.UnicodeScript.OLD_SOUTH_ARABIAN, Character.UnicodeScript.forName("Old south arabian"));
-    assertSame(Character.UnicodeScript.OLD_SOUTH_ARABIAN, Character.UnicodeScript.forName("SARB"));
-
-    // A script that's recognized by ICU but not a part of the standard
-    // java script values.
-    try {
-      Character.UnicodeScript.forName("Old north arabian");
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-  }
-
-  public void test_UnicodeScript_of() throws Exception {
-    try {
-      Character.UnicodeScript.of(-1);
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-
-    try {
-      Character.UnicodeScript.of(0xffffff);
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-
-    // The example from the ICU4C unit tests.
-    assertSame(Character.UnicodeScript.MALAYALAM, Character.UnicodeScript.of(0x0D02));
-
-    // Special cases:
-    //
-    // 0640 is the ARABIC_TATWEEL, used by both Mandiac & Syriac
-    assertSame(Character.UnicodeScript.COMMON, Character.UnicodeScript.of(0x0640));
-    // 0300 is the COMBINING GRAVE ACCENT, which should be INHERITED because it's
-    // a nonspacing mark.
-    assertSame(Character.UnicodeScript.INHERITED, Character.UnicodeScript.of(0x0300));
-    assertSame(Character.UnicodeScript.COMMON, Character.UnicodeScript.of(0x0640));
-  }
 }
diff --git a/luni/src/test/java/libcore/java/lang/StringTest.java b/luni/src/test/java/libcore/java/lang/StringTest.java
index 7df852e..bf162e5 100644
--- a/luni/src/test/java/libcore/java/lang/StringTest.java
+++ b/luni/src/test/java/libcore/java/lang/StringTest.java
@@ -376,4 +376,71 @@
         assertEquals("[-77, -10, -64, -76]", Arrays.toString("出来".getBytes("gbk")));
         assertEquals("[-77, -10]", Arrays.toString("出".getBytes("gbk")));
     }
+
+    public void test_compareTo() throws Exception {
+        // For strings where a character differs, the result is
+        // the difference between the characters.
+        assertEquals(-1, "a".compareTo("b"));
+        assertEquals(-2, "a".compareTo("c"));
+        assertEquals(1, "b".compareTo("a"));
+        assertEquals(2, "c".compareTo("a"));
+
+        // For strings where the characters match up to the length of the shorter,
+        // the result is the difference between the strings' lengths.
+        assertEquals(0, "a".compareTo("a"));
+        assertEquals(-1, "a".compareTo("aa"));
+        assertEquals(-1, "a".compareTo("az"));
+        assertEquals(-2, "a".compareTo("aaa"));
+        assertEquals(-2, "a".compareTo("azz"));
+        assertEquals(-3, "a".compareTo("aaaa"));
+        assertEquals(-3, "a".compareTo("azzz"));
+        assertEquals(0, "a".compareTo("a"));
+        assertEquals(1, "aa".compareTo("a"));
+        assertEquals(1, "az".compareTo("a"));
+        assertEquals(2, "aaa".compareTo("a"));
+        assertEquals(2, "azz".compareTo("a"));
+        assertEquals(3, "aaaa".compareTo("a"));
+        assertEquals(3, "azzz".compareTo("a"));
+    }
+
+    public void test_compareToIgnoreCase() throws Exception {
+        // For strings where a character differs, the result is
+        // the difference between the characters.
+        assertEquals(-1, "a".compareToIgnoreCase("b"));
+        assertEquals(-1, "a".compareToIgnoreCase("B"));
+        assertEquals(-2, "a".compareToIgnoreCase("c"));
+        assertEquals(-2, "a".compareToIgnoreCase("C"));
+        assertEquals(1, "b".compareToIgnoreCase("a"));
+        assertEquals(1, "B".compareToIgnoreCase("a"));
+        assertEquals(2, "c".compareToIgnoreCase("a"));
+        assertEquals(2, "C".compareToIgnoreCase("a"));
+
+        // For strings where the characters match up to the length of the shorter,
+        // the result is the difference between the strings' lengths.
+        assertEquals(0, "a".compareToIgnoreCase("a"));
+        assertEquals(0, "a".compareToIgnoreCase("A"));
+        assertEquals(0, "A".compareToIgnoreCase("a"));
+        assertEquals(0, "A".compareToIgnoreCase("A"));
+        assertEquals(-1, "a".compareToIgnoreCase("aa"));
+        assertEquals(-1, "a".compareToIgnoreCase("aA"));
+        assertEquals(-1, "a".compareToIgnoreCase("Aa"));
+        assertEquals(-1, "a".compareToIgnoreCase("az"));
+        assertEquals(-1, "a".compareToIgnoreCase("aZ"));
+        assertEquals(-2, "a".compareToIgnoreCase("aaa"));
+        assertEquals(-2, "a".compareToIgnoreCase("AAA"));
+        assertEquals(-2, "a".compareToIgnoreCase("azz"));
+        assertEquals(-2, "a".compareToIgnoreCase("AZZ"));
+        assertEquals(-3, "a".compareToIgnoreCase("aaaa"));
+        assertEquals(-3, "a".compareToIgnoreCase("AAAA"));
+        assertEquals(-3, "a".compareToIgnoreCase("azzz"));
+        assertEquals(-3, "a".compareToIgnoreCase("AZZZ"));
+        assertEquals(1, "aa".compareToIgnoreCase("a"));
+        assertEquals(1, "aA".compareToIgnoreCase("a"));
+        assertEquals(1, "Aa".compareToIgnoreCase("a"));
+        assertEquals(1, "az".compareToIgnoreCase("a"));
+        assertEquals(2, "aaa".compareToIgnoreCase("a"));
+        assertEquals(2, "azz".compareToIgnoreCase("a"));
+        assertEquals(3, "aaaa".compareToIgnoreCase("a"));
+        assertEquals(3, "azzz".compareToIgnoreCase("a"));
+    }
 }
diff --git a/luni/src/test/java/libcore/java/net/SocketTest.java b/luni/src/test/java/libcore/java/net/SocketTest.java
index b9ed99c..fb09be0 100644
--- a/luni/src/test/java/libcore/java/net/SocketTest.java
+++ b/luni/src/test/java/libcore/java/net/SocketTest.java
@@ -90,7 +90,7 @@
         // Open a local server port.
         ServerSocketChannel ssc = ServerSocketChannel.open();
         InetSocketAddress listenAddr = new InetSocketAddress(host, 0);
-        ssc.bind(listenAddr, 0);
+        ssc.socket().bind(listenAddr, 0);
         ServerSocket ss = ssc.socket();
 
         // Open a socket to the local port.
@@ -110,7 +110,7 @@
             in.socket().setTcpNoDelay(false);
         }
 
-        InetSocketAddress listenAddress = (InetSocketAddress) in.getLocalAddress();
+        InetSocketAddress listenAddress = (InetSocketAddress) in.socket().getLocalSocketAddress();
         InetSocketAddress outRemoteAddress = (InetSocketAddress) out.socket().getRemoteSocketAddress();
         InetSocketAddress outLocalAddress = (InetSocketAddress) out.socket().getLocalSocketAddress();
         InetSocketAddress inLocalAddress = (InetSocketAddress) in.socket().getLocalSocketAddress();
diff --git a/luni/src/test/java/libcore/java/nio/channels/DatagramChannelMulticastTest.java b/luni/src/test/java/libcore/java/nio/channels/DatagramChannelMulticastTest.java
deleted file mode 100644
index f0db3ba..0000000
--- a/luni/src/test/java/libcore/java/nio/channels/DatagramChannelMulticastTest.java
+++ /dev/null
@@ -1,1120 +0,0 @@
-package libcore.java.nio.channels;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.InterfaceAddress;
-import java.net.NetworkInterface;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.net.StandardSocketOptions;
-import java.nio.ByteBuffer;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.DatagramChannel;
-import java.nio.channels.MembershipKey;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-
-/**
- * Tests associated with multicast behavior of DatagramChannel.
- */
-public class DatagramChannelMulticastTest extends TestCase {
-
-  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 final InetAddress GOOD_MULTICAST_IPv4 = lookup("239.255.0.1");
-  private static final InetAddress BAD_MULTICAST_IPv4 = lookup("239.255.0.2");
-  private static final InetAddress GOOD_MULTICAST_IPv6 = lookup("ff05::7:7");
-  private static final InetAddress BAD_MULTICAST_IPv6 = lookup("ff05::7:8");
-
-  // Special addresses.
-  private static final InetAddress WILDCARD_IPv4 = lookup("0.0.0.0");
-  private static final InetAddress WILDCARD_IPv6 = lookup("::");
-
-  // Arbitrary unicast addresses. Used when the value doesn't actually matter. e.g. for source
-  // filters.
-  private static final InetAddress UNICAST_IPv4_1 = lookup("192.168.1.1");
-  private static final InetAddress UNICAST_IPv4_2 = lookup("192.168.1.2");
-  private static final InetAddress UNICAST_IPv6_1 = lookup("2001:db8::1");
-  private static final InetAddress UNICAST_IPv6_2 = lookup("2001:db8::2");
-
-  private List<NetworkInterface> ipv4networkInterfaces = new ArrayList<NetworkInterface>();
-  private List<NetworkInterface> ipv6networkInterfaces = new ArrayList<NetworkInterface>();
-  private NetworkInterface ipv4networkInterface;
-  private NetworkInterface ipv6networkInterface;
-  private NetworkInterface loopbackInterface;
-
-  @Override
-  protected void setUp() throws Exception {
-    // The loopback interface isn't actually useful for sending/receiving multicast messages but it
-    // can be used as a dummy for tests where that does not matter.
-    loopbackInterface = NetworkInterface.getByInetAddress(InetAddress.getLoopbackAddress());
-    assertNotNull(loopbackInterface);
-    assertTrue(loopbackInterface.isLoopback());
-    assertFalse(loopbackInterface.supportsMulticast());
-
-    Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
-    assertNotNull(interfaces);
-    // Only consider interfaces that have addresses associated with them. Otherwise tests don't work
-    // so well.
-    while (interfaces.hasMoreElements()) {
-      NetworkInterface networkInterface = interfaces.nextElement();
-      if (willWorkForMulticast(networkInterface)) {
-        Enumeration<InetAddress> addresses = networkInterface.getInetAddresses();
-        while (addresses.hasMoreElements()) {
-          final InetAddress nextAddress = addresses.nextElement();
-          if (nextAddress instanceof Inet4Address) {
-            ipv4networkInterfaces.add(networkInterface);
-          } else if (nextAddress instanceof Inet6Address) {
-            ipv6networkInterfaces.add(networkInterface);
-          }
-        }
-      }
-    }
-    assertTrue(
-        "Test environment must have network interfaces capable of both IPv4 and IPv6 multicast",
-        ipv4networkInterfaces.size() > 0 && ipv6networkInterfaces.size() > 0);
-    ipv4networkInterface = ipv4networkInterfaces.get(0);
-    ipv6networkInterface = ipv6networkInterfaces.get(0);
-  }
-
-  public void test_open() throws IOException {
-    DatagramChannel dc = DatagramChannel.open();
-
-    // Unlike MulticastSocket, DatagramChannel has SO_REUSEADDR set to false by default.
-    assertFalse(dc.getOption(StandardSocketOptions.SO_REUSEADDR));
-
-    // Confirm multicast loop is on by default as specified in the docs. Many tests in this class
-    // depend on this being true.
-    assertTrue(dc.getOption(StandardSocketOptions.IP_MULTICAST_LOOP));
-
-    assertNull(dc.getLocalAddress());
-    assertTrue(dc.isOpen());
-    assertFalse(dc.isConnected());
-
-    dc.close();
-  }
-
-  public void test_bind_null() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    assertNotNull(dc.getLocalAddress());
-    assertTrue(dc.isOpen());
-    assertFalse(dc.isConnected());
-
-    dc.close();
-    try {
-      dc.getLocalAddress();
-      fail();
-    } catch (ClosedChannelException expected) {
-    }
-    assertFalse(dc.isOpen());
-    assertFalse(dc.isConnected());
-  }
-
-  public void test_joinAnySource_afterClose() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    dc.close();
-    try {
-      dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface);
-      fail();
-    } catch (ClosedChannelException expected) {
-    }
-  }
-
-  public void test_joinAnySource_nullGroupAddress() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    try {
-      dc.join(null, ipv4networkInterface);
-      fail();
-    } catch (NullPointerException expected) {
-    }
-    dc.close();
-  }
-
-  public void test_joinAnySource_nullNetworkInterface() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    try {
-      dc.join(GOOD_MULTICAST_IPv4, null);
-      fail();
-    } catch (NullPointerException expected) {
-    }
-    dc.close();
-  }
-
-  public void test_joinAnySource_nonMulticastGroupAddress_IPv4() throws Exception {
-    for (NetworkInterface networkInterface : ipv4networkInterfaces) {
-      test_joinAnySource_illegalArgumentExpected(networkInterface, UNICAST_IPv4_1);
-    }
-  }
-
-  public void test_joinAnySource_nonMulticastGroupAddress_IPv6() throws Exception {
-    for (NetworkInterface networkInterface : ipv6networkInterfaces) {
-      test_joinAnySource_illegalArgumentExpected(networkInterface, UNICAST_IPv6_1);
-    }
-  }
-
-  private void test_joinAnySource_illegalArgumentExpected(NetworkInterface networkInterface,
-      InetAddress group) throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    try {
-      dc.join(group, networkInterface);
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-    dc.close();
-  }
-
-  public void test_joinAnySource_IPv4() throws Exception {
-    test_joinAnySource(ipv4networkInterfaces, GOOD_MULTICAST_IPv4, BAD_MULTICAST_IPv4);
-  }
-
-  public void test_joinAnySource_IPv6() throws Exception {
-    test_joinAnySource(ipv6networkInterfaces, GOOD_MULTICAST_IPv6, BAD_MULTICAST_IPv6);
-  }
-
-  private void test_joinAnySource(
-      Iterable<NetworkInterface> networkInterfaces, InetAddress group, InetAddress group2)
-      throws Exception {
-    for (NetworkInterface networkInterface : networkInterfaces) {
-      // Set up a receiver join the group on networkInterface.
-      DatagramChannel receiverChannel = createReceiverChannel();
-      InetSocketAddress localAddress = (InetSocketAddress) receiverChannel.getLocalAddress();
-      receiverChannel.join(group, networkInterface);
-
-      // Send a message to the group we joined.
-      String msg = "Hello World";
-      sendMessage(group, localAddress.getPort(), msg, networkInterface);
-
-      // Now verify that we received the data as expected.
-      ByteBuffer recvBuffer = ByteBuffer.allocate(100);
-      SocketAddress sourceAddress = receiverChannel.receive(recvBuffer);
-      assertNotNull(sourceAddress);
-      assertEquals(msg, new String(recvBuffer.array(), 0, recvBuffer.position()));
-
-      // Send a message to the group we did not join.
-      String msg2 = "Hello World - Different Group";
-      sendMessage(group2, localAddress.getPort(), msg2, networkInterface);
-      recvBuffer.position(0);
-      // Now verify that we didn't receive the second message.
-      SocketAddress sourceAddress2 = receiverChannel.receive(recvBuffer);
-      assertNull(sourceAddress2);
-
-      receiverChannel.close();
-    }
-  }
-
-  public void test_joinAnySource_processLimit() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    for (byte i = 1; i <= 25; i++) {
-      InetAddress groupAddress = Inet4Address.getByName("239.255.0." + i);
-      try {
-        dc.join(groupAddress, ipv4networkInterface);
-      } catch (SocketException e) {
-        // There is a limit, that's ok according to the RI docs. For this test a lower bound of 20
-        // is used, which appears to be the default linux limit.
-        // See /proc/sys/net/ipv4/igmp_max_memberships.
-        assertTrue(i > 20);
-        break;
-      }
-    }
-
-    dc.close();
-  }
-
-  public void test_joinAnySource_blockLimit() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    MembershipKey key = dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface);
-    for (byte i = 1; i <= 15; i++) {
-      InetAddress sourceAddress = Inet4Address.getByName("10.0.0." + i);
-      try {
-        key.block(sourceAddress);
-      } catch (SocketException e) {
-        // There is a limit, that's ok according to the RI docs. For this test a lower bound of 10
-        // is used, which appears to be the default linux limit.
-        // See /proc/sys/net/ipv4/igmp_max_msf.
-        assertTrue(i > 10);
-        break;
-      }
-    }
-
-    dc.close();
-  }
-
-  /** Confirms that calling join() does not cause an implicit bind() to take place. */
-  public void test_joinAnySource_doesNotCauseBind_IPv4() throws Exception {
-    test_joinAnySource_doesNotCauseBind(ipv4networkInterfaces, GOOD_MULTICAST_IPv4);
-  }
-
-  public void test_joinAnySource_doesNotCauseBind_IPv6() throws Exception {
-    test_joinAnySource_doesNotCauseBind(ipv6networkInterfaces, GOOD_MULTICAST_IPv6);
-  }
-
-  private void test_joinAnySource_doesNotCauseBind(
-      Iterable<NetworkInterface> networkInterfaces, InetAddress group) throws IOException {
-    for (NetworkInterface networkInterface : networkInterfaces) {
-      DatagramChannel dc = DatagramChannel.open();
-      dc.join(group, networkInterface);
-      assertNull(dc.getLocalAddress());
-      dc.close();
-    }
-  }
-
-  public void test_joinAnySource_networkInterfaces() throws Exception {
-    // Check that we can join on specific interfaces and that we only receive if data is
-    // received on that interface. This test is only really useful on devices with multiple
-    // non-loopback interfaces.
-
-    ArrayList<NetworkInterface> realInterfaces = new ArrayList<NetworkInterface>();
-    Enumeration<NetworkInterface> theInterfaces = NetworkInterface.getNetworkInterfaces();
-    while (theInterfaces.hasMoreElements()) {
-      NetworkInterface thisInterface = theInterfaces.nextElement();
-      // Skip interfaces that do not support multicast - there's no point in proving they cannot
-      // send / receive multicast messages.
-      if (willWorkForMulticast(thisInterface)) {
-        realInterfaces.add(thisInterface);
-      }
-    }
-
-    for (NetworkInterface thisInterface : realInterfaces) {
-      // Get the first address on the interface.
-      Enumeration<InetAddress> addresses = thisInterface.getInetAddresses();
-
-      while (addresses.hasMoreElements()) {
-        InetAddress listenAddress = addresses.nextElement();
-
-        // Start a server which is joined to the group and has only asked for packets on this
-        // interface.
-        NetworkInterface sendingInterface;
-        InetAddress group;
-        if (listenAddress instanceof Inet4Address) {
-          group = GOOD_MULTICAST_IPv4;
-          sendingInterface = ipv4networkInterface;
-        } else {
-          group = GOOD_MULTICAST_IPv6;
-          sendingInterface = ipv6networkInterface;
-        }
-        DatagramChannel dc = createReceiverChannel();
-        InetSocketAddress localAddress = (InetSocketAddress) dc.getLocalAddress();
-        dc.join(group, thisInterface);
-
-        // Now send out a packet on sendingInterface. We should only see the packet if we send
-        // it on the same interface we are listening on (thisInterface).
-        String msg = "Hello World - Again " + thisInterface.getName();
-        sendMessage(group, localAddress.getPort(), msg, sendingInterface);
-
-        ByteBuffer recvBuffer = ByteBuffer.allocate(100);
-        SocketAddress sourceAddress = dc.receive(recvBuffer);
-        if (thisInterface.equals(sendingInterface)) {
-          assertEquals(msg, new String(recvBuffer.array(), 0, recvBuffer.position()));
-        } else {
-          assertNull(sourceAddress);
-        }
-
-        dc.close();
-      }
-    }
-  }
-
-  /** Confirms that the scope of each membership is network interface-level. */
-  public void test_join_canMixJoinTypesOnDifferentInterfaces() throws Exception {
-    DatagramChannel dc = DatagramChannel.open();
-    MembershipKey membershipKey1 = dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface);
-    MembershipKey membershipKey2 = dc.join(GOOD_MULTICAST_IPv4, loopbackInterface, UNICAST_IPv4_1);
-    assertNotSame(membershipKey1, membershipKey2);
-
-    dc.close();
-  }
-
-  public void test_joinAnySource_multiple_joins_IPv4()
-      throws Exception {
-    test_joinAnySource_multiple_joins(ipv4networkInterfaces, GOOD_MULTICAST_IPv4);
-  }
-
-  public void test_joinAnySource_multiple_joins_IPv6()
-      throws Exception {
-    test_joinAnySource_multiple_joins(ipv6networkInterfaces, GOOD_MULTICAST_IPv6);
-  }
-
-  private void test_joinAnySource_multiple_joins(
-      Iterable<NetworkInterface> networkInterfaces, InetAddress group) throws Exception {
-    for (NetworkInterface networkInterface : networkInterfaces) {
-      DatagramChannel dc = createReceiverChannel();
-
-      MembershipKey membershipKey1 = dc.join(group, networkInterface);
-
-      MembershipKey membershipKey2 = dc.join(group, loopbackInterface);
-      assertFalse(membershipKey1.equals(membershipKey2));
-
-      MembershipKey membershipKey1_2 = dc.join(group, networkInterface);
-      assertEquals(membershipKey1, membershipKey1_2);
-
-      dc.close();
-    }
-  }
-
-  public void test_joinAnySource_multicastLoopOption_IPv4() throws Exception {
-    test_joinAnySource_multicastLoopOption(ipv4networkInterfaces, GOOD_MULTICAST_IPv4);
-  }
-
-  public void test_joinAnySource_multicastLoopOption_IPv6() throws Exception {
-    test_joinAnySource_multicastLoopOption(ipv6networkInterfaces, GOOD_MULTICAST_IPv6);
-  }
-
-  private void test_joinAnySource_multicastLoopOption(
-      Iterable<NetworkInterface> networkInterfaces, InetAddress group) throws Exception {
-    final String message = "Hello, world!";
-
-    for (NetworkInterface networkInterface : networkInterfaces) {
-      DatagramChannel dc = DatagramChannel.open();
-      configureChannelForReceiving(dc);
-      dc.bind(null /* leave the OS to determine the port, and use the wildcard address */);
-
-      // Make sure that the sent packets will be sent via the interface we will be joining with.
-      dc.setOption(StandardSocketOptions.IP_MULTICAST_IF, networkInterface);
-      dc.join(group, networkInterface);
-
-      // Test with loop on.
-      dc.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, true /* enable loop */);
-
-      InetSocketAddress localAddress = (InetSocketAddress) dc.getLocalAddress();
-
-      // Send the datagram.
-      sendMessage(dc, message, new InetSocketAddress(group, localAddress.getPort()));
-
-      // Receive the datagram.
-      ByteBuffer recvBuffer = ByteBuffer.allocate(100);
-      SocketAddress sourceAddress = dc.receive(recvBuffer);
-      assertNotNull(sourceAddress);
-
-      String recvMessage = new String(recvBuffer.array(), 0, recvBuffer.position());
-      assertEquals(message, recvMessage);
-
-      // Turn off loop.
-      dc.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, false /* enable loopback */);
-
-      // Send another datagram.
-      recvBuffer.position(0);
-      sendMessage(dc, message, new InetSocketAddress(group, localAddress.getPort()));
-
-      SocketAddress sourceAddress2 = dc.receive(recvBuffer);
-      assertNull(sourceAddress2);
-
-      dc.close();
-    }
-  }
-
-  public void testMembershipKeyAccessors_IPv4() throws Exception {
-    testMembershipKeyAccessors(ipv4networkInterfaces, GOOD_MULTICAST_IPv4);
-  }
-
-  public void testMembershipKeyAccessors_IPv6() throws Exception {
-    testMembershipKeyAccessors(ipv6networkInterfaces, GOOD_MULTICAST_IPv6);
-  }
-
-  private void testMembershipKeyAccessors(
-      Iterable<NetworkInterface> networkInterfaces, InetAddress group) throws Exception {
-    for (NetworkInterface networkInterface : networkInterfaces) {
-      DatagramChannel dc = createReceiverChannel();
-
-      MembershipKey key = dc.join(group, networkInterface);
-      assertSame(dc, key.channel());
-      assertSame(group, key.group());
-      assertTrue(key.isValid());
-      assertSame(networkInterface, key.networkInterface());
-      assertNull(key.sourceAddress());
-    }
-  }
-
-  public void test_dropAnySource_twice_IPv4() throws Exception {
-    test_dropAnySource_twice(ipv4networkInterfaces, GOOD_MULTICAST_IPv4);
-  }
-
-  public void test_dropAnySource_twice_IPv6() throws Exception {
-    test_dropAnySource_twice(ipv6networkInterfaces, GOOD_MULTICAST_IPv6);
-  }
-
-  private void test_dropAnySource_twice(
-      Iterable<NetworkInterface> networkInterfaces, InetAddress group)
-      throws Exception {
-    for (NetworkInterface networkInterface : networkInterfaces) {
-      DatagramChannel dc = createReceiverChannel();
-      MembershipKey membershipKey = dc.join(group, networkInterface);
-
-      assertTrue(membershipKey.isValid());
-      membershipKey.drop();
-      assertFalse(membershipKey.isValid());
-
-      // Try to leave a group we are no longer a member of. It should do nothing.
-      membershipKey.drop();
-
-      dc.close();
-    }
-  }
-
-  public void test_close_invalidatesMembershipKey() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface);
-
-    assertTrue(membershipKey.isValid());
-
-    dc.close();
-
-    assertFalse(membershipKey.isValid());
-  }
-
-  public void test_block_null() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface);
-    try {
-      membershipKey.block(null);
-      fail();
-    } catch (NullPointerException expected) {
-    }
-
-    dc.close();
-  }
-
-  public void test_block_mixedAddressTypes_IPv4() throws Exception {
-    test_block_illegalArgument(ipv4networkInterfaces, GOOD_MULTICAST_IPv4, UNICAST_IPv6_1);
-  }
-
-  public void test_block_mixedAddressTypes_IPv6() throws Exception {
-    test_block_illegalArgument(ipv6networkInterfaces, GOOD_MULTICAST_IPv6, UNICAST_IPv4_1);
-  }
-
-  private void test_block_illegalArgument(
-      Iterable<NetworkInterface> networkInterfaces, InetAddress groupAddress,
-      InetAddress badBlockAddress) throws Exception {
-
-    for (NetworkInterface networkInterface : networkInterfaces) {
-      DatagramChannel dc = createReceiverChannel();
-      MembershipKey membershipKey = dc.join(groupAddress, networkInterface);
-      try {
-        membershipKey.block(badBlockAddress);
-        fail();
-      } catch (IllegalArgumentException expected) {
-      }
-
-      dc.close();
-    }
-  }
-
-  public void test_block_cannotBlockWithSourceSpecificMembership() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey =
-        dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface, UNICAST_IPv4_1);
-    try {
-      membershipKey.block(UNICAST_IPv4_2);
-      fail();
-    } catch (IllegalStateException expected) {
-    }
-
-    dc.close();
-  }
-
-  public void test_block_multipleBlocksIgnored() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface);
-    membershipKey.block(UNICAST_IPv4_1);
-
-    MembershipKey membershipKey2 = membershipKey.block(UNICAST_IPv4_1);
-    assertSame(membershipKey2, membershipKey);
-
-    dc.close();
-  }
-
-  public void test_block_wildcardAddress() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface);
-    try {
-      membershipKey.block(WILDCARD_IPv4);
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-
-    dc.close();
-  }
-
-  public void test_unblock_multipleUnblocksFail() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface);
-
-    try {
-      membershipKey.unblock(UNICAST_IPv4_1);
-      fail();
-    } catch (IllegalStateException expected) {
-    }
-
-    assertTrue(membershipKey.isValid());
-
-    membershipKey.block(UNICAST_IPv4_1);
-    membershipKey.unblock(UNICAST_IPv4_1);
-
-    try {
-      membershipKey.unblock(UNICAST_IPv4_1);
-      fail();
-    } catch (IllegalStateException expected) {
-    }
-
-    dc.close();
-  }
-
-  public void test_unblock_null() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface);
-    membershipKey.block(UNICAST_IPv4_1);
-
-    try {
-      membershipKey.unblock(null);
-      fail();
-    } catch (IllegalStateException expected) {
-      // Either of these exceptions are fine.
-    } catch (NullPointerException expected) {
-      // Either of these exception are fine.
-    }
-
-    dc.close();
-  }
-
-  public void test_unblock_mixedAddressTypes_IPv4() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface);
-    try {
-      membershipKey.unblock(UNICAST_IPv6_1);
-      fail();
-    } catch (IllegalStateException expected) {
-      // Either of these exceptions are fine.
-    } catch (IllegalArgumentException expected) {
-      // Either of these exceptions are fine.
-    }
-
-    dc.close();
-  }
-
-  public void test_unblock_mixedAddressTypes_IPv6() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv6, ipv6networkInterface);
-    try {
-      membershipKey.unblock(UNICAST_IPv4_1);
-      fail();
-    } catch (IllegalStateException expected) {
-      // Either of these exceptions are fine.
-    } catch (IllegalArgumentException expected) {
-      // Either of these exceptions are fine.
-    }
-
-    dc.close();
-  }
-
-  /** Checks that block() works when the receiver is bound to the multicast group address */
-  public void test_block_filtersAsExpected_groupBind_IPv4() throws Exception {
-    for (NetworkInterface networkInterface : ipv4networkInterfaces) {
-      InetAddress ipv4LocalAddress = getLocalIpv4Address(networkInterface);
-      test_block_filtersAsExpected(
-          networkInterface,
-          ipv4LocalAddress /* senderBindAddress */,
-          GOOD_MULTICAST_IPv4 /* receiverBindAddress */,
-          GOOD_MULTICAST_IPv4 /* groupAddress */);
-    }
-  }
-
-  /** Checks that block() works when the receiver is bound to the multicast group address */
-  public void test_block_filtersAsExpected_groupBind_IPv6() throws Exception {
-    for (NetworkInterface networkInterface : ipv6networkInterfaces) {
-      InetAddress ipv6LocalAddress = getLocalIpv6Address(networkInterface);
-      test_block_filtersAsExpected(
-          networkInterface,
-          ipv6LocalAddress /* senderBindAddress */,
-          GOOD_MULTICAST_IPv6 /* receiverBindAddress */,
-          GOOD_MULTICAST_IPv6 /* groupAddress */);
-    }
-  }
-
-  /** Checks that block() works when the receiver is bound to the "any" address */
-  public void test_block_filtersAsExpected_anyBind_IPv4() throws Exception {
-    for (NetworkInterface networkInterface : ipv4networkInterfaces) {
-      InetAddress ipv4LocalAddress = getLocalIpv4Address(networkInterface);
-      test_block_filtersAsExpected(
-          networkInterface,
-          ipv4LocalAddress /* senderBindAddress */,
-          WILDCARD_IPv4 /* receiverBindAddress */,
-          GOOD_MULTICAST_IPv4 /* groupAddress */);
-    }
-  }
-
-  /** Checks that block() works when the receiver is bound to the "any" address */
-  public void test_block_filtersAsExpected_anyBind_IPv6() throws Exception {
-    for (NetworkInterface networkInterface : ipv6networkInterfaces) {
-      InetAddress ipv6LocalAddress = getLocalIpv6Address(networkInterface);
-      test_block_filtersAsExpected(
-          networkInterface,
-          ipv6LocalAddress /* senderBindAddress */,
-          WILDCARD_IPv6 /* receiverBindAddress */,
-          GOOD_MULTICAST_IPv6 /* groupAddress */);
-    }
-  }
-
-  private void test_block_filtersAsExpected(
-      NetworkInterface networkInterface, InetAddress senderBindAddress,
-      InetAddress receiverBindAddress, InetAddress groupAddress) throws Exception {
-
-    DatagramChannel sendingChannel = DatagramChannel.open();
-    // In order to block a sender the sender's address must be known. The sendingChannel is
-    // explicitly bound to a known, non-loopback address.
-    sendingChannel.bind(new InetSocketAddress(senderBindAddress, 0));
-    InetSocketAddress sendingAddress = (InetSocketAddress) sendingChannel.getLocalAddress();
-
-    DatagramChannel receivingChannel = DatagramChannel.open();
-    configureChannelForReceiving(receivingChannel);
-    receivingChannel.bind(
-        new InetSocketAddress(receiverBindAddress, 0) /* local port left to the OS to determine */);
-    InetSocketAddress localReceivingAddress =
-        (InetSocketAddress) receivingChannel.getLocalAddress();
-    InetSocketAddress groupSocketAddress =
-        new InetSocketAddress(groupAddress, localReceivingAddress.getPort());
-    MembershipKey membershipKey =
-        receivingChannel.join(groupSocketAddress.getAddress(), networkInterface);
-
-    ByteBuffer receiveBuffer = ByteBuffer.allocate(10);
-
-    // Send a message. It should be received.
-    String msg1 = "Hello1";
-    sendMessage(sendingChannel, msg1, groupSocketAddress);
-    InetSocketAddress sourceAddress1 = (InetSocketAddress) receivingChannel.receive(receiveBuffer);
-    assertEquals(sendingAddress, sourceAddress1);
-    assertEquals(msg1, new String(receiveBuffer.array(), 0, receiveBuffer.position()));
-
-    // Now block the sender.
-    membershipKey.block(sendingAddress.getAddress());
-
-    // Send a message. It should be filtered.
-    String msg2 = "Hello2";
-    sendMessage(sendingChannel, msg2, groupSocketAddress);
-    receiveBuffer.position(0);
-    InetSocketAddress sourceAddress2 = (InetSocketAddress) receivingChannel.receive(receiveBuffer);
-    assertNull(sourceAddress2);
-
-    // Now unblock the sender.
-    membershipKey.unblock(sendingAddress.getAddress());
-
-    // Send a message. It should be received.
-    String msg3 = "Hello3";
-    sendMessage(sendingChannel, msg3, groupSocketAddress);
-    receiveBuffer.position(0);
-    InetSocketAddress sourceAddress3 = (InetSocketAddress) receivingChannel.receive(receiveBuffer);
-    assertEquals(sourceAddress3, sendingAddress);
-    assertEquals(msg3, new String(receiveBuffer.array(), 0, receiveBuffer.position()));
-
-    sendingChannel.close();
-    receivingChannel.close();
-  }
-
-  public void test_joinSourceSpecific_nullGroupAddress() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    try {
-      dc.join(null, ipv4networkInterface, UNICAST_IPv4_1);
-      fail();
-    } catch (NullPointerException expected) {
-    }
-    dc.close();
-  }
-
-  public void test_joinSourceSpecific_afterClose() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    dc.close();
-    try {
-      dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface, UNICAST_IPv4_1);
-      fail();
-    } catch (ClosedChannelException expected) {
-    }
-  }
-
-  public void test_joinSourceSpecific_nullNetworkInterface() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    try {
-      dc.join(GOOD_MULTICAST_IPv4, null, UNICAST_IPv4_1);
-      fail();
-    } catch (NullPointerException expected) {
-    }
-    dc.close();
-  }
-
-  public void test_joinSourceSpecific_nonMulticastGroupAddress_IPv4() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    try {
-      dc.join(UNICAST_IPv4_1, ipv4networkInterface, UNICAST_IPv4_1);
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-    dc.close();
-  }
-
-  public void test_joinSourceSpecific_nonMulticastGroupAddress_IPv6() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    try {
-      dc.join(UNICAST_IPv6_1, ipv6networkInterface, UNICAST_IPv6_1);
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-    dc.close();
-  }
-
-  public void test_joinSourceSpecific_nullSourceAddress_IPv4() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    try {
-      dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface, null);
-      fail();
-    } catch (NullPointerException expected) {
-    }
-    dc.close();
-  }
-
-  public void test_joinSourceSpecific_nullSourceAddress_IPv6() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    try {
-      dc.join(GOOD_MULTICAST_IPv6, ipv6networkInterface, null);
-      fail();
-    } catch (NullPointerException expected) {
-    }
-    dc.close();
-  }
-
-  public void test_joinSourceSpecific_mixedAddressTypes() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    try {
-      dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface, UNICAST_IPv6_1);
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-    try {
-      dc.join(GOOD_MULTICAST_IPv6, ipv6networkInterface, UNICAST_IPv4_1);
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-    dc.close();
-  }
-
-  public void test_joinSourceSpecific_nonUnicastSourceAddress_IPv4() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    try {
-      dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface, BAD_MULTICAST_IPv4);
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-    dc.close();
-  }
-
-  public void test_joinSourceSpecific_nonUnicastSourceAddress_IPv6() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    try {
-      dc.join(GOOD_MULTICAST_IPv6, ipv6networkInterface, BAD_MULTICAST_IPv6);
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-    dc.close();
-  }
-
-  public void test_joinSourceSpecific_multipleSourceAddressLimit() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    for (byte i = 1; i <= 20; i++) {
-      InetAddress sourceAddress = Inet4Address.getByAddress(new byte[] { 10, 0, 0, i});
-      try {
-        dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface, sourceAddress);
-      } catch (SocketException e) {
-        // There is a limit, that's ok according to the RI docs. For this test a lower bound of 10
-        // is used, which appears to be the default linux limit. See /proc/sys/net/ipv4/igmp_max_msf
-        assertTrue(i > 10);
-        break;
-      }
-    }
-
-    dc.close();
-  }
-
-  /**
-   * Checks that a source-specific join() works when the receiver is bound to the multicast group
-   * address
-   */
-  public void test_joinSourceSpecific_groupBind_IPv4() throws Exception {
-    for (NetworkInterface networkInterface : ipv4networkInterfaces) {
-      InetAddress ipv4LocalAddress = getLocalIpv4Address(networkInterface);
-      test_joinSourceSpecific(
-          networkInterface,
-          ipv4LocalAddress /* senderBindAddress */,
-          GOOD_MULTICAST_IPv4 /* receiverBindAddress */,
-          GOOD_MULTICAST_IPv4 /* groupAddress */,
-          UNICAST_IPv4_1 /* badSenderAddress */);
-    }
-  }
-
-  /**
-   * Checks that a source-specific join() works when the receiver is bound to the multicast group
-   * address
-   */
-  public void test_joinSourceSpecific_groupBind_IPv6() throws Exception {
-    for (NetworkInterface networkInterface : ipv6networkInterfaces) {
-      InetAddress ipv6LocalAddress = getLocalIpv6Address(networkInterface);
-      test_joinSourceSpecific(
-          networkInterface,
-          ipv6LocalAddress /* senderBindAddress */,
-          GOOD_MULTICAST_IPv6 /* receiverBindAddress */,
-          GOOD_MULTICAST_IPv6 /* groupAddress */,
-          UNICAST_IPv6_1 /* badSenderAddress */);
-    }
-  }
-
-  /** Checks that a source-specific join() works when the receiver is bound to the "any" address */
-  public void test_joinSourceSpecific_anyBind_IPv4() throws Exception {
-    for (NetworkInterface networkInterface : ipv4networkInterfaces) {
-      InetAddress ipv4LocalAddress = getLocalIpv4Address(networkInterface);
-      test_joinSourceSpecific(
-          networkInterface,
-          ipv4LocalAddress /* senderBindAddress */,
-          WILDCARD_IPv4 /* receiverBindAddress */,
-          GOOD_MULTICAST_IPv4 /* groupAddress */,
-          UNICAST_IPv4_1 /* badSenderAddress */);
-    }
-  }
-
-  /** Checks that a source-specific join() works when the receiver is bound to the "any" address */
-  public void test_joinSourceSpecific_anyBind_IPv6() throws Exception {
-    for (NetworkInterface networkInterface : ipv6networkInterfaces) {
-      InetAddress ipv6LocalAddress = getLocalIpv6Address(networkInterface);
-      test_joinSourceSpecific(
-          networkInterface,
-          ipv6LocalAddress /* senderBindAddress */,
-          WILDCARD_IPv6 /* receiverBindAddress */,
-          GOOD_MULTICAST_IPv6 /* groupAddress */,
-          UNICAST_IPv6_1 /* badSenderAddress */);
-    }
-  }
-
-  /**
-   * Checks that the source-specific membership is correctly source-filtered.
-   *
-   * @param networkInterface the network interface to use when joining
-   * @param senderBindAddress the address to bind the sender socket to
-   * @param receiverBindAddress the address to bind the receiver socket to
-   * @param groupAddress the group address to join
-   * @param badSenderAddress a unicast address to join to perform a negative test
-   */
-  private void test_joinSourceSpecific(
-      NetworkInterface networkInterface, InetAddress senderBindAddress,
-      InetAddress receiverBindAddress, InetAddress groupAddress, InetAddress badSenderAddress)
-      throws Exception {
-    DatagramChannel sendingChannel = DatagramChannel.open();
-    // In order to be source-specific the sender's address must be known. The sendingChannel is
-    // explicitly bound to a known, non-loopback address.
-    sendingChannel.bind(new InetSocketAddress(senderBindAddress, 0));
-    InetSocketAddress sendingAddress = (InetSocketAddress) sendingChannel.getLocalAddress();
-
-    DatagramChannel receivingChannel = DatagramChannel.open();
-    configureChannelForReceiving(receivingChannel);
-    receivingChannel.bind(
-        new InetSocketAddress(receiverBindAddress, 0) /* local port left to the OS to determine */);
-
-    InetSocketAddress localReceivingAddress =
-        (InetSocketAddress) receivingChannel.getLocalAddress();
-    InetSocketAddress groupSocketAddress =
-        new InetSocketAddress(groupAddress, localReceivingAddress.getPort());
-    MembershipKey membershipKey1 = receivingChannel
-        .join(groupSocketAddress.getAddress(), networkInterface, senderBindAddress);
-
-    ByteBuffer receiveBuffer = ByteBuffer.allocate(10);
-
-    // Send a message. It should be received.
-    String msg1 = "Hello1";
-    sendMessage(sendingChannel, msg1, groupSocketAddress);
-    InetSocketAddress sourceAddress1 = (InetSocketAddress) receivingChannel.receive(receiveBuffer);
-    assertEquals(sourceAddress1, sendingAddress);
-    assertEquals(msg1, new String(receiveBuffer.array(), 0, receiveBuffer.position()));
-
-    membershipKey1.drop();
-
-    receivingChannel.join(groupSocketAddress.getAddress(), networkInterface, badSenderAddress);
-
-    // Send a message. It should not be received.
-    String msg2 = "Hello2";
-    sendMessage(sendingChannel, msg2, groupSocketAddress);
-    InetSocketAddress sourceAddress2 = (InetSocketAddress) receivingChannel.receive(receiveBuffer);
-    assertNull(sourceAddress2);
-
-    receivingChannel.close();
-    sendingChannel.close();
-  }
-
-  public void test_dropSourceSpecific_twice_IPv4() throws Exception {
-    for (NetworkInterface networkInterface : ipv4networkInterfaces) {
-      test_dropSourceSpecific_twice(
-          networkInterface,
-          GOOD_MULTICAST_IPv4 /* groupAddress */,
-          UNICAST_IPv4_1 /* sourceAddress */);
-    }
-  }
-
-  public void test_dropSourceSpecific_twice_IPv6() throws Exception {
-    for (NetworkInterface networkInterface : ipv6networkInterfaces) {
-      test_dropSourceSpecific_twice(
-          networkInterface,
-          GOOD_MULTICAST_IPv6 /* groupAddress */,
-          UNICAST_IPv6_1 /* sourceAddress */);
-    }
-  }
-
-  private void test_dropSourceSpecific_twice(
-      NetworkInterface networkInterface, InetAddress groupAddress, InetAddress sourceAddress)
-      throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(groupAddress, networkInterface, sourceAddress);
-
-    assertTrue(membershipKey.isValid());
-    membershipKey.drop();
-    assertFalse(membershipKey.isValid());
-
-    // Try to leave a group we are no longer a member of. It should do nothing.
-    membershipKey.drop();
-
-    dc.close();
-  }
-
-  public void test_dropSourceSpecific_sourceKeysAreIndependent_IPv4() throws Exception {
-    for (NetworkInterface networkInterface : ipv4networkInterfaces) {
-      test_dropSourceSpecific_sourceKeysAreIndependent(
-          networkInterface,
-          GOOD_MULTICAST_IPv4 /* groupAddress */,
-          UNICAST_IPv4_1 /* sourceAddress1 */,
-          UNICAST_IPv4_2 /* sourceAddress2 */);
-    }
-  }
-
-  public void test_dropSourceSpecific_sourceKeysAreIndependent_IPv6() throws Exception {
-    for (NetworkInterface networkInterface : ipv6networkInterfaces) {
-      test_dropSourceSpecific_sourceKeysAreIndependent(
-          networkInterface,
-          GOOD_MULTICAST_IPv6 /* groupAddress */,
-          UNICAST_IPv6_1 /* sourceAddress1 */,
-          UNICAST_IPv6_2 /* sourceAddress2 */);
-    }
-  }
-
-  private void test_dropSourceSpecific_sourceKeysAreIndependent(
-      NetworkInterface networkInterface, InetAddress groupAddress, InetAddress sourceAddress1,
-      InetAddress sourceAddress2)
-      throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey1 = dc.join(groupAddress, networkInterface, sourceAddress1);
-    MembershipKey membershipKey2 = dc.join(groupAddress, networkInterface, sourceAddress2);
-    assertFalse(membershipKey1.equals(membershipKey2));
-    assertTrue(membershipKey1.isValid());
-    assertTrue(membershipKey2.isValid());
-
-    membershipKey1.drop();
-
-    assertFalse(membershipKey1.isValid());
-    assertTrue(membershipKey2.isValid());
-
-    dc.close();
-  }
-
-  public void test_drop_keyBehaviorAfterDrop() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey =
-        dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface, UNICAST_IPv4_1);
-    membershipKey.drop();
-    assertFalse(membershipKey.isValid());
-
-    try {
-      membershipKey.block(UNICAST_IPv4_1);
-    } catch (IllegalStateException expected) {
-    }
-
-    try {
-      membershipKey.unblock(UNICAST_IPv4_1);
-    } catch (IllegalStateException expected) {
-    }
-
-    assertSame(dc, membershipKey.channel());
-    assertSame(GOOD_MULTICAST_IPv4, membershipKey.group());
-    assertSame(UNICAST_IPv4_1, membershipKey.sourceAddress());
-    assertSame(ipv4networkInterface, membershipKey.networkInterface());
-  }
-
-  private static DatagramChannel createReceiverChannel() throws Exception {
-    DatagramChannel dc = DatagramChannel.open();
-    configureChannelForReceiving(dc);
-    dc.bind(null /* leave the OS to determine the port, and use the wildcard address */);
-    return dc;
-  }
-
-  private static void configureChannelForReceiving(DatagramChannel receivingChannel)
-      throws Exception {
-
-    // NOTE: At the time of writing setSoTimeout() has no effect in the RI, making these tests hang
-    // if the channel is in blocking mode.
-    receivingChannel.socket().setSoTimeout(200);
-    receivingChannel.configureBlocking(true);
-    // configureBlocking(false) can be used instead in the RI and we rely on the network to the
-    // local host being instantaneous.
-    // receivingChannel.configureBlocking(false);
-  }
-
-  private static boolean willWorkForMulticast(NetworkInterface iface) throws IOException {
-    return iface.isUp()
-        // Typically loopback interfaces do not support multicast, but they are ruled out
-        // explicitly here anyway.
-        && !iface.isLoopback() && iface.supportsMulticast()
-        && iface.getInetAddresses().hasMoreElements();
-  }
-
-  private static void sendMessage(
-      InetAddress targetGroup, int targetPort, String msg, NetworkInterface sendingInterface)
-      throws IOException {
-    // Any datagram socket can send to a group. It does not need to have joined the group.
-    DatagramChannel dc = DatagramChannel.open();
-    dc.setOption(StandardSocketOptions.IP_MULTICAST_IF, sendingInterface);
-    sendMessage(dc, msg, new InetSocketAddress(targetGroup, targetPort));
-    dc.close();
-  }
-
-  private static void sendMessage(
-      DatagramChannel sendingChannel, String msg, InetSocketAddress targetAddress)
-      throws IOException {
-
-    ByteBuffer sendBuffer = ByteBuffer.wrap(msg.getBytes());
-    sendingChannel.send(sendBuffer, targetAddress);
-  }
-
-  private static InetAddress getLocalIpv4Address(NetworkInterface networkInterface) {
-    for (InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) {
-      if (interfaceAddress.getAddress() instanceof Inet4Address) {
-        return interfaceAddress.getAddress();
-      }
-    }
-    throw new AssertionFailedError("Unable to find local IPv4 address for " + networkInterface);
-  }
-
-  private static InetAddress getLocalIpv6Address(NetworkInterface networkInterface) {
-    for (InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) {
-      if (interfaceAddress.getAddress() instanceof Inet6Address) {
-        return interfaceAddress.getAddress();
-      }
-    }
-    throw new AssertionFailedError("Unable to find local IPv6 address for " + networkInterface);
-  }
-
-}
diff --git a/luni/src/test/java/libcore/java/nio/channels/DatagramChannelTest.java b/luni/src/test/java/libcore/java/nio/channels/DatagramChannelTest.java
index cd4bb22..efcfece 100644
--- a/luni/src/test/java/libcore/java/nio/channels/DatagramChannelTest.java
+++ b/luni/src/test/java/libcore/java/nio/channels/DatagramChannelTest.java
@@ -23,9 +23,6 @@
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.net.SocketOption;
-import java.net.StandardSocketOptions;
 import java.nio.ByteBuffer;
 import java.nio.channels.ClosedChannelException;
 import java.nio.channels.DatagramChannel;
@@ -61,7 +58,7 @@
         DatagramChannel dc = DatagramChannel.open();
         try {
             dc.configureBlocking(false);
-            dc.bind(null);
+            dc.socket().bind(null);
             // Should return immediately, since we're non-blocking.
             assertNull(dc.receive(ByteBuffer.allocate(2048)));
         } finally {
@@ -72,8 +69,6 @@
     public void testInitialState() throws Exception {
         DatagramChannel dc = DatagramChannel.open();
         try {
-            assertNull(dc.getLocalAddress());
-
             DatagramSocket socket = dc.socket();
             assertFalse(socket.isBound());
             assertFalse(socket.getBroadcast());
@@ -93,408 +88,20 @@
         }
     }
 
-    public void test_supportedOptions() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-        Set<SocketOption<?>> options = dc.supportedOptions();
-
-        // Probe some values. This is not intended to be complete.
-        assertTrue(options.contains(StandardSocketOptions.SO_REUSEADDR));
-        assertFalse(options.contains(StandardSocketOptions.TCP_NODELAY));
-    }
-
-    public void test_getOption_unsupportedOption() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-        try {
-            dc.getOption(StandardSocketOptions.TCP_NODELAY);
-            fail();
-        } catch (UnsupportedOperationException expected) {}
-
-        dc.close();
-    }
-
-    public void test_getOption_afterClose() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-        dc.close();
-
-        try {
-            dc.getOption(StandardSocketOptions.SO_RCVBUF);
-            fail();
-        } catch (ClosedChannelException expected) {}
-    }
-
-    public void test_setOption_afterClose() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-        dc.close();
-
-        try {
-            dc.setOption(StandardSocketOptions.SO_RCVBUF, 1234);
-            fail();
-        } catch (ClosedChannelException expected) {}
-    }
-
-    public void test_getOption_SO_RCVBUF_defaults() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-
-        int value = dc.getOption(StandardSocketOptions.SO_RCVBUF);
-        assertTrue(value > 0);
-        assertEquals(value, dc.socket().getReceiveBufferSize());
-
-        dc.close();
-    }
-
-    public void test_setOption_SO_RCVBUF_afterOpen() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-
-        trySetReceiveBufferSizeOption(dc);
-
-        dc.close();
-    }
-
-    private static void trySetReceiveBufferSizeOption(DatagramChannel dc) throws IOException {
-        int initialValue = dc.getOption(StandardSocketOptions.SO_RCVBUF);
-        try {
-            dc.setOption(StandardSocketOptions.SO_RCVBUF, -1);
-            fail();
-        } catch (IllegalArgumentException expected) {}
-        int actualValue = dc.getOption(StandardSocketOptions.SO_RCVBUF);
-        assertEquals(initialValue, actualValue);
-        assertEquals(initialValue, dc.socket().getReceiveBufferSize());
-
-        int newBufferSize = initialValue - 1;
-        dc.setOption(StandardSocketOptions.SO_RCVBUF, newBufferSize);
-        actualValue = dc.getOption(StandardSocketOptions.SO_RCVBUF);
-        // The Linux Kernel actually doubles the value it is given and may choose to ignore it.
-        // This assertion may be brittle.
-        assertTrue(actualValue != initialValue);
-        assertEquals(actualValue, dc.socket().getReceiveBufferSize());
-    }
-
-    public void test_getOption_SO_SNDBUF_defaults() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-
-        int value = dc.getOption(StandardSocketOptions.SO_SNDBUF);
-        assertTrue(value > 0);
-        assertEquals(value, dc.socket().getSendBufferSize());
-
-        dc.close();
-    }
-
-    public void test_setOption_SO_SNDBUF_afterOpen() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-
-        trySetSendBufferSizeOption(dc);
-
-        dc.close();
-    }
-
-    private static void trySetSendBufferSizeOption(DatagramChannel dc) throws IOException {
-        int initialValue = dc.getOption(StandardSocketOptions.SO_SNDBUF);
-        try {
-            dc.setOption(StandardSocketOptions.SO_SNDBUF, -1);
-            fail();
-        } catch (IllegalArgumentException expected) {}
-        int actualValue = dc.getOption(StandardSocketOptions.SO_SNDBUF);
-        assertEquals(initialValue, actualValue);
-        assertEquals(initialValue, dc.socket().getSendBufferSize());
-
-        int newBufferSize = initialValue - 1;
-        dc.setOption(StandardSocketOptions.SO_SNDBUF, newBufferSize);
-        actualValue = dc.getOption(StandardSocketOptions.SO_SNDBUF);
-        // The Linux Kernel actually doubles the value it is given and may choose to ignore it.
-        // This assertion may be brittle.
-        assertTrue(actualValue != initialValue);
-        assertEquals(actualValue, dc.socket().getSendBufferSize());
-    }
-
-    public void test_getOption_IP_MULTICAST_IF_defaults() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-
-        NetworkInterface networkInterface = dc.getOption(StandardSocketOptions.IP_MULTICAST_IF);
-        assertNull(networkInterface);
-
-        dc.close();
-    }
-
-    public void test_getOption_IP_MULTICAST_IF_nullCheck() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-        try {
-            dc.setOption(StandardSocketOptions.IP_MULTICAST_IF, null);
-            fail();
-        } catch (IllegalArgumentException expected) {}
-
-        dc.close();
-    }
-
-    public void test_setOption_IP_MULTICAST_IF_afterOpen() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-
-        Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
-        assertTrue(networkInterfaces.hasMoreElements());
-        while (networkInterfaces.hasMoreElements()) {
-            trySetNetworkInterfaceOption(dc, networkInterfaces.nextElement());
-        }
-
-        dc.close();
-    }
-
-    public void test_setOption_IP_MULTICAST_IF_afterBind() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-        dc.bind(new InetSocketAddress(Inet4Address.getLoopbackAddress(), 0));
-
-        Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
-        assertTrue(networkInterfaces.hasMoreElements());
-        while (networkInterfaces.hasMoreElements()) {
-            trySetNetworkInterfaceOption(dc, networkInterfaces.nextElement());
-        }
-
-        dc.close();
-    }
-
-    private static void trySetNetworkInterfaceOption(
-            DatagramChannel dc, NetworkInterface networkInterface) throws IOException {
-
-        NetworkInterface initialValue = dc.getOption(StandardSocketOptions.IP_MULTICAST_IF);
-        try {
-            dc.setOption(StandardSocketOptions.IP_MULTICAST_IF, null);
-            fail();
-        } catch (IllegalArgumentException expected) {}
-        assertEquals(initialValue, dc.getOption(StandardSocketOptions.IP_MULTICAST_IF));
-
-        dc.setOption(StandardSocketOptions.IP_MULTICAST_IF, networkInterface);
-        NetworkInterface actualValue =
-                dc.getOption(StandardSocketOptions.IP_MULTICAST_IF);
-        assertEquals(networkInterface, actualValue);
-    }
-
-    public void test_getOption_IP_MULTICAST_LOOP_defaults() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-
-        assertTrue(dc.getOption(StandardSocketOptions.IP_MULTICAST_LOOP));
-
-        dc.close();
-    }
-
-    public void test_getOption_IP_MULTICAST_LOOP_nullCheck() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-        try {
-            dc.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, null);
-            fail();
-        } catch (IllegalArgumentException expected) {}
-
-        dc.close();
-    }
-
-    public void test_setOption_IP_MULTICAST_LOOP_afterOpen() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-        assertTrue(dc.getOption(StandardSocketOptions.IP_MULTICAST_LOOP));
-
-        dc.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, false);
-        assertFalse(dc.getOption(StandardSocketOptions.IP_MULTICAST_LOOP));
-
-        dc.close();
-    }
-
-    public void test_setOption_IP_MULTICAST_LOOP_afterBind() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-        dc.bind(new InetSocketAddress(Inet4Address.getLoopbackAddress(), 0));
-
-        assertTrue(dc.getOption(StandardSocketOptions.IP_MULTICAST_LOOP));
-
-        dc.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, false);
-        assertFalse(dc.getOption(StandardSocketOptions.IP_MULTICAST_LOOP));
-
-        dc.close();
-    }
-
-    public void test_getOption_IP_MULTICAST_TTL_defaults() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-
-        int value = dc.getOption(StandardSocketOptions.IP_MULTICAST_TTL);
-        assertEquals(1, value);
-
-        dc.close();
-    }
-
-    public void test_setOption_IP_MULTICAST_TTL_afterOpen() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-
-        trySetMulticastTtlOption(dc);
-
-        dc.close();
-    }
-
-    private static void trySetMulticastTtlOption(DatagramChannel dc) throws IOException {
-        int initialValue = dc.getOption(StandardSocketOptions.IP_MULTICAST_TTL);
-        try {
-            dc.setOption(StandardSocketOptions.IP_MULTICAST_TTL, -1);
-            fail();
-        } catch (IllegalArgumentException expected) {}
-        int actualValue = dc.getOption(StandardSocketOptions.IP_MULTICAST_TTL);
-        assertEquals(initialValue, actualValue);
-
-        int newTtl = initialValue + 1;
-        dc.setOption(StandardSocketOptions.IP_MULTICAST_TTL, newTtl);
-        actualValue = dc.getOption(StandardSocketOptions.IP_MULTICAST_TTL);
-        assertEquals(newTtl, actualValue);
-    }
-
-    public void test_setOption_IP_MULTICAST_TTL_afterBind() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-        dc.bind(null);
-
-        trySetMulticastTtlOption(dc);
-
-        dc.close();
-    }
-
-    public void test_getOption_SO_BROADCAST_defaults() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-
-        assertFalse(dc.getOption(StandardSocketOptions.SO_BROADCAST));
-
-        dc.close();
-    }
-
-    public void test_setOption_SO_BROADCAST_afterOpen() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-
-        trySetSoBroadcastOption(dc);
-
-        dc.close();
-    }
-
-    private static void trySetSoBroadcastOption(DatagramChannel dc) throws IOException {
-        boolean initialValue = dc.getOption(StandardSocketOptions.SO_BROADCAST);
-
-        dc.setOption(StandardSocketOptions.SO_BROADCAST, !initialValue);
-        boolean actualValue = dc.getOption(StandardSocketOptions.SO_BROADCAST);
-        assertEquals(!initialValue, actualValue);
-    }
-
-    public void test_setOption_SO_BROADCAST_afterBind() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-        dc.bind(null);
-
-        trySetSoBroadcastOption(dc);
-
-        dc.close();
-    }
-
-    public void test_getOption_IP_TOS_defaults() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-
-        int value = dc.getOption(StandardSocketOptions.IP_TOS);
-        assertEquals(0, value);
-        assertEquals(value, dc.socket().getTrafficClass());
-
-        dc.close();
-    }
-
-    public void test_setOption_IP_TOS_afterOpen() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-
-        trySetTosOption(dc);
-
-        dc.close();
-    }
-
-    private static void trySetTosOption(DatagramChannel dc) throws IOException {
-        int initialValue = dc.getOption(StandardSocketOptions.IP_TOS);
-        try {
-            dc.setOption(StandardSocketOptions.IP_TOS, -1);
-            fail();
-        } catch (IllegalArgumentException expected) {}
-        assertEquals(initialValue, (int) dc.getOption(StandardSocketOptions.IP_TOS));
-        assertEquals(initialValue, dc.socket().getTrafficClass());
-
-        try {
-            dc.setOption(StandardSocketOptions.IP_TOS, 256);
-            fail();
-        } catch (IllegalArgumentException expected) {}
-        assertEquals(initialValue, (int) dc.getOption(StandardSocketOptions.IP_TOS));
-        assertEquals(initialValue, dc.socket().getTrafficClass());
-
-        int newValue = (initialValue + 1) % 255;
-        dc.setOption(StandardSocketOptions.IP_TOS, newValue);
-        assertEquals(newValue, (int) dc.getOption(StandardSocketOptions.IP_TOS));
-        assertEquals(newValue, dc.socket().getTrafficClass());
-    }
-
-    public void test_setOption_IP_TOS_afterBind() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-        dc.bind(null);
-
-        trySetTosOption(dc);
-
-        dc.close();
-    }
-
-    public void test_getOption_SO_REUSEADDR_defaults() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-
-        boolean value = dc.getOption(StandardSocketOptions.SO_REUSEADDR);
-        assertFalse(value);
-        assertFalse(dc.socket().getReuseAddress());
-
-        dc.close();
-    }
-
-    public void test_setOption_SO_REUSEADDR_afterOpen() throws Exception {
-        DatagramChannel dc = DatagramChannel.open();
-
-        boolean initialValue = dc.getOption(StandardSocketOptions.SO_REUSEADDR);
-        dc.setOption(StandardSocketOptions.SO_REUSEADDR, !initialValue);
-        assertEquals(!initialValue, (boolean) dc.getOption(StandardSocketOptions.SO_REUSEADDR));
-        assertEquals(!initialValue, dc.socket().getReuseAddress());
-
-        dc.close();
-    }
-
     public void test_bind_unresolvedAddress() throws IOException {
         DatagramChannel dc = DatagramChannel.open();
         try {
-            dc.bind(new InetSocketAddress("unresolvedname", 31415));
+            dc.socket().bind(new InetSocketAddress("unresolvedname", 31415));
             fail();
-        } catch (UnresolvedAddressException expected) {
+        } catch (IOException expected) {
         }
 
-        assertNull(dc.getLocalAddress());
         assertTrue(dc.isOpen());
         assertFalse(dc.isConnected());
 
         dc.close();
     }
 
-    public void test_bind_noReuseAddress() throws Exception {
-        DatagramChannel dc1 = DatagramChannel.open();
-        dc1.setOption(StandardSocketOptions.SO_REUSEADDR, false);
-        DatagramChannel dc2 = DatagramChannel.open();
-        dc1.setOption(StandardSocketOptions.SO_REUSEADDR, false);
-
-        dc1.bind(null);
-
-        try {
-            dc2.bind(dc1.getLocalAddress());
-            fail();
-        } catch (IOException expected) {}
-
-        dc1.close();
-        dc2.close();
-    }
-
-    public void test_bind_withReuseAddress() throws Exception {
-        DatagramChannel dc1 = DatagramChannel.open();
-        dc1.setOption(StandardSocketOptions.SO_REUSEADDR, true);
-        DatagramChannel dc2 = DatagramChannel.open();
-        dc2.setOption(StandardSocketOptions.SO_REUSEADDR, true);
-
-        dc1.bind(null);
-        dc2.bind(dc1.getLocalAddress());
-
-        dc1.close();
-        dc2.close();
-    }
-
     public void test_bind_any_IPv4() throws Exception {
         test_bind_any(InetAddress.getByName("0.0.0.0"));
     }
@@ -505,12 +112,12 @@
 
     private void test_bind_any(InetAddress bindAddress) throws Exception {
         DatagramChannel dc = DatagramChannel.open();
-        dc.bind(new InetSocketAddress(bindAddress, 0));
+        dc.socket().bind(new InetSocketAddress(bindAddress, 0));
 
         assertTrue(dc.isOpen());
         assertFalse(dc.isConnected());
 
-        InetSocketAddress actualAddress = (InetSocketAddress) dc.getLocalAddress();
+        InetSocketAddress actualAddress = (InetSocketAddress) dc.socket().getLocalSocketAddress();
         assertTrue(actualAddress.getAddress().isAnyLocalAddress());
         assertTrue(actualAddress.getPort() > 0);
 
@@ -537,18 +144,16 @@
 
     private void test_bind(InetAddress bindAddress) throws IOException {
         DatagramChannel dc = DatagramChannel.open();
-        dc.bind(new InetSocketAddress(bindAddress, 0));
+        dc.socket().bind(new InetSocketAddress(bindAddress, 0));
 
-        InetSocketAddress actualAddress = (InetSocketAddress) dc.getLocalAddress();
+        InetSocketAddress actualAddress = (InetSocketAddress) dc.socket().getLocalSocketAddress();
         assertEquals(bindAddress, actualAddress.getAddress());
         assertTrue(actualAddress.getPort() > 0);
 
         dc.close();
     }
 
-    private static InetAddress getNonLoopbackNetworkInterfaceAddress(boolean ipv4)
-            throws SocketException {
-
+    private static InetAddress getNonLoopbackNetworkInterfaceAddress(boolean ipv4) throws IOException {
         Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
         while (networkInterfaces.hasMoreElements()) {
             NetworkInterface networkInterface = networkInterfaces.nextElement();
diff --git a/luni/src/test/java/libcore/java/nio/channels/ServerSocketChannelTest.java b/luni/src/test/java/libcore/java/nio/channels/ServerSocketChannelTest.java
index e819d82..1178b70 100644
--- a/luni/src/test/java/libcore/java/nio/channels/ServerSocketChannelTest.java
+++ b/luni/src/test/java/libcore/java/nio/channels/ServerSocketChannelTest.java
@@ -21,8 +21,7 @@
 import java.net.InetSocketAddress;
 import java.net.NetworkInterface;
 import java.net.ServerSocket;
-import java.net.SocketOption;
-import java.net.StandardSocketOptions;
+import java.net.SocketException;
 import java.nio.channels.ClosedChannelException;
 import java.nio.channels.ServerSocketChannel;
 import java.nio.channels.SocketChannel;
@@ -36,7 +35,7 @@
         ServerSocketChannel ssc = ServerSocketChannel.open();
         try {
             ssc.configureBlocking(false);
-            ssc.bind(null);
+            ssc.socket().bind(null);
             // Should return immediately, since we're non-blocking.
             assertNull(ssc.accept());
         } finally {
@@ -48,7 +47,7 @@
     public void test_open_initialState() throws Exception {
         ServerSocketChannel ssc = ServerSocketChannel.open();
         try {
-            assertNull(ssc.getLocalAddress());
+            assertNull(ssc.socket().getLocalSocketAddress());
 
             ServerSocket socket = ssc.socket();
             assertFalse(socket.isBound());
@@ -67,12 +66,12 @@
     public void test_bind_unresolvedAddress() throws IOException {
         ServerSocketChannel ssc = ServerSocketChannel.open();
         try {
-            ssc.bind(new InetSocketAddress("unresolvedname", 31415));
+            ssc.socket().bind(new InetSocketAddress("unresolvedname", 31415));
             fail();
-        } catch (UnresolvedAddressException expected) {
+        } catch (SocketException expected) {
         }
 
-        assertNull(ssc.getLocalAddress());
+        assertNull(ssc.socket().getLocalSocketAddress());
         assertTrue(ssc.isOpen());
 
         ssc.close();
@@ -80,8 +79,8 @@
 
     public void test_bind_nullBindsToAll() throws Exception {
         ServerSocketChannel ssc = ServerSocketChannel.open();
-        ssc.bind(null);
-        InetSocketAddress boundAddress = (InetSocketAddress) ssc.getLocalAddress();
+        ssc.socket().bind(null);
+        InetSocketAddress boundAddress = (InetSocketAddress) ssc.socket().getLocalSocketAddress();
         assertTrue(boundAddress.getAddress().isAnyLocalAddress());
         assertFalse(boundAddress.getAddress().isLinkLocalAddress());
         assertFalse(boundAddress.getAddress().isLoopbackAddress());
@@ -106,8 +105,8 @@
 
     public void test_bind_loopback() throws Exception {
         ServerSocketChannel ssc = ServerSocketChannel.open();
-        ssc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
-        InetSocketAddress boundAddress = (InetSocketAddress) ssc.getLocalAddress();
+        ssc.socket().bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
+        InetSocketAddress boundAddress = (InetSocketAddress) ssc.socket().getLocalSocketAddress();
         assertFalse(boundAddress.getAddress().isAnyLocalAddress());
         assertFalse(boundAddress.getAddress().isLinkLocalAddress());
         assertTrue(boundAddress.getAddress().isLoopbackAddress());
@@ -146,102 +145,4 @@
             return false;
         }
     }
-
-    public void test_supportedOptions() throws Exception {
-        ServerSocketChannel ssc = ServerSocketChannel.open();
-        Set<SocketOption<?>> options = ssc.supportedOptions();
-
-        // Probe some values. This is not intended to be complete.
-        assertTrue(options.contains(StandardSocketOptions.SO_REUSEADDR));
-        assertFalse(options.contains(StandardSocketOptions.IP_MULTICAST_TTL));
-    }
-
-    public void test_getOption_unsupportedOption() throws Exception {
-        ServerSocketChannel ssc = ServerSocketChannel.open();
-        try {
-            ssc.getOption(StandardSocketOptions.IP_MULTICAST_TTL);
-            fail();
-        } catch (UnsupportedOperationException expected) {}
-
-        ssc.close();
-    }
-
-    public void test_getOption_afterClose() throws Exception {
-        ServerSocketChannel ssc = ServerSocketChannel.open();
-        ssc.close();
-
-        try {
-            ssc.getOption(StandardSocketOptions.SO_RCVBUF);
-            fail();
-        } catch (ClosedChannelException expected) {}
-    }
-
-    public void test_setOption_afterClose() throws Exception {
-        ServerSocketChannel ssc = ServerSocketChannel.open();
-        ssc.close();
-
-        try {
-            ssc.setOption(StandardSocketOptions.SO_RCVBUF, 1234);
-            fail();
-        } catch (ClosedChannelException expected) {}
-    }
-
-    public void test_getOption_SO_RCVBUF_defaults() throws Exception {
-        ServerSocketChannel ssc = ServerSocketChannel.open();
-
-        int value = ssc.getOption(StandardSocketOptions.SO_RCVBUF);
-        assertTrue(value > 0);
-        assertEquals(value, ssc.socket().getReceiveBufferSize());
-
-        ssc.close();
-    }
-
-    public void test_setOption_SO_RCVBUF_afterOpen() throws Exception {
-        ServerSocketChannel ssc = ServerSocketChannel.open();
-
-        trySetReceiveBufferSizeOption(ssc);
-
-        ssc.close();
-    }
-
-    private static void trySetReceiveBufferSizeOption(ServerSocketChannel ssc) throws IOException {
-        int initialValue = ssc.getOption(StandardSocketOptions.SO_RCVBUF);
-        try {
-            ssc.setOption(StandardSocketOptions.SO_RCVBUF, -1);
-            fail();
-        } catch (IllegalArgumentException expected) {}
-        int actualValue = ssc.getOption(StandardSocketOptions.SO_RCVBUF);
-        assertEquals(initialValue, actualValue);
-        assertEquals(initialValue, ssc.socket().getReceiveBufferSize());
-
-        int newBufferSize = initialValue - 1;
-        ssc.setOption(StandardSocketOptions.SO_RCVBUF, newBufferSize);
-        actualValue = ssc.getOption(StandardSocketOptions.SO_RCVBUF);
-        // The Linux Kernel actually doubles the value it is given and may choose to ignore it.
-        // This assertion may be brittle.
-        assertTrue(actualValue != initialValue);
-        assertEquals(actualValue, ssc.socket().getReceiveBufferSize());
-    }
-
-    public void test_getOption_SO_REUSEADDR_defaults() throws Exception {
-        ServerSocketChannel ssc = ServerSocketChannel.open();
-
-        boolean value = ssc.getOption(StandardSocketOptions.SO_REUSEADDR);
-        assertTrue(value);
-        assertTrue(ssc.socket().getReuseAddress());
-
-        ssc.close();
-    }
-
-    public void test_setOption_SO_REUSEADDR_afterOpen() throws Exception {
-        ServerSocketChannel ssc = ServerSocketChannel.open();
-
-        boolean initialValue = ssc.getOption(StandardSocketOptions.SO_REUSEADDR);
-        ssc.setOption(StandardSocketOptions.SO_REUSEADDR, !initialValue);
-        assertEquals(!initialValue, (boolean) ssc.getOption(StandardSocketOptions.SO_REUSEADDR));
-        assertEquals(!initialValue, ssc.socket().getReuseAddress());
-
-        ssc.close();
-    }
-
 }
diff --git a/luni/src/test/java/libcore/java/nio/channels/SocketChannelTest.java b/luni/src/test/java/libcore/java/nio/channels/SocketChannelTest.java
index 6bba862..a54b30a 100644
--- a/luni/src/test/java/libcore/java/nio/channels/SocketChannelTest.java
+++ b/luni/src/test/java/libcore/java/nio/channels/SocketChannelTest.java
@@ -24,8 +24,6 @@
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.ServerSocket;
-import java.net.SocketOption;
-import java.net.StandardSocketOptions;
 import java.nio.ByteBuffer;
 import java.nio.channels.ClosedChannelException;
 import java.nio.channels.SocketChannel;
@@ -143,7 +141,7 @@
   public void test_open_initialState() throws Exception {
     SocketChannel sc = SocketChannel.open();
     try {
-      assertNull(sc.getLocalAddress());
+      assertNull(sc.socket().getLocalSocketAddress());
 
       Socket socket = sc.socket();
       assertFalse(socket.isBound());
@@ -166,12 +164,12 @@
   public void test_bind_unresolvedAddress() throws IOException {
     SocketChannel sc = SocketChannel.open();
     try {
-      sc.bind(new InetSocketAddress("unresolvedname", 31415));
+      sc.socket().bind(new InetSocketAddress("unresolvedname", 31415));
       fail();
-    } catch (UnresolvedAddressException expected) {
+    } catch (IOException expected) {
     }
 
-    assertNull(sc.getLocalAddress());
+    assertNull(sc.socket().getLocalSocketAddress());
     assertTrue(sc.isOpen());
     assertFalse(sc.isConnected());
 
@@ -181,16 +179,16 @@
   /** Checks that the SocketChannel and associated Socket agree on the socket state. */
   public void test_bind_socketStateSync() throws IOException {
     SocketChannel sc = SocketChannel.open();
-    assertNull(sc.getLocalAddress());
+    assertNull(sc.socket().getLocalSocketAddress());
 
     Socket socket = sc.socket();
     assertNull(socket.getLocalSocketAddress());
     assertFalse(socket.isBound());
 
     InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
-    sc.bind(bindAddr);
+    sc.socket().bind(bindAddr);
 
-    InetSocketAddress actualAddr = (InetSocketAddress) sc.getLocalAddress();
+    InetSocketAddress actualAddr = (InetSocketAddress) sc.socket().getLocalSocketAddress();
     assertEquals(actualAddr, socket.getLocalSocketAddress());
     assertEquals(bindAddr.getHostName(), actualAddr.getHostName());
     assertTrue(socket.isBound());
@@ -209,14 +207,14 @@
    */
   public void test_bind_socketObjectCreationAfterBind() throws IOException {
     SocketChannel sc = SocketChannel.open();
-    assertNull(sc.getLocalAddress());
+    assertNull(sc.socket().getLocalSocketAddress());
 
     InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
-    sc.bind(bindAddr);
+    sc.socket().bind(bindAddr);
 
     // Socket object creation after bind().
     Socket socket = sc.socket();
-    InetSocketAddress actualAddr = (InetSocketAddress) sc.getLocalAddress();
+    InetSocketAddress actualAddr = (InetSocketAddress) sc.socket().getLocalSocketAddress();
     assertEquals(actualAddr, socket.getLocalSocketAddress());
     assertEquals(bindAddr.getHostName(), actualAddr.getHostName());
     assertTrue(socket.isBound());
@@ -276,307 +274,4 @@
     ss.close();
     sc.close();
   }
-
-  public void test_supportedOptions() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-    Set<SocketOption<?>> options = sc.supportedOptions();
-
-    // Probe some values. This is not intended to be complete.
-    assertTrue(options.contains(StandardSocketOptions.SO_REUSEADDR));
-    assertFalse(options.contains(StandardSocketOptions.IP_MULTICAST_TTL));
-  }
-
-  public void test_getOption_unsupportedOption() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-    try {
-      sc.getOption(StandardSocketOptions.IP_MULTICAST_TTL);
-      fail();
-    } catch (UnsupportedOperationException expected) {
-    }
-
-    sc.close();
-  }
-
-  public void test_getOption_afterClose() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-    sc.close();
-
-    try {
-      sc.getOption(StandardSocketOptions.SO_RCVBUF);
-      fail();
-    } catch (ClosedChannelException expected) {
-    }
-  }
-
-  public void test_setOption_afterClose() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-    sc.close();
-
-    try {
-      sc.setOption(StandardSocketOptions.SO_RCVBUF, 1234);
-      fail();
-    } catch (ClosedChannelException expected) {
-    }
-  }
-
-  public void test_getOption_SO_RCVBUF_defaults() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-
-    int value = sc.getOption(StandardSocketOptions.SO_RCVBUF);
-    assertTrue(value > 0);
-    assertEquals(value, sc.socket().getReceiveBufferSize());
-
-    sc.close();
-  }
-
-  public void test_setOption_SO_RCVBUF_afterOpen() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-
-    trySetReceiveBufferSizeOption(sc);
-
-    sc.close();
-  }
-
-  private static void trySetReceiveBufferSizeOption(SocketChannel sc) throws IOException {
-    int initialValue = sc.getOption(StandardSocketOptions.SO_RCVBUF);
-    try {
-      sc.setOption(StandardSocketOptions.SO_RCVBUF, -1);
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-    int actualValue = sc.getOption(StandardSocketOptions.SO_RCVBUF);
-    assertEquals(initialValue, actualValue);
-    assertEquals(initialValue, sc.socket().getReceiveBufferSize());
-
-    int newBufferSize = initialValue - 1;
-    sc.setOption(StandardSocketOptions.SO_RCVBUF, newBufferSize);
-    actualValue = sc.getOption(StandardSocketOptions.SO_RCVBUF);
-    // The Linux Kernel actually doubles the value it is given and may choose to ignore it.
-    // This assertion may be brittle.
-    assertTrue(actualValue != initialValue);
-    assertEquals(actualValue, sc.socket().getReceiveBufferSize());
-  }
-
-  public void test_getOption_SO_SNDBUF_defaults() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-
-    int bufferSize = sc.getOption(StandardSocketOptions.SO_SNDBUF);
-    assertTrue(bufferSize > 0);
-    assertEquals(bufferSize, sc.socket().getSendBufferSize());
-
-    sc.close();
-  }
-
-  public void test_setOption_SO_SNDBUF_afterOpen() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-
-    trySetSendBufferSizeOption(sc);
-
-    sc.close();
-  }
-
-  private static void trySetSendBufferSizeOption(SocketChannel sc) throws IOException {
-    int initialValue = sc.getOption(StandardSocketOptions.SO_SNDBUF);
-    try {
-      sc.setOption(StandardSocketOptions.SO_SNDBUF, -1);
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-    int actualValue = sc.getOption(StandardSocketOptions.SO_SNDBUF);
-    assertEquals(initialValue, actualValue);
-    assertEquals(initialValue, sc.socket().getSendBufferSize());
-
-    int newValue = initialValue - 1;
-    sc.setOption(StandardSocketOptions.SO_SNDBUF, newValue);
-    actualValue = sc.getOption(StandardSocketOptions.SO_SNDBUF);
-    // The Linux Kernel actually doubles the value it is given and may choose to ignore it.
-    // This assertion may be brittle.
-    assertTrue(actualValue != initialValue);
-    assertEquals(actualValue, sc.socket().getSendBufferSize());
-  }
-
-  public void test_getOption_SO_KEEPALIVE_defaults() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-
-    assertFalse(sc.getOption(StandardSocketOptions.SO_KEEPALIVE));
-
-    sc.close();
-  }
-
-  public void test_setOption_SO_KEEPALIVE_afterOpen() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-
-    trySetSoKeepaliveOption(sc);
-
-    sc.close();
-  }
-
-  private static void trySetSoKeepaliveOption(SocketChannel sc) throws IOException {
-    boolean initialValue = sc.getOption(StandardSocketOptions.SO_KEEPALIVE);
-
-    sc.setOption(StandardSocketOptions.SO_KEEPALIVE, !initialValue);
-    boolean actualValue = sc.getOption(StandardSocketOptions.SO_KEEPALIVE);
-    assertEquals(!initialValue, actualValue);
-  }
-
-  public void test_setOption_SO_KEEPALIVE_afterBind() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-    sc.bind(null);
-
-    trySetSoKeepaliveOption(sc);
-
-    sc.close();
-  }
-
-  public void test_getOption_IP_TOS_defaults() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-
-    int value = sc.getOption(StandardSocketOptions.IP_TOS);
-    assertEquals(0, value);
-    assertEquals(value, sc.socket().getTrafficClass());
-
-    sc.close();
-  }
-
-  public void test_setOption_IP_TOS_afterOpen() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-
-    trySetTosOption(sc);
-
-    sc.close();
-  }
-
-  private static void trySetTosOption(SocketChannel sc) throws IOException {
-    int initialValue = sc.getOption(StandardSocketOptions.IP_TOS);
-    try {
-      sc.setOption(StandardSocketOptions.IP_TOS, -1);
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-    assertEquals(initialValue, (int) sc.getOption(StandardSocketOptions.IP_TOS));
-    assertEquals(initialValue, sc.socket().getTrafficClass());
-
-    try {
-      sc.setOption(StandardSocketOptions.IP_TOS, 256);
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-    assertEquals(initialValue, (int) sc.getOption(StandardSocketOptions.IP_TOS));
-    assertEquals(initialValue, sc.socket().getTrafficClass());
-
-    int newValue = (initialValue + 1) % 255;
-    sc.setOption(StandardSocketOptions.IP_TOS, newValue);
-    assertEquals(newValue, (int) sc.getOption(StandardSocketOptions.IP_TOS));
-    assertEquals(newValue, sc.socket().getTrafficClass());
-  }
-
-  public void test_setOption_IP_TOS_afterBind() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-    sc.bind(null);
-
-    trySetTosOption(sc);
-
-    sc.close();
-  }
-
-  public void test_getOption_SO_LINGER_defaults() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-
-    int value = sc.getOption(StandardSocketOptions.SO_LINGER);
-    assertTrue(value < 0);
-    assertEquals(value, sc.socket().getSoLinger());
-
-    sc.close();
-  }
-
-  public void test_setOption_SO_LINGER_afterOpen() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-
-    trySetLingerOption(sc);
-
-    sc.close();
-  }
-
-  private static void trySetLingerOption(SocketChannel sc) throws IOException {
-    int initialValue = sc.getOption(StandardSocketOptions.SO_LINGER);
-    // Any negative value disables the setting, -1 is used to report SO_LINGER being disabled.
-    sc.setOption(StandardSocketOptions.SO_LINGER, -2);
-    int soLingerDisabled = -1;
-    assertEquals(soLingerDisabled, (int) sc.getOption(StandardSocketOptions.SO_LINGER));
-    assertEquals(soLingerDisabled, sc.socket().getSoLinger());
-
-    sc.setOption(StandardSocketOptions.SO_LINGER, 65536);
-    assertEquals(65535, (int) sc.getOption(StandardSocketOptions.SO_LINGER));
-    assertEquals(65535, sc.socket().getSoLinger());
-
-    int newValue = (initialValue + 1) % 65535;
-    sc.setOption(StandardSocketOptions.SO_LINGER, newValue);
-    assertEquals(newValue, (int) sc.getOption(StandardSocketOptions.SO_LINGER));
-    assertEquals(newValue, sc.socket().getSoLinger());
-  }
-
-  public void test_setOption_SO_LINGER_afterBind() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-    sc.bind(null);
-
-    trySetLingerOption(sc);
-
-    sc.close();
-  }
-
-  public void test_getOption_SO_REUSEADDR_defaults() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-
-    boolean value = sc.getOption(StandardSocketOptions.SO_REUSEADDR);
-    assertFalse(value);
-    assertFalse(sc.socket().getReuseAddress());
-
-    sc.close();
-  }
-
-  public void test_setOption_SO_REUSEADDR_afterOpen() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-
-    boolean initialValue = sc.getOption(StandardSocketOptions.SO_REUSEADDR);
-    sc.setOption(StandardSocketOptions.SO_REUSEADDR, !initialValue);
-    assertEquals(!initialValue, (boolean) sc.getOption(StandardSocketOptions.SO_REUSEADDR));
-    assertEquals(!initialValue, sc.socket().getReuseAddress());
-
-    sc.close();
-  }
-
-  public void test_getOption_TCP_NODELAY_defaults() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-
-    boolean value = sc.getOption(StandardSocketOptions.TCP_NODELAY);
-    assertFalse(value);
-    assertFalse(sc.socket().getTcpNoDelay());
-
-    sc.close();
-  }
-
-  public void test_setOption_TCP_NODELAY_afterOpen() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-
-    trySetNoDelay(sc);
-
-    sc.close();
-  }
-
-  private static void trySetNoDelay(SocketChannel sc) throws IOException {
-    boolean initialValue = sc.getOption(StandardSocketOptions.TCP_NODELAY);
-    sc.setOption(StandardSocketOptions.TCP_NODELAY, !initialValue);
-    assertEquals(!initialValue, (boolean) sc.getOption(StandardSocketOptions.TCP_NODELAY));
-    assertEquals(!initialValue, sc.socket().getTcpNoDelay());
-  }
-
-  public void test_setOption_TCP_NODELAY_afterBind() throws Exception {
-    SocketChannel sc = SocketChannel.open();
-    sc.bind(null);
-
-    trySetNoDelay(sc);
-
-    sc.close();
-  }
-
 }
diff --git a/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java b/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java
index 09a18e2..e7fdb1f 100644
--- a/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java
+++ b/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java
@@ -47,6 +47,8 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import javax.crypto.interfaces.DHPrivateKey;
+import javax.crypto.interfaces.DHPublicKey;
 import javax.crypto.spec.DHParameterSpec;
 
 import junit.framework.TestCase;
@@ -126,12 +128,8 @@
 
             AlgorithmParameterSpec params = null;
 
-            // TODO: detect if we're running in vogar and run the full test
             if ("DH".equals(algorithm)) {
-                // Disabled because this takes too long on devices.
-                // TODO: Re-enable DH test. http://b/5513723.
-                // params = getDHParams();
-                continue;
+                params = getDHParams();
             }
 
             try {
@@ -218,6 +216,14 @@
         test_KeyPair(kpg, kpg.generateKeyPair());
 
         String algorithm = kpg.getAlgorithm();
+
+        // TODO: detect if we're running in vogar and run the full test
+        if ("DH".equals(algorithm)) {
+            // Disabled because this takes too long on devices.
+            // TODO: Re-enable DH test. http://b/5513723.
+            return;
+        }
+
         List<Integer> keySizes = getKeySizes(algorithm);
         for (int keySize : keySizes) {
             kpg.initialize(keySize);
@@ -263,6 +269,17 @@
             expectedAlgorithm = "DH";
         }
         assertEquals(expectedAlgorithm, k.getAlgorithm().toUpperCase());
+        if (expectedAlgorithm.equals("DH")) {
+            if (k instanceof DHPublicKey) {
+                DHPublicKey dhPub = (DHPublicKey) k;
+                assertEquals(dhPub.getParams().getP(), getDHParams().getP());
+            } else if (k instanceof DHPrivateKey) {
+                DHPrivateKey dhPriv = (DHPrivateKey) k;
+                assertEquals(dhPriv.getParams().getP(), getDHParams().getP());
+            } else {
+                fail("not a public or private key!?");
+            }
+        }
         assertNotNull(k.getEncoded());
         assertNotNull(k.getFormat());
 
@@ -344,7 +361,7 @@
      *
      * openssl gendh 512 | openssl dhparams -C
      */
-    private static AlgorithmParameterSpec getDHParams() {
+    private static DHParameterSpec getDHParams() {
         BigInteger p = new BigInteger("E7AB1768BD75CD24700960FFA32D3F1557344E587101237532CC641646ED7A7C104743377F6D46251698B665CE2A6CBAB6714C2569A7D2CA22C0CF03FA40AC93", 16);
         BigInteger g = new BigInteger("02", 16);
         return new DHParameterSpec(p, g, 512);
diff --git a/luni/src/test/java/libcore/java/text/DecimalFormatTest.java b/luni/src/test/java/libcore/java/text/DecimalFormatTest.java
index 722924d..0eae20a 100644
--- a/luni/src/test/java/libcore/java/text/DecimalFormatTest.java
+++ b/luni/src/test/java/libcore/java/text/DecimalFormatTest.java
@@ -124,21 +124,21 @@
         df.setMaximumFractionDigits(2);
         df.setMultiplier(2);
         assertEquals(df.format(BigDecimal.valueOf(0.16)),
-        df.format(BigDecimal.valueOf(0.16).doubleValue()));
+                df.format(BigDecimal.valueOf(0.16).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(0.0293)),
-        df.format(BigDecimal.valueOf(0.0293).doubleValue()));
+                df.format(BigDecimal.valueOf(0.0293).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(0.006)),
-        df.format(BigDecimal.valueOf(0.006).doubleValue()));
+                df.format(BigDecimal.valueOf(0.006).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(0.00283)),
-        df.format(BigDecimal.valueOf(0.00283).doubleValue()));
+                df.format(BigDecimal.valueOf(0.00283).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(1.60)),
         df.format(BigDecimal.valueOf(1.60).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(15)),
-        df.format(BigDecimal.valueOf(15).doubleValue()));
+                df.format(BigDecimal.valueOf(15).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(170)),
-        df.format(BigDecimal.valueOf(170).doubleValue()));
+                df.format(BigDecimal.valueOf(170).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(234.56)),
-        df.format(BigDecimal.valueOf(234.56).doubleValue()));
+                df.format(BigDecimal.valueOf(234.56).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(0)),
         df.format(BigDecimal.valueOf(0).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(-1)),
@@ -146,11 +146,11 @@
         assertEquals(df.format(BigDecimal.valueOf(-10000)),
         df.format(BigDecimal.valueOf(-10000).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(-0.001)),
-        df.format(BigDecimal.valueOf(-0.001).doubleValue()));
+                df.format(BigDecimal.valueOf(-0.001).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(1234567890.1234567)),
-        df.format(BigDecimal.valueOf(1234567890.1234567).doubleValue()));
+                df.format(BigDecimal.valueOf(1234567890.1234567).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(1.234567E100)),
-        df.format(BigDecimal.valueOf(1.234567E100).doubleValue()));
+                df.format(BigDecimal.valueOf(1.234567E100).doubleValue()));
     }
 
     private void assertBigDecimalWithFraction(BigDecimal bd, String expectedResult, int fraction) {
@@ -282,4 +282,40 @@
 
         assertEquals(expected, numberFormat.format(2.01));
     }
+
+    // Confirm the currency symbol used by a format is determined by the locale of the format
+    // not the current default Locale.
+    public void testSetCurrency_symbolOrigin() {
+        Currency currency = Currency.getInstance("CNY");
+        Locale locale1 = Locale.CHINA;
+        Locale locale2 = Locale.US;
+        String locale1Symbol = currency.getSymbol(locale1);
+        String locale2Symbol = currency.getSymbol(locale2);
+        // This test only works if we can tell where the symbol came from, which requires they are
+        // different across the two locales chosen.
+        assertFalse(locale1Symbol.equals(locale2Symbol));
+
+        Locale originalLocale = Locale.getDefault();
+        try {
+            Locale.setDefault(locale1);
+            String amountDefaultLocale1 =
+                    formatArbitraryCurrencyAmountInLocale(currency, locale2);
+
+            Locale.setDefault(locale2);
+            String amountDefaultLocale2 =
+                    formatArbitraryCurrencyAmountInLocale(currency, locale2);
+
+            // This used to fail because Currency.getSymbol() was used without providing the
+            // format's locale.
+            assertEquals(amountDefaultLocale1, amountDefaultLocale2);
+        } finally {
+            Locale.setDefault(originalLocale);
+        }
+    }
+
+    private String formatArbitraryCurrencyAmountInLocale(Currency currency, Locale locale) {
+        NumberFormat localeCurrencyFormat = NumberFormat.getCurrencyInstance(locale);
+        localeCurrencyFormat.setCurrency(currency);
+        return localeCurrencyFormat.format(1000);
+    }
 }
diff --git a/luni/src/test/java/libcore/java/util/CurrencyTest.java b/luni/src/test/java/libcore/java/util/CurrencyTest.java
index fb7fbf6..61a22fd 100644
--- a/luni/src/test/java/libcore/java/util/CurrencyTest.java
+++ b/luni/src/test/java/libcore/java/util/CurrencyTest.java
@@ -67,13 +67,6 @@
         assertEquals(-1, Currency.getInstance("XXX").getDefaultFractionDigits());
     }
 
-    public void test_getNumericCode() throws Exception {
-        assertEquals(840, Currency.getInstance("USD").getNumericCode());
-        assertEquals(826, Currency.getInstance("GBP").getNumericCode());
-        assertEquals(999, Currency.getInstance("XXX").getNumericCode());
-        assertEquals(0, Currency.getInstance("XFU").getNumericCode());
-    }
-
     // http://code.google.com/p/android/issues/detail?id=38622
     public void test_getSymbol_38622() throws Exception {
         // The CLDR data had the Portuguese symbol for "EUR" in pt, not in pt_PT.
diff --git a/luni/src/test/java/libcore/java/util/LocaleTest.java b/luni/src/test/java/libcore/java/util/LocaleTest.java
index f3b31bb..94bf363 100644
--- a/luni/src/test/java/libcore/java/util/LocaleTest.java
+++ b/luni/src/test/java/libcore/java/util/LocaleTest.java
@@ -107,22 +107,38 @@
         assertEquals("Taiwan", new Locale("", "TW").getDisplayCountry(Locale.US));
     }
 
-    public void test_tl() throws Exception {
+    public void test_tl_and_fil() throws Exception {
         // In jb-mr1, we had a last-minute hack to always return "Filipino" because
-        // icu4c 4.8 didn't have any localizations for fil. (http://b/7291355)
+        // icu4c 4.8 didn't have any localizations for fil. (http://b/7291355).
+        //
+        // After the icu4c 4.9 upgrade, we could localize "fil" correctly, though we
+        // needed another hack to supply "fil" instead of "tl" to icu4c. (http://b/8023288).
+        //
+        // These hacks have now been reverted, so "tl" really does represent
+        // tagalog and not filipino.
         Locale tl = new Locale("tl");
         Locale tl_PH = new Locale("tl", "PH");
-        assertEquals("Filipino", tl.getDisplayLanguage(Locale.ENGLISH));
-        assertEquals("Filipino", tl_PH.getDisplayLanguage(Locale.ENGLISH));
-        assertEquals("Filipino", tl.getDisplayLanguage(tl));
-        assertEquals("Filipino", tl_PH.getDisplayLanguage(tl_PH));
+        assertEquals("Tagalog", tl.getDisplayLanguage(Locale.ENGLISH));
+        assertEquals("Tagalog", tl_PH.getDisplayLanguage(Locale.ENGLISH));
+        assertEquals("tl", tl.getDisplayLanguage(tl));
+        assertEquals("tl", tl_PH.getDisplayLanguage(tl_PH));
 
-        // After the icu4c 4.9 upgrade, we could localize "fil" correctly, though we
-        // needed another hack to supply "fil" instead of "tl" to icu4c. (http://b/8023288)
         Locale es_MX = new Locale("es", "MX");
-        assertEquals("filipino", tl.getDisplayLanguage(es_MX));
-        assertEquals("filipino", tl_PH.getDisplayLanguage(es_MX));
-      }
+        assertEquals("tagalo", tl.getDisplayLanguage(es_MX));
+        assertEquals("tagalo", tl_PH.getDisplayLanguage(es_MX));
+
+        // Assert that we can deal with "fil" correctly, since we've switched
+        // to using "fil" for Filipino, and not "tl". (http://b/15873165).
+        Locale fil = new Locale("fil");
+        Locale fil_PH = new Locale("fil", "PH");
+        assertEquals("Filipino", fil.getDisplayLanguage(Locale.ENGLISH));
+        assertEquals("Filipino", fil_PH.getDisplayLanguage(Locale.ENGLISH));
+        assertEquals("Filipino", fil.getDisplayLanguage(fil));
+        assertEquals("Filipino", fil_PH.getDisplayLanguage(fil_PH));
+
+        assertEquals("filipino", fil.getDisplayLanguage(es_MX));
+        assertEquals("filipino", fil_PH.getDisplayLanguage(es_MX));
+    }
 
     // http://b/3452611; Locale.getDisplayLanguage fails for the obsolete language codes.
     public void test_getDisplayName_obsolete() throws Exception {
diff --git a/luni/src/test/java/libcore/java/util/OldAndroidLocaleTest.java b/luni/src/test/java/libcore/java/util/OldAndroidLocaleTest.java
index fa761d3..87f2f9d 100644
--- a/luni/src/test/java/libcore/java/util/OldAndroidLocaleTest.java
+++ b/luni/src/test/java/libcore/java/util/OldAndroidLocaleTest.java
@@ -76,9 +76,16 @@
 
     // This one makes sure we have all necessary locales installed.
     public void testICULocales() {
-        String[] locales = new String[] {
-                // List of locales currently required for Android.
-                "en_US", "es_US", "en_GB", "fr_FR", "de_DE", "de_AT", "cs_CZ", "nl_NL" };
+        // List of locales currently required for Android.
+        Locale[] locales = new Locale[] {
+                new Locale("en", "US"),
+                new Locale("es", "US"),
+                new Locale("en", "GB"),
+                new Locale("fr", "FR"),
+                new Locale("de", "DE"),
+                new Locale("de", "AT"),
+                new Locale("cs", "CZ"),
+                new Locale("nl", "NL") };
 
         String[] mondays = new String[] {
                 "Monday", "lunes", "Monday", "lundi", "Montag", "Montag", "pond\u011bl\u00ed", "maandag" };
@@ -87,14 +94,12 @@
                 "USD", "USD", "GBP", "EUR", "EUR", "EUR", "CZK", "EUR"};
 
         for (int i = 0; i < locales.length; i++) {
-            Locale l = new Locale(locales[i].substring(0, 2), locales[i].substring(3));
+            final Locale l = locales[i];
 
-            // Check language part of locale.
             DateFormatSymbols d = new DateFormatSymbols(l);
             assertEquals("Monday name for " + locales[i] + " must match",
                     mondays[i], d.getWeekdays()[2]);
 
-            // Check country part of locale.
             Currency c = Currency.getInstance(l);
             assertEquals("Currency code for " + locales[i] + " must match",
                     currencies[i], c.getCurrencyCode());
diff --git a/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java b/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
index 81ff673..a9ff56f 100644
--- a/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
@@ -217,96 +217,6 @@
         }
     }
 
-    public void testNullCharset() throws IOException {
-        try {
-            new ZipFile(createTemporaryZipFile(), null);
-            fail();
-        } catch (NullPointerException expected) {
-        }
-    }
-
-    // Tests that non-UTF8 encoded zip files can be interpreted. Relies on ZipOutputStream.
-    public void testNonUtf8Encoding() throws IOException {
-        Charset charset = Charset.forName("Cp437");
-        String encodingDependentString = "\u00FB";
-        assertEncodingDiffers(encodingDependentString, charset, StandardCharsets.US_ASCII,
-                StandardCharsets.UTF_8);
-        String name = "name" + encodingDependentString;
-        String comment = "comment" + encodingDependentString;
-
-        File result = createTemporaryZipFile();
-        OutputStream os = new BufferedOutputStream(new FileOutputStream(result));
-        ZipOutputStream out = new ZipOutputStream(os, charset);
-        out.setComment(comment);
-        ZipEntry writeEntry = new ZipEntry(name);
-        writeEntry.setComment(comment);
-        out.putNextEntry(writeEntry);
-        out.write("FileContentsIrrelevant".getBytes());
-        out.closeEntry();
-        out.close();
-
-        ZipFile zipFile = new ZipFile(result, StandardCharsets.US_ASCII);
-        assertNull(zipFile.getEntry(name));
-        assertFalse(zipFile.getComment().equals(comment));
-        zipFile.close();
-
-        zipFile = new ZipFile(result, charset);
-        ZipEntry readEntry = zipFile.getEntry(name);
-        assertNotNull(readEntry);
-        assertEquals(name, readEntry.getName());
-        assertEquals(comment, readEntry.getComment());
-        assertEquals(comment, zipFile.getComment());
-        zipFile.close();
-    }
-
-    // Tests that UTF8 encoded zip files can be interpreted when the constructor is provided with a
-    // non-UTF-8 encoding. Relies on ZipOutputStream.
-    public void testUtf8EncodingOverridesConstructor() throws IOException {
-        Charset charset = Charset.forName("Cp437");
-        String encodingDependentString = "\u00FB";
-        assertEncodingDiffers(encodingDependentString, charset, StandardCharsets.UTF_8);
-        String name = "name" + encodingDependentString;
-        String comment = "comment" + encodingDependentString;
-
-        File result = createTemporaryZipFile();
-        OutputStream os = new BufferedOutputStream(new FileOutputStream(result));
-        ZipOutputStream out = new ZipOutputStream(os, StandardCharsets.UTF_8);
-        // The file comment does not get meta-data about the character encoding.
-        out.setComment(comment);
-        // The entry will be tagged as being UTF-8 encoded.
-        ZipEntry writeEntry = new ZipEntry(name);
-        writeEntry.setComment(comment);
-        out.putNextEntry(writeEntry);
-        out.write("FileContentsIrrelevant".getBytes());
-        out.closeEntry();
-        out.close();
-
-        ZipFile zipFile = new ZipFile(result, charset);
-        // The entry should be found, because it should be tagged as being UTF-8 encoded.
-        ZipEntry readEntry = zipFile.getEntry(name);
-        assertNotNull(readEntry);
-        assertEquals(name, readEntry.getName());
-        assertEquals(comment, readEntry.getComment());
-        // We expect the comment to be mangled because it is not tagged.
-        assertFalse(zipFile.getComment().equals(comment));
-        zipFile.close();
-    }
-
-    /**
-     * Asserts the byte encoding for the string is different for all the supplied character
-     * sets.
-     */
-    private void assertEncodingDiffers(String string, Charset... charsets) {
-        Set<List<Byte>> encodings = new HashSet<List<Byte>>();
-        for (int i = 0; i < charsets.length; i++) {
-            List<Byte> byteList = new ArrayList<Byte>();
-            for (byte b : string.getBytes(charsets[i])) {
-                byteList.add(b);
-            }
-            assertTrue("Encoding has been seen before", encodings.add(byteList));
-        }
-    }
-
     /**
      * Compresses the given number of files, each of the given size, into a .zip archive.
      */
diff --git a/luni/src/test/java/libcore/java/util/zip/ZipInputStreamTest.java b/luni/src/test/java/libcore/java/util/zip/ZipInputStreamTest.java
index 2daa127..49990a3 100644
--- a/luni/src/test/java/libcore/java/util/zip/ZipInputStreamTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/ZipInputStreamTest.java
@@ -50,97 +50,6 @@
         assertTrue(Arrays.equals(data, unzip("r", ZipOutputStreamTest.zip("r", data))));
     }
 
-    public void testNullCharset() throws IOException {
-        try {
-            new ZipInputStream(new ByteArrayInputStream(new byte[1]), null);
-            fail();
-        } catch (NullPointerException expected) {
-        }
-    }
-
-    // Tests that non-UTF8 encoded zip file entries can be interpreted. Relies on ZipOutputStream.
-    public void testNonUtf8Encoding() throws IOException {
-        Charset charset = Charset.forName("Cp437");
-        String encodingDependentString = "\u00FB";
-        assertEncodingDiffers(encodingDependentString, charset, StandardCharsets.US_ASCII,
-                StandardCharsets.UTF_8);
-        String name = "name" + encodingDependentString;
-        String comment = "comment" + encodingDependentString;
-
-        ByteArrayOutputStream bytesOutputStream = new ByteArrayOutputStream();
-        ZipOutputStream out = new ZipOutputStream(bytesOutputStream, charset);
-        ZipEntry writeEntry = new ZipEntry(name);
-        writeEntry.setComment(comment);
-        out.putNextEntry(writeEntry);
-        out.write("FileContentsIrrelevant".getBytes());
-        out.closeEntry();
-        out.close();
-
-        ByteArrayInputStream bytesInputStream =
-                new ByteArrayInputStream(bytesOutputStream.toByteArray());
-        ZipInputStream in = new ZipInputStream(bytesInputStream, StandardCharsets.US_ASCII);
-        ZipEntry readEntry = in.getNextEntry();
-        // Due to the way ZipInputStream works it never returns entry comments.
-        assertNull("ZipInputStream must not retrieve comments", readEntry.getComment());
-        assertFalse(readEntry.getName().equals(name));
-        in.close();
-
-        bytesInputStream = new ByteArrayInputStream(bytesOutputStream.toByteArray());
-        in = new ZipInputStream(bytesInputStream, charset);
-        readEntry = in.getNextEntry();
-        // Because ZipInputStream never reads the central directory it never returns entry
-        // comments or the file comment.
-        assertNull("ZipInputStream must not retrieve comments", readEntry.getComment());
-        assertEquals(name, readEntry.getName());
-        in.close();
-    }
-
-    // Tests that UTF8 encoded zip file entries can be interpreted when the constructor is provided
-    // with a non-UTF-8 encoding. Relies on ZipOutputStream.
-    public void testUtf8EncodingOverridesConstructor() throws IOException {
-        Charset charset = Charset.forName("Cp437");
-        String encodingDependentString = "\u00FB";
-        assertEncodingDiffers(encodingDependentString, charset, StandardCharsets.UTF_8);
-        String name = "name" + encodingDependentString;
-        String comment = "comment" + encodingDependentString;
-
-        ByteArrayOutputStream bytesOutputStream = new ByteArrayOutputStream();
-        ZipOutputStream out = new ZipOutputStream(bytesOutputStream, StandardCharsets.UTF_8);
-        // The entry will be tagged as being UTF-8 encoded.
-        ZipEntry writeEntry = new ZipEntry(name);
-        writeEntry.setComment(comment);
-        out.putNextEntry(writeEntry);
-        out.write("FileContentsIrrelevant".getBytes());
-        out.closeEntry();
-        out.close();
-
-        ByteArrayInputStream bytesInputStream =
-                new ByteArrayInputStream(bytesOutputStream.toByteArray());
-        ZipInputStream in = new ZipInputStream(bytesInputStream, charset);
-        ZipEntry readEntry = in.getNextEntry();
-        // Because ZipInputStream never reads the central directory it never returns entry
-        // comments or the file comment.
-        assertNull("ZipInputStream must not retrieve comments", readEntry.getComment());
-        assertNotNull(readEntry);
-        assertEquals(name, readEntry.getName());
-        in.close();
-    }
-
-    /**
-     * Asserts the byte encoding for the string is different for all the supplied character
-     * sets.
-     */
-    private void assertEncodingDiffers(String string, Charset... charsets) {
-        Set<List<Byte>> encodings = new HashSet<List<Byte>>();
-        for (int i = 0; i < charsets.length; i++) {
-            List<Byte> byteList = new ArrayList<Byte>();
-            for (byte b : string.getBytes(charsets[i])) {
-                byteList.add(b);
-            }
-            assertTrue("Encoding has been seen before", encodings.add(byteList));
-        }
-    }
-
     public static byte[] unzip(String name, byte[] bytes) throws IOException {
         ZipInputStream in = new ZipInputStream(new ByteArrayInputStream(bytes));
         ByteArrayOutputStream out = new ByteArrayOutputStream();
diff --git a/luni/src/test/java/libcore/java/util/zip/ZipOutputStreamTest.java b/luni/src/test/java/libcore/java/util/zip/ZipOutputStreamTest.java
index 92afffa..e69f010 100644
--- a/luni/src/test/java/libcore/java/util/zip/ZipOutputStreamTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/ZipOutputStreamTest.java
@@ -78,14 +78,6 @@
         }
     }
 
-    public void testNullCharset() throws IOException {
-        try {
-            new ZipOutputStream(new ByteArrayOutputStream(), null);
-            fail();
-        } catch (NullPointerException expected) {
-        }
-    }
-
     /** Regression test for null comment causing a NullPointerException during write. */
     public void testNullComment() throws IOException {
         ZipOutputStream out = new ZipOutputStream(new ByteArrayOutputStream());
@@ -95,54 +87,4 @@
         out.closeEntry();
         out.finish();
     }
-
-    /** Contrived test to force a longer name than can be stored. */
-    public void testLongName() throws IOException {
-        int maxNameBytes = 0xffff; // 2 bytes
-        String longName = createString(maxNameBytes);
-
-        ZipEntry entry = new ZipEntry(longName);
-
-        // Using UTF-16 will result in name bytes twice as large as is supported by Zip.
-        // UTF-16 is an unlikely character set to actually want to use with Zip but enables
-        // the edge-case behavior required without using direct field access.
-        ZipOutputStream out = new ZipOutputStream(
-                new ByteArrayOutputStream(), StandardCharsets.UTF_16);
-        try {
-            out.putNextEntry(entry);
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    /** Contrived test to force a longer comment than can be stored. */
-    public void testLongComment() throws IOException {
-        int maxCommentBytes = 0xffff; // 2 bytes
-        String longComment = createString(maxCommentBytes);
-
-        ZipEntry entry = new ZipEntry("name");
-        // setComment() should pass, because it is at the limit of what ZipEntry will detect as
-        // valid (since it uses UTF-8 as a worst-case guess).
-        entry.setComment(longComment);
-
-        // Using UTF-16 will result in comment bytes twice as large as is supported by Zip.
-        // UTF-16 is an unlikely character set to actually want to use with Zip but enables
-        // the edge-case behavior required without using direct field access.
-        ZipOutputStream out = new ZipOutputStream(
-                new ByteArrayOutputStream(), StandardCharsets.UTF_16);
-        try {
-            out.putNextEntry(entry);
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    private static String createString(int numChars) {
-        char c = 'a';
-        StringBuilder sb = new StringBuilder(numChars);
-        for (int i = 0; i < numChars; i++) {
-            sb.append(c);
-        }
-        return sb.toString();
-    }
 }
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLContextTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLContextTest.java
index 0e13fb0..dccadbd 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLContextTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLContextTest.java
@@ -24,7 +24,12 @@
 import java.security.Provider;
 import java.security.Security;
 import java.security.UnrecoverableKeyException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 import java.util.concurrent.Callable;
+import libcore.io.IoUtils;
 import libcore.java.security.StandardNames;
 import javax.net.ServerSocketFactory;
 import javax.net.SocketFactory;
@@ -34,12 +39,15 @@
 import javax.net.ssl.ManagerFactoryParameters;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLServerSocket;
 import javax.net.ssl.SSLServerSocketFactory;
 import javax.net.ssl.SSLSessionContext;
+import javax.net.ssl.SSLSocket;
 import javax.net.ssl.SSLSocketFactory;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.TrustManagerFactory;
 import javax.net.ssl.TrustManagerFactorySpi;
+import javax.net.ssl.X509KeyManager;
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
@@ -85,6 +93,94 @@
         }
     }
 
+    public void test_SSLContext_pskOnlyConfiguration_defaultProviderOnly() throws Exception {
+        // Test the scenario where only a PSKKeyManager is provided and no TrustManagers are
+        // provided.
+        SSLContext sslContext = SSLContext.getInstance("TLS");
+        sslContext.init(
+                new KeyManager[] {
+                        PSKKeyManagerProxy.getConscryptPSKKeyManager(new PSKKeyManagerProxy())
+                },
+                new TrustManager[0],
+                null);
+        List<String> expectedCipherSuites =
+                new ArrayList<String>(StandardNames.CIPHER_SUITES_DEFAULT_PSK);
+        expectedCipherSuites.add(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION);
+        assertEnabledCipherSuites(expectedCipherSuites, sslContext);
+    }
+
+    public void test_SSLContext_x509AndPskConfiguration_defaultProviderOnly() throws Exception {
+        // Test the scenario where an X509TrustManager and PSKKeyManager are provided.
+        SSLContext sslContext = SSLContext.getInstance("TLS");
+        sslContext.init(
+                new KeyManager[] {
+                        PSKKeyManagerProxy.getConscryptPSKKeyManager(new PSKKeyManagerProxy())
+                },
+                null, // Use default trust managers, one of which is an X.509 one.
+                null);
+        List<String> expectedCipherSuites =
+                new ArrayList<String>(StandardNames.CIPHER_SUITES_DEFAULT_PSK);
+        expectedCipherSuites.addAll(StandardNames.CIPHER_SUITES_DEFAULT);
+        assertEnabledCipherSuites(expectedCipherSuites, sslContext);
+
+        // Test the scenario where an X509KeyManager and PSKKeyManager are provided.
+        sslContext = SSLContext.getInstance("TLS");
+        // Just an arbitrary X509KeyManager -- it won't be invoked in this test.
+        X509KeyManager x509KeyManager = new RandomPrivateKeyX509ExtendedKeyManager(null);
+        sslContext.init(
+                new KeyManager[] {
+                        x509KeyManager,
+                        PSKKeyManagerProxy.getConscryptPSKKeyManager(new PSKKeyManagerProxy())
+                },
+                new TrustManager[0],
+                null);
+        assertEnabledCipherSuites(expectedCipherSuites, sslContext);
+    }
+
+    public void test_SSLContext_emptyConfiguration_defaultProviderOnly() throws Exception {
+        // Test the scenario where neither X.509 nor PSK KeyManagers or TrustManagers are provided.
+        SSLContext sslContext = SSLContext.getInstance("TLS");
+        sslContext.init(
+                new KeyManager[0],
+                new TrustManager[0],
+                null);
+        assertEnabledCipherSuites(
+                Arrays.asList(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION),
+                sslContext);
+    }
+
+    private static void assertEnabledCipherSuites(
+            List<String> expectedCipherSuites, SSLContext sslContext) throws Exception {
+        assertContentsInOrder(
+                expectedCipherSuites, sslContext.createSSLEngine().getEnabledCipherSuites());
+        assertContentsInOrder(
+                expectedCipherSuites,
+                sslContext.createSSLEngine().getSSLParameters().getCipherSuites());
+        assertContentsInOrder(
+                expectedCipherSuites, sslContext.getSocketFactory().getDefaultCipherSuites());
+        assertContentsInOrder(
+                expectedCipherSuites, sslContext.getServerSocketFactory().getDefaultCipherSuites());
+
+        SSLSocket sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket();
+        try {
+            assertContentsInOrder(
+                    expectedCipherSuites, sslSocket.getEnabledCipherSuites());
+            assertContentsInOrder(
+                    expectedCipherSuites, sslSocket.getSSLParameters().getCipherSuites());
+        } finally {
+            IoUtils.closeQuietly(sslSocket);
+        }
+
+        SSLServerSocket sslServerSocket =
+                (SSLServerSocket) sslContext.getServerSocketFactory().createServerSocket();
+        try {
+            assertContentsInOrder(
+                    expectedCipherSuites, sslServerSocket.getEnabledCipherSuites());
+        } finally {
+            IoUtils.closeQuietly(sslSocket);
+        }
+    }
+
     public void test_SSLContext_getInstance() throws Exception {
         try {
             SSLContext.getInstance(null);
@@ -463,4 +559,16 @@
         assertTrue(testContext.port != 0);
         testContext.close();
     }
+
+    private static void assertContentsInOrder(List<String> expected, String... actual) {
+        if (expected.size() != actual.length) {
+            fail("Unexpected length. Expected len <" + expected.size()
+                    + ">, actual len <" + actual.length + ">, expected <" + expected
+                    + ">, actual <" + Arrays.asList(actual) + ">");
+        }
+        if (!expected.equals(Arrays.asList(actual))) {
+            fail("Unexpected element(s). Expected <" + expected
+                    + ">, actual <" + Arrays.asList(actual) + ">" );
+        }
+    }
 }
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
index c32a178..8e29e71 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
@@ -282,6 +282,16 @@
         c.close();
     }
 
+    public void test_SSLEngine_setEnabledCipherSuites_storesCopy() throws Exception {
+        TestSSLContext c = TestSSLContext.create();
+        SSLEngine e = c.clientContext.createSSLEngine();
+        String[] array = new String[] {e.getEnabledCipherSuites()[0]};
+        String originalFirstElement = array[0];
+        e.setEnabledCipherSuites(array);
+        array[0] = "Modified after having been set";
+        assertEquals(originalFirstElement, e.getEnabledCipherSuites()[0]);
+    }
+
     public void test_SSLEngine_setEnabledCipherSuites() throws Exception {
         TestSSLContext c = TestSSLContext.create();
         SSLEngine e = c.clientContext.createSSLEngine();
@@ -328,6 +338,16 @@
         c.close();
     }
 
+    public void test_SSLEngine_setEnabledProtocols_storesCopy() throws Exception {
+        TestSSLContext c = TestSSLContext.create();
+        SSLEngine e = c.clientContext.createSSLEngine();
+        String[] array = new String[] {e.getEnabledProtocols()[0]};
+        String originalFirstElement = array[0];
+        e.setEnabledProtocols(array);
+        array[0] = "Modified after having been set";
+        assertEquals(originalFirstElement, e.getEnabledProtocols()[0]);
+    }
+
     public void test_SSLEngine_setEnabledProtocols() throws Exception {
         TestSSLContext c = TestSSLContext.create();
         SSLEngine e = c.clientContext.createSSLEngine();
@@ -573,20 +593,6 @@
         }
     }
 
-    public void test_SSLEngine_endpointVerification_Success() throws Exception {
-        TestSSLContext c = TestSSLContext.create();
-        TestSSLEnginePair p = TestSSLEnginePair.create(c, new TestSSLEnginePair.Hooks() {
-            @Override
-            void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
-                SSLParameters p = client.getSSLParameters();
-                p.setEndpointIdentificationAlgorithm("HTTPS");
-                client.setSSLParameters(p);
-            }
-        });
-        assertConnected(p);
-        c.close();
-    }
-
     public void test_SSLEngine_getEnableSessionCreation() throws Exception {
         TestSSLContext c = TestSSLContext.create();
         SSLEngine e = c.clientContext.createSSLEngine();
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketTest.java
index 8c4dbdd..59c44c1 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLServerSocketTest.java
@@ -36,6 +36,16 @@
     assertEquals(Arrays.asList(cipherSuites), Arrays.asList(socket.getEnabledCipherSuites()));
   }
 
+  public void testSetEnabledCipherSuitesStoresCopy() throws Exception {
+      SSLServerSocket socket =
+              (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket();
+      String[] array = new String[] {socket.getEnabledCipherSuites()[0]};
+      String originalFirstElement = array[0];
+      socket.setEnabledCipherSuites(array);
+      array[0] = "Modified after having been set";
+      assertEquals(originalFirstElement, socket.getEnabledCipherSuites()[0]);
+  }
+
   public void testSetEnabledProtocolsAffectsGetter() throws Exception {
     SSLServerSocket socket =
         (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket();
@@ -43,4 +53,14 @@
     socket.setEnabledProtocols(protocols);
     assertEquals(Arrays.asList(protocols), Arrays.asList(socket.getEnabledProtocols()));
   }
+
+  public void testSetEnabledProtocolsStoresCopy() throws Exception {
+      SSLServerSocket socket =
+              (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket();
+      String[] array = new String[] {socket.getEnabledProtocols()[0]};
+      String originalFirstElement = array[0];
+      socket.setEnabledProtocols(array);
+      array[0] = "Modified after having been set";
+      assertEquals(originalFirstElement, socket.getEnabledProtocols()[0]);
+  }
 }
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java
index 86e96ff..d59bbb2 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java
@@ -16,24 +16,198 @@
 
 package libcore.javax.net.ssl;
 
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.net.SocketException;
+import java.security.KeyManagementException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.util.Properties;
 import javax.net.ServerSocketFactory;
 import javax.net.SocketFactory;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLContextSpi;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSessionContext;
 import javax.net.ssl.SSLSocket;
 import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
 import junit.framework.TestCase;
+import libcore.java.security.StandardNames;
 
 public class SSLSocketFactoryTest extends TestCase {
+    private static final String SSL_PROPERTY = "ssl.SocketFactory.provider";
+
     public void test_SSLSocketFactory_getDefault() {
         SocketFactory sf = SSLSocketFactory.getDefault();
         assertNotNull(sf);
         assertTrue(SSLSocketFactory.class.isAssignableFrom(sf.getClass()));
     }
 
+    public static class FakeSSLSocketProvider extends Provider {
+        public FakeSSLSocketProvider() {
+            super("FakeSSLSocketProvider", 1.0, "Testing provider");
+            put("SSLContext.Default", FakeSSLContextSpi.class.getName());
+        }
+    }
+
+    public static final class FakeSSLContextSpi extends SSLContextSpi {
+        @Override
+        protected void engineInit(KeyManager[] keyManagers, TrustManager[] trustManagers,
+                SecureRandom secureRandom) throws KeyManagementException {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        protected SSLSocketFactory engineGetSocketFactory() {
+            return new FakeSSLSocketFactory();
+        }
+
+        @Override
+        protected SSLServerSocketFactory engineGetServerSocketFactory() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        protected SSLEngine engineCreateSSLEngine(String s, int i) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        protected SSLEngine engineCreateSSLEngine() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        protected SSLSessionContext engineGetServerSessionContext() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        protected SSLSessionContext engineGetClientSessionContext() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    public static class FakeSSLSocketFactory extends SSLSocketFactory {
+        public FakeSSLSocketFactory() {
+        }
+
+        @Override
+        public String[] getDefaultCipherSuites() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public String[] getSupportedCipherSuites() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Socket createSocket(Socket s, String host, int port, boolean autoClose) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Socket createSocket(InetAddress address, int port, InetAddress localAddress,
+                int localPort) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Socket createSocket(InetAddress host, int port) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Socket createSocket(String host, int port, InetAddress localHost, int localPort) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Socket createSocket(String host, int port) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    public void test_SSLSocketFactory_getDefault_cacheInvalidate() throws Exception {
+        String origProvider = resetSslProvider();
+        try {
+            SocketFactory sf1 = SSLSocketFactory.getDefault();
+            assertNotNull(sf1);
+            assertTrue(SSLSocketFactory.class.isAssignableFrom(sf1.getClass()));
+
+            Provider fakeProvider = new FakeSSLSocketProvider();
+            SocketFactory sf4 = null;
+            SSLContext origContext = null;
+            try {
+                origContext = SSLContext.getDefault();
+                Security.insertProviderAt(fakeProvider, 1);
+                SSLContext.setDefault(SSLContext.getInstance("Default", fakeProvider));
+
+                sf4 = SSLSocketFactory.getDefault();
+                assertNotNull(sf4);
+                assertTrue(SSLSocketFactory.class.isAssignableFrom(sf4.getClass()));
+
+                assertFalse(sf1.getClass() + " should not be " + sf4.getClass(),
+                        sf1.getClass().equals(sf4.getClass()));
+            } finally {
+                SSLContext.setDefault(origContext);
+                Security.removeProvider(fakeProvider.getName());
+            }
+
+            SocketFactory sf3 = SSLSocketFactory.getDefault();
+            assertNotNull(sf3);
+            assertTrue(SSLSocketFactory.class.isAssignableFrom(sf3.getClass()));
+
+            assertTrue(sf1.getClass() + " should be " + sf3.getClass(),
+                    sf1.getClass().equals(sf3.getClass()));
+
+            if (!StandardNames.IS_RI) {
+                Security.setProperty(SSL_PROPERTY, FakeSSLSocketFactory.class.getName());
+                SocketFactory sf2 = SSLSocketFactory.getDefault();
+                assertNotNull(sf2);
+                assertTrue(SSLSocketFactory.class.isAssignableFrom(sf2.getClass()));
+
+                assertFalse(sf2.getClass().getName() + " should not be " + Security.getProperty(SSL_PROPERTY),
+                        sf1.getClass().equals(sf2.getClass()));
+                assertTrue(sf2.getClass().equals(sf4.getClass()));
+
+                resetSslProvider();
+            }
+        } finally {
+            Security.setProperty(SSL_PROPERTY, origProvider);
+        }
+    }
+
+    private String resetSslProvider() {
+        String origProvider = Security.getProperty(SSL_PROPERTY);
+
+        try {
+            Field field_secprops = Security.class.getDeclaredField("secprops");
+            field_secprops.setAccessible(true);
+            Properties secprops = (Properties) field_secprops.get(null);
+            secprops.remove(SSL_PROPERTY);
+
+            Class<?> class_services =
+                    Class.forName("org.apache.harmony.security.fortress.Services");
+            Method m_setNeedRefresh = class_services.getMethod("setNeedRefresh");
+            m_setNeedRefresh.invoke(null);
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail("Cannot find a way to clear out the SocketFactory provider");
+        }
+
+        return origProvider;
+    }
+
     public void test_SSLSocketFactory_defaultConfiguration() throws Exception {
         SSLDefaultConfigurationAsserts.assertSSLSocketFactory(
                 (SSLSocketFactory) SSLSocketFactory.getDefault());
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
index 47e83cb..d24ef0b 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
@@ -192,6 +192,16 @@
         assertNotSame(ssl.getEnabledCipherSuites(), ssl.getEnabledCipherSuites());
     }
 
+    public void test_SSLSocket_setEnabledCipherSuites_storesCopy() throws Exception {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket ssl = (SSLSocket) sf.createSocket();
+        String[] array = new String[] {ssl.getEnabledCipherSuites()[0]};
+        String originalFirstElement = array[0];
+        ssl.setEnabledCipherSuites(array);
+        array[0] = "Modified after having been set";
+        assertEquals(originalFirstElement, ssl.getEnabledCipherSuites()[0]);
+    }
+
     public void test_SSLSocket_setEnabledCipherSuites() throws Exception {
         SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
         SSLSocket ssl = (SSLSocket) sf.createSocket();
@@ -234,6 +244,16 @@
         assertNotSame(ssl.getEnabledProtocols(), ssl.getEnabledProtocols());
     }
 
+    public void test_SSLSocket_setEnabledProtocols_storesCopy() throws Exception {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket ssl = (SSLSocket) sf.createSocket();
+        String[] array = new String[] {ssl.getEnabledProtocols()[0]};
+        String originalFirstElement = array[0];
+        ssl.setEnabledProtocols(array);
+        array[0] = "Modified after having been set";
+        assertEquals(originalFirstElement, ssl.getEnabledProtocols()[0]);
+    }
+
     public void test_SSLSocket_setEnabledProtocols() throws Exception {
         SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
         SSLSocket ssl = (SSLSocket) sf.createSocket();
@@ -281,13 +301,6 @@
         assertFalse(session.isValid());
     }
 
-    public void test_SSLSocket_getHandshakeSession() throws Exception {
-        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
-        SSLSocket ssl = (SSLSocket) sf.createSocket();
-        SSLSession session = ssl.getHandshakeSession();
-        assertNull(session);
-    }
-
     public void test_SSLSocket_startHandshake() throws Exception {
         final TestSSLContext c = TestSSLContext.create();
         SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
@@ -298,7 +311,6 @@
             @Override public Void call() throws Exception {
                 server.startHandshake();
                 assertNotNull(server.getSession());
-                assertNull(server.getHandshakeSession());
                 try {
                     server.getSession().getPeerCertificates();
                     fail();
@@ -510,7 +522,6 @@
                     assertSame(client, socket);
 
                     assertTrue(socket instanceof SSLSocket);
-                    assertNull(((SSLSocket) socket).getHandshakeSession());
 
                     synchronized (handshakeCompletedListenerCalled) {
                         handshakeCompletedListenerCalled[0] = true;
@@ -941,14 +952,6 @@
 
         assertEquals(p.getWantClientAuth(), ssl.getWantClientAuth());
         assertEquals(p.getNeedClientAuth(), ssl.getNeedClientAuth());
-
-        assertNull(p.getEndpointIdentificationAlgorithm());
-        p.setEndpointIdentificationAlgorithm(null);
-        assertNull(p.getEndpointIdentificationAlgorithm());
-        p.setEndpointIdentificationAlgorithm("HTTPS");
-        assertEquals("HTTPS", p.getEndpointIdentificationAlgorithm());
-        p.setEndpointIdentificationAlgorithm("FOO");
-        assertEquals("FOO", p.getEndpointIdentificationAlgorithm());
     }
 
     public void test_SSLSocket_setSSLParameters() throws Exception {
@@ -1132,84 +1135,6 @@
         server.close();
     }
 
-    public void test_SSLSocket_endpointIdentification_Success() throws Exception {
-        final TestSSLContext c = TestSSLContext.create();
-        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket();
-        SSLParameters p = client.getSSLParameters();
-        p.setEndpointIdentificationAlgorithm("HTTPS");
-        client.connect(new InetSocketAddress(c.host, c.port));
-        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
-        ExecutorService executor = Executors.newSingleThreadExecutor();
-        Future<Void> future = executor.submit(new Callable<Void>() {
-            @Override public Void call() throws Exception {
-                server.startHandshake();
-                assertNotNull(server.getSession());
-                try {
-                    server.getSession().getPeerCertificates();
-                    fail();
-                } catch (SSLPeerUnverifiedException expected) {
-                }
-                Certificate[] localCertificates = server.getSession().getLocalCertificates();
-                assertNotNull(localCertificates);
-                TestKeyStore.assertChainLength(localCertificates);
-                assertNotNull(localCertificates[0]);
-                TestSSLContext.assertCertificateInKeyStore(localCertificates[0],
-                                                           c.serverKeyStore);
-                return null;
-            }
-        });
-        executor.shutdown();
-        client.startHandshake();
-        assertNotNull(client.getSession());
-        assertNull(client.getSession().getLocalCertificates());
-        Certificate[] peerCertificates = client.getSession().getPeerCertificates();
-        assertNotNull(peerCertificates);
-        TestKeyStore.assertChainLength(peerCertificates);
-        assertNotNull(peerCertificates[0]);
-        TestSSLContext.assertCertificateInKeyStore(peerCertificates[0], c.serverKeyStore);
-        future.get();
-        client.close();
-        server.close();
-        c.close();
-    }
-
-    public void test_SSLSocket_endpointIdentification_Failure() throws Exception {
-
-        final TestSSLContext c = TestSSLContext.create();
-        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(
-                InetAddress.getByName("127.0.0.2"), c.port);
-        SSLParameters p = client.getSSLParameters();
-        p.setEndpointIdentificationAlgorithm("HTTPS");
-        client.setSSLParameters(p);
-        // client.connect(new InetSocketAddress(c.host, c.port));
-        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
-        ExecutorService executor = Executors.newSingleThreadExecutor();
-        Future<Void> future = executor.submit(new Callable<Void>() {
-            @Override public Void call() throws Exception {
-                try {
-                    server.startHandshake();
-                    fail("Should receive SSLHandshakeException as server");
-                } catch (SSLHandshakeException expected) {
-                }
-                return null;
-            }
-        });
-        executor.shutdown();
-        try {
-            client.startHandshake();
-            fail("Should throw when hostname does not match expected");
-        } catch (SSLHandshakeException expected) {
-        } finally {
-            try {
-                future.get();
-            } finally {
-                client.close();
-                server.close();
-                c.close();
-            }
-        }
-    }
-
     public void test_SSLSocket_setSoTimeout_basic() throws Exception {
         ServerSocket listening = new ServerSocket(0);
 
diff --git a/luni/src/test/java/libcore/util/ZoneInfoDBTest.java b/luni/src/test/java/libcore/util/ZoneInfoDBTest.java
index 215821d..f5d4e54 100644
--- a/luni/src/test/java/libcore/util/ZoneInfoDBTest.java
+++ b/luni/src/test/java/libcore/util/ZoneInfoDBTest.java
@@ -77,6 +77,24 @@
     }
   }
 
+  // Confirms any caching that exists correctly handles TimeZone mutability.
+  public void testTimeZoneMutability() throws Exception {
+    ZoneInfoDB.TzData data = new ZoneInfoDB.TzData(TZDATA_IN_ROOT);
+    String tzId = "Europe/London";
+    ZoneInfo first = data.makeTimeZone(tzId);
+    ZoneInfo second = data.makeTimeZone(tzId);
+    assertNotSame(first, second);
+
+    assertTrue(first.hasSameRules(second));
+
+    first.setID("Not Europe/London");
+
+    assertFalse(first.getID().equals(second.getID()));
+
+    first.setRawOffset(3600);
+    assertFalse(first.getRawOffset() == second.getRawOffset());
+  }
+
   private static String makeCorruptFile() throws Exception {
     return makeTemporaryFile("invalid content".getBytes());
   }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java
index d3da174..d52b033 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java
@@ -484,20 +484,6 @@
         fileURLCon.getInputStream().close();
     }
 
-    /**
-     * {@link java.net.URLConnection#getContentLengthLong()}
-     */
-    public void test_getContentLengthLong() throws Exception {
-        assertEquals(testString.getBytes().length, fileURLCon.getContentLengthLong());
-        assertEquals(Support_TestWebData.test1.length, uc.getContentLengthLong());
-        assertEquals(Support_TestWebData.test2.length, uc2.getContentLengthLong());
-
-        assertTrue(jarURLCon.getContentLength() > 0);
-        assertTrue(gifURLCon.getContentLength() > 0);
-
-        fileURLCon.getInputStream().close();
-    }
-
     public void test_getContentType() throws Exception {
         assertTrue("getContentType failed: " + fileURLCon.getContentType(),
                 fileURLCon.getContentType().contains("text/plain"));
@@ -772,39 +758,6 @@
     }
 
     /**
-     * {@link java.net.URLConnection#getHeaderFieldLong(String, long)}
-     */
-    public void test_getHeaderFieldLong() throws IOException, ParseException {
-        // Test getHeaderFieldLong() can read an int value.
-        Support_TestWebData params0 = Support_TestWebData.testParams[0];
-        long hf = uc.getHeaderFieldLong("Content-Length", Long.MIN_VALUE);
-        assertEquals(params0.testLength, hf);
-
-        // Test getHeaderFieldLong() for a value outside of the range of int.
-        Support_TestWebData params2 = Support_TestWebData.testParams[2];
-        hf = uc3.getHeaderFieldLong("Content-Length", Long.MIN_VALUE);
-        assertEquals(params2.testLength, hf);
-
-        // The remaining fields should be invalid or missing. Confirm the default is returned.
-        hf = uc3.getHeaderFieldLong("Content-Encoding", Long.MIN_VALUE);
-        assertEquals(Long.MIN_VALUE, hf);
-        hf = uc3.getHeaderFieldInt("Content-Type", Integer.MIN_VALUE);
-        assertEquals(Integer.MIN_VALUE, hf);
-        hf = uc3.getHeaderFieldInt("Date", Integer.MIN_VALUE);
-        assertEquals(Integer.MIN_VALUE, hf);
-        hf = uc3.getHeaderFieldInt("Expires", Integer.MIN_VALUE);
-        assertEquals(Integer.MIN_VALUE, hf);
-        hf = uc3.getHeaderFieldInt("SERVER", Integer.MIN_VALUE);
-        assertEquals(Integer.MIN_VALUE, hf);
-        hf = uc3.getHeaderFieldInt("Last-Modified", Integer.MIN_VALUE);
-        assertEquals(Integer.MIN_VALUE, hf);
-        hf = uc3.getHeaderFieldInt("accept-ranges", Integer.MIN_VALUE);
-        assertEquals(Integer.MIN_VALUE, hf);
-        hf = uc3.getHeaderFieldInt("DoesNotExist", Integer.MIN_VALUE);
-        assertEquals(Integer.MIN_VALUE, hf);
-    }
-
-    /**
      * {@link java.net.URLConnection#getHeaderField(java.lang.String)}
      */
     public void test_getHeaderFieldLjava_lang_String() {
diff --git a/support/src/test/java/libcore/java/security/StandardNames.java b/support/src/test/java/libcore/java/security/StandardNames.java
index 2090d3b..a526c2e 100644
--- a/support/src/test/java/libcore/java/security/StandardNames.java
+++ b/support/src/test/java/libcore/java/security/StandardNames.java
@@ -717,8 +717,8 @@
         addOpenSsl("TLS_PSK_WITH_3DES_EDE_CBC_SHA");
         addOpenSsl("TLS_PSK_WITH_AES_128_CBC_SHA");
         addOpenSsl("TLS_PSK_WITH_AES_256_CBC_SHA");
-        addOpenSsl("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256");
-        addOpenSsl("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384");
+        addOpenSsl("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA");
+        addOpenSsl("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA");
 
         // RFC 5746's Signaling Cipher Suite Value to indicate a request for secure renegotiation
         addBoth(CIPHER_SUITE_SECURE_RENEGOTIATION);
@@ -863,6 +863,15 @@
                             "SSL_RSA_WITH_RC4_128_SHA",
                             CIPHER_SUITE_SECURE_RENEGOTIATION);
 
+    // NOTE: This list needs to be kept in sync with Javadoc of javax.net.ssl.SSLSocket and
+    // javax.net.ssl.SSLEngine.
+    public static final List<String> CIPHER_SUITES_DEFAULT_PSK = Arrays.asList(
+            "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
+            "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA",
+            "TLS_PSK_WITH_AES_128_CBC_SHA",
+            "TLS_PSK_WITH_AES_256_CBC_SHA"
+            );
+
     private static final Set<String> PERMITTED_DEFAULT_KEY_EXCHANGE_ALGS =
             new HashSet<String>(Arrays.asList("RSA",
                                               "DHE_RSA",
diff --git a/support/src/test/java/libcore/javax/net/ssl/TestSSLContext.java b/support/src/test/java/libcore/javax/net/ssl/TestSSLContext.java
index 5741f2b..8dd2085 100644
--- a/support/src/test/java/libcore/javax/net/ssl/TestSSLContext.java
+++ b/support/src/test/java/libcore/javax/net/ssl/TestSSLContext.java
@@ -33,7 +33,6 @@
 import javax.net.ssl.SSLSocket;
 import javax.net.ssl.SSLSocketFactory;
 import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509ExtendedTrustManager;
 import javax.net.ssl.X509TrustManager;
 import junit.framework.Assert;
 import libcore.java.security.StandardNames;
@@ -83,8 +82,8 @@
     public final char[] serverStorePassword;
     public final KeyManager[] clientKeyManagers;
     public final KeyManager[] serverKeyManagers;
-    public final X509ExtendedTrustManager clientTrustManager;
-    public final X509ExtendedTrustManager serverTrustManager;
+    public final X509TrustManager clientTrustManager;
+    public final X509TrustManager serverTrustManager;
     public final SSLContext clientContext;
     public final SSLContext serverContext;
     public final SSLServerSocket serverSocket;
@@ -97,8 +96,8 @@
                            char[] serverStorePassword,
                            KeyManager[] clientKeyManagers,
                            KeyManager[] serverKeyManagers,
-                           X509ExtendedTrustManager clientTrustManager,
-                           X509ExtendedTrustManager serverTrustManager,
+                           X509TrustManager clientTrustManager,
+                           X509TrustManager serverTrustManager,
                            SSLContext clientContext,
                            SSLContext serverContext,
                            SSLServerSocket serverSocket,
@@ -189,8 +188,8 @@
                                       serverKeyStore, serverStorePassword,
                                       clientKeyManagers,
                                       serverKeyManagers,
-                                      (X509ExtendedTrustManager) clientTrustManagers,
-                                      (X509ExtendedTrustManager) serverTrustManagers,
+                                      (X509TrustManager) clientTrustManagers,
+                                      (X509TrustManager) serverTrustManagers,
                                       clientContext, serverContext,
                                       serverSocket, host, port);
         } catch (RuntimeException e) {
diff --git a/support/src/test/java/libcore/javax/net/ssl/TestTrustManager.java b/support/src/test/java/libcore/javax/net/ssl/TestTrustManager.java
index b703984..dc4bb28 100644
--- a/support/src/test/java/libcore/javax/net/ssl/TestTrustManager.java
+++ b/support/src/test/java/libcore/javax/net/ssl/TestTrustManager.java
@@ -20,7 +20,6 @@
 import java.net.Socket;
 import javax.net.ssl.SSLEngine;
 import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509ExtendedTrustManager;
 import javax.net.ssl.X509TrustManager;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
@@ -29,16 +28,15 @@
 
 /**
  * TestTrustManager is a simple proxy class that wraps an existing
- * X509ExtendedTrustManager to provide debug logging and recording of
+ * X509TrustManager to provide debug logging and recording of
  * values.
  */
-public final class TestTrustManager extends X509ExtendedTrustManager {
+public final class TestTrustManager implements X509TrustManager {
 
     private static final boolean LOG = false;
     private static final PrintStream out = LOG ? System.out : new NullPrintStream();
 
     private final X509TrustManager trustManager;
-    private final X509ExtendedTrustManager extendedTrustManager;
 
     public static TrustManager[] wrap(TrustManager[] trustManagers) {
         TrustManager[] result = trustManagers.clone();
@@ -49,23 +47,14 @@
     }
 
     public static TrustManager wrap(TrustManager trustManager) {
-        if (trustManager instanceof X509ExtendedTrustManager) {
-            return new TestTrustManager((X509ExtendedTrustManager) trustManager);
-        } else if (trustManager instanceof X509TrustManager) {
+        if (trustManager instanceof X509TrustManager) {
             return new TestTrustManager((X509TrustManager) trustManager);
         }
         return trustManager;
     }
 
-    public TestTrustManager(X509ExtendedTrustManager trustManager) {
-        out.println("TestTrustManager.<init> extendedTrustManager=" + trustManager);
-        this.extendedTrustManager = trustManager;
-        this.trustManager = trustManager;
-    }
-
     public TestTrustManager(X509TrustManager trustManager) {
         out.println("TestTrustManager.<init> trustManager=" + trustManager);
-        this.extendedTrustManager = null;
         this.trustManager = trustManager;
     }
 
@@ -84,50 +73,6 @@
         }
     }
 
-    @Override
-    public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket)
-            throws CertificateException {
-        if (extendedTrustManager == null) {
-            out.print("(fallback to X509TrustManager) ");
-            checkClientTrusted(chain, authType);
-            return;
-        }
-        out.print("TestTrustManager.checkClientTrusted "
-                + "chain=" + chain.length + " "
-                + "authType=" + authType + " "
-                + "socket=" + socket + " ");
-        try {
-            assertClientAuthType(authType);
-            extendedTrustManager.checkClientTrusted(chain, authType, socket);
-            out.println("OK");
-        } catch (CertificateException e) {
-            e.printStackTrace(out);
-            throw e;
-        }
-    }
-
-    @Override
-    public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine)
-            throws CertificateException {
-        if (extendedTrustManager == null) {
-            out.print("(fallback to X509TrustManager) ");
-            checkClientTrusted(chain, authType);
-            return;
-        }
-        out.print("TestTrustManager.checkClientTrusted "
-                + "chain=" + chain.length + " "
-                + "authType=" + authType + " "
-                + "engine=" + engine + " ");
-        try {
-            assertClientAuthType(authType);
-            extendedTrustManager.checkClientTrusted(chain, authType, engine);
-            out.println("OK");
-        } catch (CertificateException e) {
-            e.printStackTrace(out);
-            throw e;
-        }
-    }
-
     private void assertClientAuthType(String authType) {
         if (!StandardNames.CLIENT_AUTH_TYPES.contains(authType)) {
             throw new AssertionError("Unexpected client auth type " + authType);
@@ -149,50 +94,6 @@
         }
     }
 
-    @Override
-    public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket)
-            throws CertificateException {
-        if (extendedTrustManager == null) {
-            out.print("(fallback to X509TrustManager) ");
-            checkServerTrusted(chain, authType);
-            return;
-        }
-        out.print("TestTrustManager.checkServerTrusted "
-                + "chain=" + chain.length + " "
-                + "authType=" + authType + " "
-                + "socket=" + socket.toString() + " ");
-        try {
-            assertServerAuthType(authType);
-            extendedTrustManager.checkServerTrusted(chain, authType, socket);
-            out.println("OK");
-        } catch (CertificateException e) {
-            e.printStackTrace(out);
-            throw e;
-        }
-    }
-
-    @Override
-    public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine)
-            throws CertificateException {
-        if (extendedTrustManager == null) {
-            out.print("(fallback to X509TrustManager) ");
-            checkServerTrusted(chain, authType);
-            return;
-        }
-        out.print("TestTrustManager.checkServerTrusted "
-                + "chain=" + chain.length + " "
-                + "authType=" + authType + " "
-                + "engine=" + engine.toString() + " ");
-        try {
-            assertServerAuthType(authType);
-            extendedTrustManager.checkServerTrusted(chain, authType, engine);
-            out.println("OK");
-        } catch (CertificateException e) {
-            e.printStackTrace(out);
-            throw e;
-        }
-    }
-
     private void assertServerAuthType(String authType) {
         if (!StandardNames.SERVER_AUTH_TYPES.contains(authType)) {
             throw new AssertionError("Unexpected server auth type " + authType);