Merge "Update java.util.jar to openJdk8u60"
diff --git a/JavaLibrary.mk b/JavaLibrary.mk
index cda2d47..33b127c 100644
--- a/JavaLibrary.mk
+++ b/JavaLibrary.mk
@@ -171,8 +171,8 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, dalvik/test-rules/src/main test-rules/src/main)
 LOCAL_NO_STANDARD_LIBRARIES := true
 LOCAL_MODULE := core-test-rules
-LOCAL_JAVA_LIBRARIES := core-all core-junit
-LOCAL_STATIC_JAVA_LIBRARIES := junit4-target
+LOCAL_JAVA_LIBRARIES := core-all
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
 # Build libcore test rules for host
@@ -206,7 +206,7 @@
 LOCAL_SRC_FILES := $(test_src_files)
 LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
 LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := core-oj core-libart okhttp core-junit junit4-target bouncycastle mockito-target
+LOCAL_JAVA_LIBRARIES := core-oj core-libart okhttp junit bouncycastle mockito-target
 LOCAL_STATIC_JAVA_LIBRARIES := \
 	core-test-rules \
 	core-tests-support \
@@ -227,7 +227,7 @@
 LOCAL_SRC_FILES := $(call all-test-java-files-under,support)
 LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
 LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := core-oj core-libart core-junit junit4-target bouncycastle
+LOCAL_JAVA_LIBRARIES := core-oj core-libart junit bouncycastle
 LOCAL_STATIC_JAVA_LIBRARIES := bouncycastle-bcpkix bouncycastle-ocsp
 LOCAL_JAVACFLAGS := $(local_javac_flags)
 LOCAL_MODULE := core-tests-support
@@ -241,7 +241,7 @@
 LOCAL_SRC_FILES :=  $(call all-test-java-files-under, jsr166-tests)
 LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
 LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := core-oj core-libart core-junit junit4-target
+LOCAL_JAVA_LIBRARIES := core-oj core-libart junit
 LOCAL_JAVACFLAGS := $(local_javac_flags)
 LOCAL_MODULE := jsr166-tests
 LOCAL_JAVA_LANGUAGE_VERSION := 1.8
diff --git a/benchmarks/Android.mk b/benchmarks/Android.mk
index 22d0d26..c48c224 100644
--- a/benchmarks/Android.mk
+++ b/benchmarks/Android.mk
@@ -28,7 +28,7 @@
   core-oj \
   core-libart \
   conscrypt \
-  core-junit \
+  legacy-test \
   bouncycastle \
   framework
 LOCAL_MODULE_TAGS := tests
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectInputStream2Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectInputStream2Test.java
index e81224a..af5fce5 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectInputStream2Test.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectInputStream2Test.java
@@ -17,10 +17,8 @@
 
 package org.apache.harmony.tests.java.io;
 
-import dalvik.system.DexFile;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InvalidClassException;
@@ -29,9 +27,6 @@
 import java.io.ObjectStreamClass;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
-import java.lang.reflect.Field;
-import java.nio.file.Files;
-import java.nio.file.StandardCopyOption;
 import java.util.ArrayList;
 
 import junit.framework.TestCase;
@@ -215,54 +210,4 @@
             // Excpected
         }
     }
-
-    // http://b/29721023
-    public void test_sameName() throws Exception {
-        // Load class from dex, it's not possible to create a class with same-named
-        // fields in java (but it's allowed in dex).
-        File sameFieldNames = File.createTempFile("sameFieldNames", ".dex");
-        InputStream dexIs = this.getClass().getClassLoader().
-            getResourceAsStream("tests/api/java/io/sameFieldNames.dex");
-        assertNotNull(dexIs);
-
-        Class<?> clazz = null;
-
-        // Get the class object
-        try {
-            Files.copy(dexIs, sameFieldNames.toPath(), StandardCopyOption.REPLACE_EXISTING);
-            DexFile dexFile = new DexFile(sameFieldNames);
-            clazz = dexFile.loadClass("sameFieldNames", getClass().getClassLoader());
-            dexFile.close();
-        } finally {
-            if (sameFieldNames.exists()) {
-                sameFieldNames.delete();
-            }
-        }
-
-        // Create class instance, fill it with content
-        Object o1 = clazz.getConstructor().newInstance();
-        int v = 123;
-        for(Field f : clazz.getFields()) {
-            if (f.getType() == Integer.class) {
-                f.set(o1, new Integer(v++));
-            } else if (f.getType() == Long.class) {
-                f.set(o1, new Long(v++));
-            }
-        }
-
-        // Serialize and deserialize
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream oos = new ObjectOutputStream(baos);
-        oos.writeObject(o1);
-        oos.close();
-        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
-                baos.toByteArray()));
-        Object o2 = ois.readObject();
-        ois.close();
-
-        // Compare content
-        for(Field f : clazz.getFields()) {
-            assertEquals(f.get(o1), f.get(o2));
-        }
-    }
 }
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamClassTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamClassTest.java
index 6253b6b..bebeb6e 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamClassTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamClassTest.java
@@ -17,23 +17,17 @@
 
 package org.apache.harmony.tests.java.io;
 
-import dalvik.system.DexFile;
 import dalvik.system.VMRuntime;
 import java.io.Externalizable;
-import java.io.File;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
 import java.io.ObjectStreamClass;
 import java.io.ObjectStreamField;
 import java.io.Serializable;
-import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
-import java.nio.file.Files;
-import java.nio.file.StandardCopyOption;
 import junit.framework.TestCase;
 
 public class ObjectStreamClassTest extends TestCase {
@@ -325,27 +319,4 @@
                     hasStaticInitializer.invoke(null, NoClinitChildWithNoClinitParent.class,
                                                 true /* checkSuperclass */));
     }
-
-    // http://b/29721023
-    public void testClassWithSameFieldName() throws Exception {
-        // Load class from dex, it's not possible to create a class with same-named
-        // fields in java (but it's allowed in dex).
-        File sameFieldNames = File.createTempFile("sameFieldNames", ".dex");
-        InputStream dexIs = this.getClass().getClassLoader().
-            getResourceAsStream("tests/api/java/io/sameFieldNames.dex");
-        assertNotNull(dexIs);
-
-        try {
-            Files.copy(dexIs, sameFieldNames.toPath(), StandardCopyOption.REPLACE_EXISTING);
-            DexFile dexFile = new DexFile(sameFieldNames);
-            Class<?> clazz = dexFile.loadClass("sameFieldNames", getClass().getClassLoader());
-            ObjectStreamClass osc = ObjectStreamClass.lookup(clazz);
-            assertEquals(4, osc.getFields().length);
-            dexFile.close();
-        } finally {
-            if (sameFieldNames.exists()) {
-                sameFieldNames.delete();
-            }
-        }
-    }
 }
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/DatagramSocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/DatagramSocketTest.java
index 1cb6808..7523752 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/DatagramSocketTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/DatagramSocketTest.java
@@ -31,11 +31,15 @@
 import java.net.SocketException;
 import java.net.UnknownHostException;
 import java.nio.channels.DatagramChannel;
+import libcore.io.Libcore;
 import libcore.junit.junit3.TestCaseWithRules;
 import libcore.junit.util.ResourceLeakageDetector;
 import org.junit.Rule;
 import org.junit.rules.TestRule;
 
+import static android.system.OsConstants.IPPROTO_IP;
+import static android.system.OsConstants.IP_MULTICAST_ALL;
+
 public class DatagramSocketTest extends TestCaseWithRules {
     @Rule
     public TestRule guardRule = ResourceLeakageDetector.getRule();
@@ -97,8 +101,14 @@
     /**
      * java.net.DatagramSocket#DatagramSocket()
      */
-    public void test_Constructor() throws SocketException {
-        new DatagramSocket().close();
+    public void test_Constructor() throws Exception {
+        try (DatagramSocket ds = new DatagramSocket()) {
+            // Datagram sockets bound to the wildcard INADDR_ANY address should by default only
+            // receive messages from groups they explicitly joined.
+            boolean multicastAllEnabled = Libcore.os.getsockoptInt(ds.getFileDescriptor$(),
+                    IPPROTO_IP, IP_MULTICAST_ALL) == 1;
+            assertFalse(multicastAllEnabled);
+        }
     }
 
     /**
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 302b505..261975a 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
@@ -310,14 +310,20 @@
         long startTime = System.currentTimeMillis();
         // We use a busy wait loop here since we cannot know when the ReferenceQueue
         // daemon will enqueue the cleared references on their internal reference
-        // queues. The current timeout is 5 seconds.
+        // queues.
+        // The timeout after which the reference should be cleared. This test used to
+        // be flaky when it was set to 5 seconds. Daemons.MAX_FINALIZE_NANOS is
+        // currently 10 seconds so that seems like the correct value.
+        // We allow an extra 500msec buffer to minimize races between finalizer,
+        // keySet.size() evaluation and time check.
+        long timeout = 10000 + 500;
         do {
             try {
                 Thread.sleep(100);
             } catch (InterruptedException e) {
             }
         } while (keySet.size() != 99 &&
-                 System.currentTimeMillis() - startTime < 5000);
+                 System.currentTimeMillis() - startTime < timeout);
 
         assertEquals("Incorrect number of keys returned after gc,", 99, keySet.size());
     }
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HandshakeCompletedEventTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HandshakeCompletedEventTest.java
index bb2265f..74c3a7f 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HandshakeCompletedEventTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HandshakeCompletedEventTest.java
@@ -25,6 +25,7 @@
 import java.security.KeyStore;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
+import java.util.Base64;
 import javax.net.ssl.HandshakeCompletedEvent;
 import javax.net.ssl.HandshakeCompletedListener;
 import javax.net.ssl.KeyManager;
@@ -39,7 +40,6 @@
 import javax.net.ssl.X509TrustManager;
 import javax.security.cert.X509Certificate;
 import junit.framework.TestCase;
-import libcore.io.Base64;
 import org.apache.harmony.xnet.tests.support.mySSLSession;
 
 /**
@@ -535,7 +535,7 @@
      * for the result.
      */
     private KeyManager[] getKeyManagers(String keys) throws Exception {
-        byte[] bytes = Base64.decode(keys.getBytes());
+        byte[] bytes = Base64.getDecoder().decode(keys.getBytes());
         InputStream inputStream = new ByteArrayInputStream(bytes);
 
         KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLServerSocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLServerSocketTest.java
index 5a0cf6f..117a1a0 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLServerSocketTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLServerSocketTest.java
@@ -18,8 +18,6 @@
 
 import junit.framework.TestCase;
 
-import libcore.io.Base64;
-
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -27,6 +25,7 @@
 import java.security.KeyStore;
 import java.security.SecureRandom;
 import java.util.Arrays;
+import java.util.Base64;
 
 import javax.net.ssl.KeyManager;
 import javax.net.ssl.KeyManagerFactory;
@@ -391,7 +390,7 @@
      */
     private KeyManager[] getKeyManagers() throws Exception {
         String keys = (useBKS ? SERVER_KEYS_BKS : SERVER_KEYS_JKS);
-        byte[] bytes = Base64.decode(keys.getBytes());
+        byte[] bytes = Base64.getDecoder().decode(keys.getBytes());
         InputStream inputStream = new ByteArrayInputStream(bytes);
 
         KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSessionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSessionTest.java
index 018de8c..fde1ff8 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSessionTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSessionTest.java
@@ -26,6 +26,7 @@
 import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
 import java.util.Arrays;
+import java.util.Base64;
 
 import javax.net.ssl.ExtendedSSLSession;
 import javax.net.ssl.KeyManager;
@@ -42,7 +43,6 @@
 import org.apache.harmony.tests.javax.net.ssl.HandshakeCompletedEventTest.TestTrustManager;
 
 import junit.framework.TestCase;
-import libcore.io.Base64;
 import libcore.java.security.StandardNames;
 
 public class SSLSessionTest extends TestCase {
@@ -643,7 +643,7 @@
      * for the result.
      */
     private KeyStore getKeyStore(String keys) throws Exception {
-        byte[] bytes = Base64.decode(keys.getBytes());
+        byte[] bytes = Base64.getDecoder().decode(keys.getBytes());
         InputStream inputStream = new ByteArrayInputStream(bytes);
 
         KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketTest.java
index a791a77..5712a48 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketTest.java
@@ -24,6 +24,7 @@
 import java.security.KeyStore;
 import java.security.SecureRandom;
 import java.util.Arrays;
+import java.util.Base64;
 import javax.net.ssl.HandshakeCompletedEvent;
 import javax.net.ssl.HandshakeCompletedListener;
 import javax.net.ssl.KeyManager;
@@ -35,7 +36,6 @@
 import javax.net.ssl.TrustManager;
 import javax.security.cert.X509Certificate;
 import junit.framework.TestCase;
-import libcore.io.Base64;
 import libcore.java.security.StandardNames;
 import org.apache.harmony.tests.javax.net.ssl.HandshakeCompletedEventTest.TestTrustManager;
 
@@ -587,7 +587,7 @@
      * for the result.
      */
     private KeyManager[] getKeyManagers(String keys) throws Exception {
-        byte[] bytes = Base64.decode(keys.getBytes());
+        byte[] bytes = Base64.getDecoder().decode(keys.getBytes());
         InputStream inputStream = new ByteArrayInputStream(bytes);
 
         KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
diff --git a/libart/src/main/java/dalvik/system/ClassExt.java b/libart/src/main/java/dalvik/system/ClassExt.java
index a23529b..131124e 100644
--- a/libart/src/main/java/dalvik/system/ClassExt.java
+++ b/libart/src/main/java/dalvik/system/ClassExt.java
@@ -27,8 +27,44 @@
  */
 public final class ClassExt {
     /**
+     * An array of all obsolete DexCache objects that are needed for obsolete methods.
+     *
+     * These entries are associated with the obsolete ArtMethod pointers at the same indexes in the
+     * obsoleteMethods array.
+     *
+     * This field has native components and is a logical part of the 'Class' type.
+     */
+    private Object[] obsoleteDexCaches;
+
+    /**
+     * An array of all native obsolete ArtMethod pointers.
+     *
+     * These are associated with their DexCaches at the same index in the obsoleteDexCaches array.
+     *
+     * This field is actually either an int[] or a long[] depending on size of a pointer.
+     *
+     * This field contains native pointers and is a logical part of the 'Class' type.
+     */
+    private Object obsoleteMethods;
+
+    /**
+     * If set, the original DexCache associated with the related class.
+     *
+     * In this instance 'original' means the dex-cache (and associated dex-file) for this class when
+     * it was first loaded after all non-retransformation capable transformations had been performed
+     * but before any retransformation capable ones had been done.
+     *
+     * Needed in order to implement retransformation of classes.
+     *
+     * This field has native components and is a logical part of the 'Class' type.
+     */
+    private Object originalDexCache;
+
+    /**
      * If class verify fails, we must return same error on subsequent tries. We may store either
      * the class of the error, or an actual instance of Throwable here.
+     *
+     * This field is a logical part of the 'Class' type.
      */
     private Object verifyError;
 
diff --git a/luni/src/main/java/android/system/OsConstants.java b/luni/src/main/java/android/system/OsConstants.java
index 28b2523..96846ca 100644
--- a/luni/src/main/java/android/system/OsConstants.java
+++ b/luni/src/main/java/android/system/OsConstants.java
@@ -313,6 +313,7 @@
     public static final int IPV6_TCLASS = placeholder();
     public static final int IPV6_UNICAST_HOPS = placeholder();
     public static final int IPV6_V6ONLY = placeholder();
+    /** @hide */ public static final int IP_MULTICAST_ALL = placeholder();
     public static final int IP_MULTICAST_IF = placeholder();
     public static final int IP_MULTICAST_LOOP = placeholder();
     public static final int IP_MULTICAST_TTL = placeholder();
diff --git a/luni/src/main/java/java/lang/ref/FinalizerReference.java b/luni/src/main/java/java/lang/ref/FinalizerReference.java
index 02cfa01..91c3197 100644
--- a/luni/src/main/java/java/lang/ref/FinalizerReference.java
+++ b/luni/src/main/java/java/lang/ref/FinalizerReference.java
@@ -100,7 +100,10 @@
             // We search the list for that FinalizerReference (it should be at or near the head),
             // and then put it on the queue so that it can be finalized.
             for (FinalizerReference<?> r = head; r != null; r = r.next) {
-                if (r.referent == sentinel) {
+                // Use getReferent() instead of directly accessing the referent field not to race
+                // with GC reference processing. Can't use get() either because it's overridden to
+                // return the zombie.
+                if (r.getReferent() == sentinel) {
                     FinalizerReference<Sentinel> sentinelReference = (FinalizerReference<Sentinel>) r;
                     sentinelReference.referent = null;
                     sentinelReference.zombie = sentinel;
@@ -126,6 +129,7 @@
         throw new AssertionError("newly-created live Sentinel not on list!");
     }
 
+    private final native T getReferent();
     private native boolean makeCircularListIfUnenqueued();
 
     /**
diff --git a/luni/src/main/java/libcore/io/Base64.java b/luni/src/main/java/libcore/io/Base64.java
deleted file mode 100644
index f22bef4..0000000
--- a/luni/src/main/java/libcore/io/Base64.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package libcore.io;
-
-import java.io.ByteArrayOutputStream;
-import java.nio.charset.StandardCharsets;
-
-/**
- * Perform encoding and decoding of Base64 byte arrays as described in
- * http://www.ietf.org/rfc/rfc2045.txt
- *
- * @deprecated use {@link java.util.Base64} instead
- */
-@Deprecated
-public final class Base64 {
-    private static final byte[] BASE_64_ALPHABET = initializeBase64Alphabet();
-
-    private static byte[] initializeBase64Alphabet() {
-        return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
-                    .getBytes(StandardCharsets.US_ASCII);
-    }
-
-    // Bit masks for the 4 output 6-bit values from 3 input bytes.
-    private static final int FIRST_OUTPUT_BYTE_MASK = 0x3f << 18;
-    private static final int SECOND_OUTPUT_BYTE_MASK = 0x3f << 12;
-    private static final int THIRD_OUTPUT_BYTE_MASK = 0x3f << 6;
-    private static final int FOURTH_OUTPUT_BYTE_MASK = 0x3f;
-
-    private Base64() {}
-
-    public static String encode(byte[] in) {
-        int len = in.length;
-        int outputLen = computeEncodingOutputLen(len);
-        byte[] output = new byte[outputLen];
-
-        int outputIndex = 0;
-        for (int i = 0; i < len; i += 3) {
-            // Only a "triplet" if there are there are at least three remaining bytes
-            // in the input...
-            // Mask with 0xff to avoid signed extension.
-            int byteTripletAsInt = in[i] & 0xff;
-            if (i + 1 < len) {
-                // Add second byte to the triplet.
-                byteTripletAsInt <<= 8;
-                byteTripletAsInt |= in[i + 1] & 0xff;
-                if (i + 2 < len) {
-                    byteTripletAsInt <<= 8;
-                    byteTripletAsInt |= in[i + 2] & 0xff;
-                } else {
-                    // Insert 2 zero bits as to make output 18 bits long.
-                    byteTripletAsInt <<= 2;
-                }
-            } else {
-                // Insert 4 zero bits as to make output 12 bits long.
-                byteTripletAsInt <<= 4;
-            }
-
-            if (i + 2 < len) {
-                // The int may have up to 24 non-zero bits.
-                output[outputIndex++] = BASE_64_ALPHABET[
-                        (byteTripletAsInt & FIRST_OUTPUT_BYTE_MASK) >>> 18];
-            }
-            if (i + 1 < len) {
-                // The int may have up to 18 non-zero bits.
-                output[outputIndex++] = BASE_64_ALPHABET[
-                        (byteTripletAsInt & SECOND_OUTPUT_BYTE_MASK) >>> 12];
-            }
-            output[outputIndex++] = BASE_64_ALPHABET[
-                    (byteTripletAsInt & THIRD_OUTPUT_BYTE_MASK) >>> 6];
-            output[outputIndex++] = BASE_64_ALPHABET[
-                    byteTripletAsInt & FOURTH_OUTPUT_BYTE_MASK];
-        }
-
-        int inLengthMod3 = len % 3;
-        // Add padding as per the spec.
-        if (inLengthMod3 > 0) {
-            output[outputIndex++] = '=';
-            if (inLengthMod3 == 1) {
-                output[outputIndex++] = '=';
-            }
-        }
-
-        return new String(output, StandardCharsets.US_ASCII);
-    }
-
-    private static int computeEncodingOutputLen(int inLength) {
-        int inLengthMod3 = inLength % 3;
-        int outputLen = (inLength / 3) * 4;
-        if (inLengthMod3 == 2) {
-            // Need 3 6-bit characters as to express the last 16 bits, plus 1 padding.
-            outputLen += 4;
-        } else if (inLengthMod3 == 1) {
-            // Need 2 6-bit characters as to express the last 8 bits, plus 2 padding.
-            outputLen += 4;
-        }
-        return outputLen;
-    }
-
-    public static byte[] decode(byte[] in) {
-        return decode(in, in.length);
-    }
-
-    /** Decodes the input from position 0 (inclusive) to len (exclusive). */
-    public static byte[] decode(byte[] in, int len) {
-        final int inLength = Math.min(in.length, len);
-        // Overestimating 3 bytes per each 4 blocks of input (plus a possibly incomplete one).
-        ByteArrayOutputStream output = new ByteArrayOutputStream((inLength / 4) * 3 + 3);
-        // Position in the input. Use an array so we can pass it to {@code getNextByte}.
-        int[] pos = new int[1];
-
-        try {
-            while (pos[0] < inLength) {
-                int byteTripletAsInt = 0;
-
-                // j is the index in a 4-tuple of 6-bit characters where are trying to read from the
-                // input.
-                for (int j = 0; j < 4; j++) {
-                    byte c = getNextByte(in, pos, inLength);
-                    if (c == END_OF_INPUT || c == PAD_AS_BYTE) {
-                        // Padding or end of file...
-                        switch (j) {
-                            case 0:
-                            case 1:
-                                return (c == END_OF_INPUT) ? output.toByteArray() : null;
-                            case 2:
-                                // The input is over with two 6-bit characters: a single byte padded
-                                // with 4 extra 0's.
-
-                                if (c == END_OF_INPUT) {
-                                    // Do not consider the block, since padding is not present.
-                                    return checkNoTrailingAndReturn(output, in, pos[0], inLength);
-                                }
-                                // We are at a pad character, consume and look for the second one.
-                                pos[0]++;
-                                c = getNextByte(in, pos, inLength);
-                                if (c == END_OF_INPUT) {
-                                    // Do not consider the block, since padding is not present.
-                                    return checkNoTrailingAndReturn(output, in, pos[0], inLength);
-                                }
-                                if (c == PAD_AS_BYTE) {
-                                    byteTripletAsInt >>= 4;
-                                    output.write(byteTripletAsInt);
-                                    return checkNoTrailingAndReturn(output, in, pos[0], inLength);
-                                }
-                                // Something other than pad and non-alphabet characters, illegal.
-                                return null;
-
-
-                            case 3:
-                                // The input is over with three 6-bit characters: two bytes padded
-                                // with 2 extra 0's.
-                                if (c == PAD_AS_BYTE) {
-                                    // Consider the block only if padding is present.
-                                    byteTripletAsInt >>= 2;
-                                    output.write(byteTripletAsInt >> 8);
-                                    output.write(byteTripletAsInt & 0xff);
-                                }
-                                return checkNoTrailingAndReturn(output, in, pos[0], inLength);
-                        }
-                    } else {
-                        byteTripletAsInt <<= 6;
-                        byteTripletAsInt += (c & 0xff);
-                        pos[0]++;
-                    }
-                }
-                // We have four 6-bit characters: output the corresponding 3 bytes
-                output.write(byteTripletAsInt >> 16);
-                output.write((byteTripletAsInt >> 8) & 0xff);
-                output.write(byteTripletAsInt & 0xff);
-            }
-            return checkNoTrailingAndReturn(output, in, pos[0], inLength);
-        } catch (InvalidBase64ByteException e) {
-            return null;
-        }
-    }
-
-    /**
-     * On decoding, an illegal character always return null.
-     *
-     * Using this exception to avoid "if" checks every time.
-     */
-
-    private static class InvalidBase64ByteException extends Exception { }
-
-    /**
-     * Obtain the numeric value corresponding to the next relevant byte in the input.
-     *
-     * Calculates the numeric value (6-bit, 0 <= x <= 63) of the next Base64 encoded byte in
-     * {@code in} at or after {@code pos[0]} and before {@code inLength}. Returns
-     * {@link #WHITESPACE_AS_BYTE}, {@link #PAD_AS_BYTE}, {@link #END_OF_INPUT} or the 6-bit value.
-     * {@code pos[0]} is updated as a side effect of this method.
-     */
-    private static byte getNextByte(byte[] in, int[] pos, int inLength)
-            throws InvalidBase64ByteException {
-        // Ignore all whitespace.
-        while (pos[0] < inLength) {
-            byte c = base64AlphabetToNumericalValue(in[pos[0]]);
-            if (c != WHITESPACE_AS_BYTE) {
-                return c;
-            }
-            pos[0]++;
-        }
-        return END_OF_INPUT;
-    }
-
-    /**
-     * Check that there are no invalid trailing characters (ie, other then whitespace and padding)
-     *
-     * Returns {@code output} as a byte array in case of success, {@code null} in case of invalid
-     * characters.
-     */
-    private static byte[] checkNoTrailingAndReturn(
-            ByteArrayOutputStream output, byte[] in, int i, int inLength)
-                    throws InvalidBase64ByteException{
-        while (i < inLength) {
-            byte c = base64AlphabetToNumericalValue(in[i]);
-            if (c != WHITESPACE_AS_BYTE && c != PAD_AS_BYTE) {
-                return null;
-            }
-            i++;
-        }
-        return output.toByteArray();
-    }
-
-    private static final byte PAD_AS_BYTE = -1;
-    private static final byte WHITESPACE_AS_BYTE = -2;
-    private static final byte END_OF_INPUT = -3;
-    private static byte base64AlphabetToNumericalValue(byte c) throws InvalidBase64ByteException {
-        if ('A' <= c && c <= 'Z') {
-            return (byte) (c - 'A');
-        }
-        if ('a' <= c && c <= 'z') {
-            return (byte) (c - 'a' + 26);
-        }
-        if ('0' <= c && c <= '9') {
-            return (byte) (c - '0' + 52);
-        }
-        if (c == '+') {
-            return (byte) 62;
-        }
-        if (c == '/') {
-            return (byte) 63;
-        }
-        if (c == '=') {
-            return PAD_AS_BYTE;
-        }
-        if (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
-            return WHITESPACE_AS_BYTE;
-        }
-        throw new InvalidBase64ByteException();
-    }
-}
diff --git a/luni/src/main/java/libcore/io/DropBox.java b/luni/src/main/java/libcore/io/DropBox.java
index cf88106..4180a2a 100644
--- a/luni/src/main/java/libcore/io/DropBox.java
+++ b/luni/src/main/java/libcore/io/DropBox.java
@@ -16,6 +16,8 @@
 
 package libcore.io;
 
+import java.util.Base64;
+
 public final class DropBox {
 
     /**
@@ -54,7 +56,7 @@
     private static final class DefaultReporter implements Reporter {
 
         public void addData(String tag, byte[] data, int flags) {
-            System.out.println(tag + ": " + Base64.encode(data));
+            System.out.println(tag + ": " + Base64.getEncoder().encodeToString(data));
         }
 
         public void addText(String tag, String data) {
diff --git a/luni/src/main/java/libcore/io/IoBridge.java b/luni/src/main/java/libcore/io/IoBridge.java
index f5177fd..e5d1930 100644
--- a/luni/src/main/java/libcore/io/IoBridge.java
+++ b/luni/src/main/java/libcore/io/IoBridge.java
@@ -35,7 +35,6 @@
 import java.net.InetSocketAddress;
 import java.net.NetworkInterface;
 import java.net.PortUnreachableException;
-import java.net.SocketAddress;
 import java.net.SocketException;
 import java.net.SocketOptions;
 import java.net.SocketTimeoutException;
@@ -645,6 +644,29 @@
         }
     }
 
+    /**
+     * Wait for some event on a file descriptor, blocks until the event happened or timeout period
+     * passed. See poll(2) and @link{android.system.Os.Poll}.
+     *
+     * @throws SocketException if poll(2) fails.
+     * @throws SocketTimeoutException if the event has not happened before timeout period has passed.
+     */
+    public static void poll(FileDescriptor fd, int events, int timeout)
+            throws SocketException, SocketTimeoutException {
+        StructPollfd[] pollFds = new StructPollfd[]{ new StructPollfd() };
+        pollFds[0].fd = fd;
+        pollFds[0].events = (short) events;
+
+        try {
+            int ret = android.system.Os.poll(pollFds, timeout);
+            if (ret == 0) {
+                throw new SocketTimeoutException("Poll timed out");
+            }
+        } catch (ErrnoException e) {
+            e.rethrowAsSocketException();
+        }
+    }
+
     public static InetSocketAddress getLocalInetSocketAddress(FileDescriptor fd) throws SocketException {
         try {
             return (InetSocketAddress) Libcore.os.getsockname(fd);
diff --git a/luni/src/main/java/libcore/util/ZoneInfoDB.java b/luni/src/main/java/libcore/util/ZoneInfoDB.java
index c53db12..e6559b5 100644
--- a/luni/src/main/java/libcore/util/ZoneInfoDB.java
+++ b/luni/src/main/java/libcore/util/ZoneInfoDB.java
@@ -37,8 +37,8 @@
  * @hide - used to implement TimeZone
  */
 public final class ZoneInfoDB {
-  private static final TzData DATA =
-      new TzData(System.getenv("ANDROID_DATA") + "/misc/zoneinfo/current/tzdata",
+  private static final TzData DATA = TzData.loadTzDataWithFallback(
+          System.getenv("ANDROID_DATA") + "/misc/zoneinfo/current/tzdata",
           System.getenv("ANDROID_ROOT") + "/usr/share/zoneinfo/tzdata");
 
   public static class TzData {
@@ -83,10 +83,16 @@
       }
     };
 
-    public TzData(String... paths) {
+    /**
+     * Loads the data at the specified paths in order, returning the first valid one as a
+     * {@link TzData} object. If there is no valid one found a basic fallback instance is created
+     * containing just GMT.
+     */
+    public static TzData loadTzDataWithFallback(String... paths) {
       for (String path : paths) {
-        if (loadData(path)) {
-          return;
+        TzData tzData = new TzData();
+        if (tzData.loadData(path)) {
+          return tzData;
         }
       }
 
@@ -94,10 +100,28 @@
       // This is actually implemented in TimeZone itself, so if this is the only time zone
       // we report, we won't be asked any more questions.
       System.logE("Couldn't find any tzdata!");
-      version = "missing";
-      zoneTab = "# Emergency fallback data.\n";
-      ids = new String[] { "GMT" };
-      byteOffsets = rawUtcOffsetsCache = new int[1];
+      return TzData.createFallback();
+    }
+
+    /**
+     * Loads the data at the specified path and returns the {@link TzData} object if it is valid,
+     * otherwise {@code null}.
+     */
+    public static TzData loadTzData(String path) {
+      TzData tzData = new TzData();
+      if (tzData.loadData(path)) {
+        return tzData;
+      }
+      return null;
+    }
+
+    private static TzData createFallback() {
+      TzData tzData = new TzData();
+      tzData.populateFallback();
+      return tzData;
+    }
+
+    private TzData() {
     }
 
     /**
@@ -115,6 +139,13 @@
       return it;
     }
 
+    private void populateFallback() {
+      version = "missing";
+      zoneTab = "# Emergency fallback data.\n";
+      ids = new String[] { "GMT" };
+      byteOffsets = rawUtcOffsetsCache = new int[1];
+    }
+
     private boolean loadData(String path) {
       try {
         mappedFile = MemoryMappedFile.mmapRO(path);
@@ -125,6 +156,11 @@
         readHeader();
         return true;
       } catch (Exception ex) {
+        try {
+          mappedFile.close();
+        } catch (ErrnoException ignored) {
+        }
+
         // Something's wrong with the file.
         // Log the problem and return false so we try the next choice.
         System.logE("tzdata file \"" + path + "\" was present but invalid!", ex);
diff --git a/luni/src/main/native/android_system_OsConstants.cpp b/luni/src/main/native/android_system_OsConstants.cpp
index 7334420..a8b2c2f 100644
--- a/luni/src/main/native/android_system_OsConstants.cpp
+++ b/luni/src/main/native/android_system_OsConstants.cpp
@@ -335,6 +335,7 @@
 #endif
     initConstant(env, c, "IPV6_UNICAST_HOPS", IPV6_UNICAST_HOPS);
     initConstant(env, c, "IPV6_V6ONLY", IPV6_V6ONLY);
+    initConstant(env, c, "IP_MULTICAST_ALL", IP_MULTICAST_ALL);
     initConstant(env, c, "IP_MULTICAST_IF", IP_MULTICAST_IF);
     initConstant(env, c, "IP_MULTICAST_LOOP", IP_MULTICAST_LOOP);
     initConstant(env, c, "IP_MULTICAST_TTL", IP_MULTICAST_TTL);
diff --git a/luni/src/main/native/java_lang_StringToReal.cpp b/luni/src/main/native/java_lang_StringToReal.cpp
index d1902af..c321702 100644
--- a/luni/src/main/native/java_lang_StringToReal.cpp
+++ b/luni/src/main/native/java_lang_StringToReal.cpp
@@ -286,6 +286,7 @@
       free(y);
       free(D);
       free(D2);
+      y = D = D2 = NULL;
 
       if (e >= 0 && k >= 0)
         {
@@ -713,6 +714,7 @@
       free(y);
       free(D);
       free(D2);
+      y = D = D2 = NULL;
 
       if (e >= 0 && k >= 0)
         {
diff --git a/luni/src/test/java/libcore/java/nio/BufferTest.java b/luni/src/test/java/libcore/java/nio/BufferTest.java
index 9a2cb12..9063e27 100644
--- a/luni/src/test/java/libcore/java/nio/BufferTest.java
+++ b/luni/src/test/java/libcore/java/nio/BufferTest.java
@@ -1429,4 +1429,41 @@
         assertFalse(bigEndian.asFloatBuffer().slice().get() ==
                 littleEndian.asFloatBuffer().slice().get());
     }
+
+    // http://b/32655865
+    public void test_ByteBufferAsXBuffer_ByteOrder_2() {
+        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(10);
+        byteBuffer.order(ByteOrder.BIG_ENDIAN);
+        // Fill a ByteBuffer with different bytes that make it easy to tell byte ordering issues.
+        for (int i = 0; i < 10; i++) {
+            byteBuffer.put((byte)i);
+        }
+        byteBuffer.rewind();
+
+        // Create BIG_ENDIAN views of the buffer.
+        ShortBuffer sb_be = byteBuffer.asShortBuffer();
+        LongBuffer lb_be = byteBuffer.asLongBuffer();
+        IntBuffer ib_be = byteBuffer.asIntBuffer();
+        DoubleBuffer db_be = byteBuffer.asDoubleBuffer();
+        CharBuffer cb_be = byteBuffer.asCharBuffer();
+        FloatBuffer fb_be = byteBuffer.asFloatBuffer();
+
+        // Change the order of the underlying buffer.
+        byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
+
+        // Create LITTLE_ENDIAN views of the buffer.
+        ShortBuffer sb_le = byteBuffer.asShortBuffer();
+        LongBuffer lb_le = byteBuffer.asLongBuffer();
+        IntBuffer ib_le = byteBuffer.asIntBuffer();
+        DoubleBuffer db_le = byteBuffer.asDoubleBuffer();
+        CharBuffer cb_le = byteBuffer.asCharBuffer();
+        FloatBuffer fb_le = byteBuffer.asFloatBuffer();
+
+        assertFalse(sb_be.get() == sb_le.get());
+        assertFalse(lb_be.get() == lb_le.get());
+        assertFalse(ib_be.get() == ib_le.get());
+        assertFalse(db_be.get() == db_le.get());
+        assertFalse(cb_be.get() == cb_le.get());
+        assertFalse(fb_be.get() == fb_le.get());
+    }
 }
diff --git a/luni/src/test/java/libcore/java/nio/channels/DatagramChannelMulticastTest.java b/luni/src/test/java/libcore/java/nio/channels/DatagramChannelMulticastTest.java
index 52146ee..ae45c0d 100644
--- a/luni/src/test/java/libcore/java/nio/channels/DatagramChannelMulticastTest.java
+++ b/luni/src/test/java/libcore/java/nio/channels/DatagramChannelMulticastTest.java
@@ -18,7 +18,6 @@
 
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
@@ -28,6 +27,7 @@
 import java.net.NetworkInterface;
 import java.net.SocketAddress;
 import java.net.SocketException;
+import java.net.SocketTimeoutException;
 import java.net.StandardSocketOptions;
 import java.nio.ByteBuffer;
 import java.nio.channels.ClosedChannelException;
@@ -36,6 +36,10 @@
 import java.util.ArrayList;
 import java.util.Enumeration;
 
+import libcore.io.IoBridge;
+
+import static android.system.OsConstants.POLLIN;
+
 /**
  * Tests associated with multicast behavior of DatagramChannel.
  * These tests require IPv6 multicasting enabled network.
@@ -774,6 +778,7 @@
         // Send a message. It should be received.
         String msg1 = "Hello1";
         sendMessage(sendingChannel, msg1, groupSocketAddress);
+        IoBridge.poll(receivingChannel.socket().getFileDescriptor$(), POLLIN, 1000);
         InetSocketAddress sourceAddress1 = (InetSocketAddress) receivingChannel.receive(receiveBuffer);
         assertEquals(sourceAddress1, sendingAddress);
         assertEquals(msg1, new String(receiveBuffer.array(), 0, receiveBuffer.position()));
@@ -784,6 +789,10 @@
         // Send a message. It should be filtered.
         String msg2 = "Hello2";
         sendMessage(sendingChannel, msg2, groupSocketAddress);
+        try {
+            IoBridge.poll(receivingChannel.socket().getFileDescriptor$(), POLLIN, 1000);
+            fail();
+        } catch (SocketTimeoutException expected) { }
         receiveBuffer.position(0);
         InetSocketAddress sourceAddress2 = (InetSocketAddress) receivingChannel.receive(receiveBuffer);
         assertNull(sourceAddress2);
@@ -794,6 +803,7 @@
         // Send a message. It should be received.
         String msg3 = "Hello3";
         sendMessage(sendingChannel, msg3, groupSocketAddress);
+        IoBridge.poll(receivingChannel.socket().getFileDescriptor$(), POLLIN, 1000);
         receiveBuffer.position(0);
         InetSocketAddress sourceAddress3 = (InetSocketAddress) receivingChannel.receive(receiveBuffer);
         assertEquals(sourceAddress3, sendingAddress);
@@ -1236,6 +1246,5 @@
         }
         throw new AssertionFailedError("Unable to find local IPv6 address for " + networkInterface);
     }
-
 }
 
diff --git a/luni/src/test/java/libcore/java/util/FormatterTest.java b/luni/src/test/java/libcore/java/util/FormatterTest.java
index e87fee5..aed9ca0 100644
--- a/luni/src/test/java/libcore/java/util/FormatterTest.java
+++ b/luni/src/test/java/libcore/java/util/FormatterTest.java
@@ -17,7 +17,11 @@
 package libcore.java.util;
 
 import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
 import java.util.Calendar;
+import java.util.Formatter;
 import java.util.GregorianCalendar;
 import java.util.Locale;
 import java.util.TimeZone;
@@ -183,4 +187,24 @@
       assertEquals(expected, String.format(Locale.US, "%t" + pattern, c));
       assertEquals(expected, String.format(Locale.US, "%T" + pattern, c));
     }
+
+    // http://b/33245708: Some locales have a group separator != '\0' but a default decimal format
+    // pattern without grouping (e.g. a group size of zero). This would throw divide by zero when
+    // working out where to place the separator.
+    public void testGroupingSizeZero() {
+        Locale localeWithoutGrouping = new Locale("hy");
+        DecimalFormat decimalFormat =
+                (DecimalFormat) NumberFormat.getInstance(localeWithoutGrouping);
+
+        // Confirm the locale is still a good example: it has a group separator, but no grouping in
+        // the default decimal format.
+        assertEquals(0, decimalFormat.getGroupingSize());
+        assertFalse(decimalFormat.isGroupingUsed());
+        DecimalFormatSymbols symbols = decimalFormat.getDecimalFormatSymbols();
+        assertTrue(symbols.getGroupingSeparator() != '\0');
+
+        Formatter formatter = new Formatter(localeWithoutGrouping);
+        formatter.format("%,d", 123456789);
+        // No exception expected
+    }
 }
diff --git a/luni/src/test/java/libcore/io/Base64Test.java b/luni/src/test/java/libcore/java/util/LibcoreIoDerivedBase64Test.java
similarity index 78%
rename from luni/src/test/java/libcore/io/Base64Test.java
rename to luni/src/test/java/libcore/java/util/LibcoreIoDerivedBase64Test.java
index 6cfe186..2a888f7 100644
--- a/luni/src/test/java/libcore/io/Base64Test.java
+++ b/luni/src/test/java/libcore/java/util/LibcoreIoDerivedBase64Test.java
@@ -15,7 +15,7 @@
  *  limitations under the License.
  */
 
-package libcore.io;
+package libcore.java.util;
 
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
@@ -26,10 +26,16 @@
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 
+import java.util.Base64;
+import java.util.Base64.Decoder;
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
-public final class Base64Test extends TestCase {
+/**
+ * Additional tests for {@link java.util.Base64} derived from old tests for
+ * the removed class {@code libcore.io.Base64}.
+ */
+public final class LibcoreIoDerivedBase64Test extends TestCase {
 
     public void testEncodeDecode() throws Exception {
         assertEncodeDecode("");
@@ -59,7 +65,7 @@
         for (int i = 0; i < toEncode.length; i++) {
             inputBytes[i] = (byte) toEncode[i];
         }
-        String encoded = Base64.encode(inputBytes);
+        String encoded = encode(inputBytes);
         assertEquals(expectedEncoded, encoded);
 
         // Check we can round-trip the encoded bytes to
@@ -69,7 +75,7 @@
     }
 
     public void testDecode_empty() throws Exception {
-        byte[] decoded = Base64.decode(new byte[0]);
+        byte[] decoded = decode(new byte[0]);
         assertEquals(0, decoded.length);
     }
 
@@ -78,26 +84,26 @@
         assertEquals("hello, world", decodeToString("aGVsbG8sIHdvcmxk"));
 
         // The following are missing the final bytes
-        assertEquals("hello, wo", decodeToString("aGVsbG8sIHdvcmx"));
-        assertEquals("hello, wo", decodeToString("aGVsbG8sIHdvcm"));
-        assertEquals("hello, wo", decodeToString("aGVsbG8sIHdvc"));
-        assertEquals("hello, wo", decodeToString("aGVsbG8sIHdv"));
+        assertEquals("hello, worl", decodeToString("aGVsbG8sIHdvcmx"));
+        assertEquals("hello, wor",  decodeToString("aGVsbG8sIHdvcm"));
+        assertEquals(null,          decodeToString("aGVsbG8sIHdvc"));
+        assertEquals("hello, wo",   decodeToString("aGVsbG8sIHdv"));
     }
 
     public void testDecode_extraChars() throws Exception {
         // Characters outside of alphabet before padding.
-        assertEquals("hello, world", decodeToString(" aGVsbG8sIHdvcmxk"));
-        assertEquals("hello, world", decodeToString("aGV sbG8sIHdvcmxk"));
-        assertEquals("hello, world", decodeToString("aGVsbG8sIHdvcmxk "));
+        assertEquals(null, decodeToString(" aGVsbG8sIHdvcmxk"));
+        assertEquals(null, decodeToString("aGV sbG8sIHdvcmxk"));
+        assertEquals(null, decodeToString("aGVsbG8sIHdvcmxk "));
         assertEquals(null, decodeToString("*aGVsbG8sIHdvcmxk"));
         assertEquals(null, decodeToString("aGV*sbG8sIHdvcmxk"));
         assertEquals(null, decodeToString("aGVsbG8sIHdvcmxk*"));
-        assertEquals("hello, world", decodeToString("\r\naGVsbG8sIHdvcmxk"));
-        assertEquals("hello, world", decodeToString("aGV\r\nsbG8sIHdvcmxk"));
-        assertEquals("hello, world", decodeToString("aGVsbG8sIHdvcmxk\r\n"));
-        assertEquals("hello, world", decodeToString("\naGVsbG8sIHdvcmxk"));
-        assertEquals("hello, world", decodeToString("aGV\nsbG8sIHdvcmxk"));
-        assertEquals("hello, world", decodeToString("aGVsbG8sIHdvcmxk\n"));
+        assertEquals(null, decodeToString("\r\naGVsbG8sIHdvcmxk"));
+        assertEquals(null, decodeToString("aGV\r\nsbG8sIHdvcmxk"));
+        assertEquals(null, decodeToString("aGVsbG8sIHdvcmxk\r\n"));
+        assertEquals(null, decodeToString("\naGVsbG8sIHdvcmxk"));
+        assertEquals(null, decodeToString("aGV\nsbG8sIHdvcmxk"));
+        assertEquals(null, decodeToString("aGVsbG8sIHdvcmxk\n"));
 
         // padding 0
         assertEquals("hello, world", decodeToString("aGVsbG8sIHdvcmxk"));
@@ -111,49 +117,49 @@
         // padding 1
         assertEquals("hello, world?!", decodeToString("aGVsbG8sIHdvcmxkPyE="));
         // Missing padding
-        assertEquals("hello, world", decodeToString("aGVsbG8sIHdvcmxkPyE"));
+        assertEquals("hello, world?!", decodeToString("aGVsbG8sIHdvcmxkPyE"));
         // Characters outside alphabet before padding.
-        assertEquals("hello, world?!", decodeToString("aGVsbG8sIHdvcmxkPyE ="));
+        assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkPyE ="));
         assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkPyE*="));
         // Trailing characters, otherwise valid.
-        assertEquals("hello, world?!", decodeToString("aGVsbG8sIHdvcmxkPyE= "));
+        assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkPyE= "));
         assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkPyE=*"));
         assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkPyE=X"));
         assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkPyE=XY"));
         assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkPyE=XYZ"));
         assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkPyE=XYZA"));
-        assertEquals("hello, world?!", decodeToString("aGVsbG8sIHdvcmxkPyE=\n"));
-        assertEquals("hello, world?!", decodeToString("aGVsbG8sIHdvcmxkPyE=\r\n"));
-        assertEquals("hello, world?!", decodeToString("aGVsbG8sIHdvcmxkPyE= "));
-        assertEquals("hello, world?!", decodeToString("aGVsbG8sIHdvcmxkPyE=="));
+        assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkPyE=\n"));
+        assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkPyE=\r\n"));
+        assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkPyE= "));
+        assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkPyE=="));
         // Whitespace characters outside alphabet intermixed with (too much) padding.
-        assertEquals("hello, world?!", decodeToString("aGVsbG8sIHdvcmxkPyE =="));
-        assertEquals("hello, world?!", decodeToString("aGVsbG8sIHdvcmxkPyE = = "));
+        assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkPyE =="));
+        assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkPyE = = "));
 
         // padding 2
         assertEquals("hello, world.", decodeToString("aGVsbG8sIHdvcmxkLg=="));
         // Missing padding
-        assertEquals("hello, world", decodeToString("aGVsbG8sIHdvcmxkLg"));
+        assertEquals("hello, world.", decodeToString("aGVsbG8sIHdvcmxkLg"));
         // Partially missing padding
-        assertEquals("hello, world", decodeToString("aGVsbG8sIHdvcmxkLg="));
+        assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkLg="));
         // Characters outside alphabet before padding.
-        assertEquals("hello, world.", decodeToString("aGVsbG8sIHdvcmxkLg =="));
+        assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkLg =="));
         assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkLg*=="));
         // Trailing characters, otherwise valid.
-        assertEquals("hello, world.", decodeToString("aGVsbG8sIHdvcmxkLg== "));
+        assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkLg== "));
         assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkLg==*"));
         assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkLg==X"));
         assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkLg==XY"));
         assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkLg==XYZ"));
         assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkLg==XYZA"));
-        assertEquals("hello, world.", decodeToString("aGVsbG8sIHdvcmxkLg==\n"));
-        assertEquals("hello, world.", decodeToString("aGVsbG8sIHdvcmxkLg==\r\n"));
-        assertEquals("hello, world.", decodeToString("aGVsbG8sIHdvcmxkLg== "));
-        assertEquals("hello, world.", decodeToString("aGVsbG8sIHdvcmxkLg==="));
+        assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkLg==\n"));
+        assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkLg==\r\n"));
+        assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkLg== "));
+        assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkLg==="));
         // Characters outside alphabet inside padding.
-        assertEquals("hello, world.", decodeToString("aGVsbG8sIHdvcmxkLg= ="));
+        assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkLg= ="));
         assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkLg=*="));
-        assertEquals("hello, world.", decodeToString("aGVsbG8sIHdvcmxkLg=\r\n="));
+        assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkLg=\r\n="));
         // Characters inside alphabet inside padding.
         assertEquals(null, decodeToString("aGVsbG8sIHdvcmxkLg=X="));
 
@@ -206,7 +212,7 @@
      */
     private static String decodeToString(String in) throws Exception {
         byte[] bytes = asciiToBytes(in);
-        byte[] out = Base64.decode(bytes);
+        byte[] out = decode(bytes);
         if (out == null) {
             return null;
         }
@@ -251,10 +257,23 @@
 
     /** Decodes an ASCII string, returning an int array. */
     private static int[] decodeToInts(String in) throws Exception {
-        byte[] bytes = Base64.decode(asciiToBytes(in));
+        byte[] bytes = decode(asciiToBytes(in));
         return bytesToInts(bytes);
     }
 
+    private static byte[] decode(byte[] encoded) {
+        Decoder decoder = Base64.getDecoder();
+        try {
+            return decoder.decode(encoded);
+        } catch (IllegalArgumentException e) {
+            return null;
+        }
+    }
+
+    private static String encode(byte[] data) {
+        return Base64.getEncoder().encodeToString(data);
+    }
+
     /**
      * Convert a byte[] to an int[]. int is used because it is more convenient to use ints in
      * tests.
@@ -270,16 +289,6 @@
         return ints;
     }
 
-    /** Assert that decoding 'in' throws ArrayIndexOutOfBoundsException. */
-    private static void assertDecodeBad(String in) throws Exception {
-        try {
-            byte[] result = Base64.decode(asciiToBytes(in));
-            fail("should have failed to decode. Actually received: " +
-                    (result == null ? result : Arrays.toString(bytesToInts(result))));
-        } catch (ArrayIndexOutOfBoundsException e) {
-        }
-    }
-
     private static void assertArrayEquals(int[] expected, int[] actual) {
         assertSubArrayEquals(expected, expected.length, actual);
     }
diff --git a/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java b/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java
index 4f5d658..5471b1f 100644
--- a/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java
+++ b/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java
@@ -120,6 +120,30 @@
         expectExceptionInDNConstructor("l=\\g0");
     }
 
+    public void testNegativeLen() {
+        try {
+            X500Principal p = new X500Principal(new byte[]{
+                    0x30, // DerValue.tag_Sequence read in DerValue#getSequence
+                    9,    // Length of the vector. read in readVector.
+                          // DerInputStream.getLength will just return this as 10 & 0x80 == 0
+                    -1,   // Tag of the first value in the sequencevalue. Convenient so that it
+                          // doesn't hold DerIndefLenConverter.isEOC()
+                    (byte) 0x80, // Encoding in indefinite form
+                    -1,          // Second tag to be read by DerIndefLenConverter
+                    (byte) 0x84, // Second length byte to be read, 0x80 means long form, 4 bytes
+                    (byte) 0xff, // Length to be read by DerIndefLenConverter, -6, will move the
+                                 // buffer position to the second tag
+                    (byte) 0xff,
+                    (byte) 0xff,
+                    (byte) -6,
+                    0,           // Needed as otherwise it's detected that there's nothing after
+                    // the length
+            });
+            fail("expected IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
     private void expectExceptionInDNConstructor(String dn) {
         try {
             X500Principal principal = new X500Principal(dn);
diff --git a/luni/src/test/java/libcore/sun/security/x509/AlgorithmIdTest.java b/luni/src/test/java/libcore/sun/security/x509/AlgorithmIdTest.java
index c2ab862..b20816f 100644
--- a/luni/src/test/java/libcore/sun/security/x509/AlgorithmIdTest.java
+++ b/luni/src/test/java/libcore/sun/security/x509/AlgorithmIdTest.java
@@ -48,6 +48,13 @@
                 "2.16.840.1.101.3.4.3.1", AlgorithmId.get("sHA224withDSA").getOID().toString());
         assertEquals(
                 "2.16.840.1.101.3.4.3.2", AlgorithmId.get("sHA256withDSA").getOID().toString());
+
+        // Used to be 2.16.840.1.101.3.4.42 until N because BouncyCastle accepts this alias. It
+        // started with a typo they once had and for compatibility they still support it. Since we
+        // scan the aliases, we were picking it as the canonical OID for AES. See:
+        // http://www.docjar.org/html/api/org/bouncycastle/jce/provider/symmetric/AESMappings.java.html
+        assertEquals("2.16.840.1.101.3.4.1", AlgorithmId.get("AES").getOID().toString());
+        assertEquals("1.3.132.1.12", AlgorithmId.get("ECDH").getOID().toString());
     }
 
     public void test_getName() throws Exception {
@@ -61,6 +68,15 @@
         assertEquals("SHA256withDSA", getOidName("2.16.840.1.101.3.4.3.2"));
         assertEquals("SHA224withRSA", getOidName("1.2.840.113549.1.1.14"));
 
+        assertEquals("AES", getOidName("2.16.840.1.101.3.4.1"));
+        // AES is also the result of 2.16.840.1.101.3.4.42 because BouncyCastle accepts this alias.
+        // It started with a typo they once had and for compatibility they still support it. Since
+        // we scan the aliases, we were picking it. See:
+        // http://www.docjar.org/html/api/org/bouncycastle/jce/provider/symmetric/AESMappings.java.html
+        assertEquals("AES", getOidName("2.16.840.1.101.3.4.42"));
+
+        // ECDH not present before and in N
+        assertEquals("ECDH", getOidName("1.3.132.1.12"));
     }
 
     private String getOidName(String oid) throws Exception {
diff --git a/luni/src/test/java/libcore/util/ZoneInfoDBTest.java b/luni/src/test/java/libcore/util/ZoneInfoDBTest.java
index 12ad0d7..7fa46d5 100644
--- a/luni/src/test/java/libcore/util/ZoneInfoDBTest.java
+++ b/luni/src/test/java/libcore/util/ZoneInfoDBTest.java
@@ -29,36 +29,38 @@
       System.getenv("ANDROID_ROOT") + "/usr/share/zoneinfo/tzdata";
 
   // An empty override file should fall back to the default file.
-  public void testEmptyOverrideFile() throws Exception {
-    ZoneInfoDB.TzData data = new ZoneInfoDB.TzData(TZDATA_IN_ROOT);
+  public void testLoadTzDataWithFallback_emptyOverrideFile() throws Exception {
+    ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(TZDATA_IN_ROOT);
     String emptyFilePath = makeEmptyFile().getPath();
+
     ZoneInfoDB.TzData dataWithEmptyOverride =
-        new ZoneInfoDB.TzData(emptyFilePath, TZDATA_IN_ROOT);
+        ZoneInfoDB.TzData.loadTzDataWithFallback(emptyFilePath, TZDATA_IN_ROOT);
     assertEquals(data.getVersion(), dataWithEmptyOverride.getVersion());
     assertEquals(data.getAvailableIDs().length, dataWithEmptyOverride.getAvailableIDs().length);
   }
 
   // A corrupt override file should fall back to the default file.
-  public void testCorruptOverrideFile() throws Exception {
-    ZoneInfoDB.TzData data = new ZoneInfoDB.TzData(TZDATA_IN_ROOT);
+  public void testLoadTzDataWithFallback_corruptOverrideFile() throws Exception {
+    ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(TZDATA_IN_ROOT);
     String corruptFilePath = makeCorruptFile().getPath();
+
     ZoneInfoDB.TzData dataWithCorruptOverride =
-        new ZoneInfoDB.TzData(corruptFilePath, TZDATA_IN_ROOT);
+        ZoneInfoDB.TzData.loadTzDataWithFallback(corruptFilePath, TZDATA_IN_ROOT);
     assertEquals(data.getVersion(), dataWithCorruptOverride.getVersion());
     assertEquals(data.getAvailableIDs().length, dataWithCorruptOverride.getAvailableIDs().length);
   }
 
   // Given no tzdata files we can use, we should fall back to built-in "GMT".
-  public void testNoGoodFile() throws Exception {
+  public void testLoadTzDataWithFallback_noGoodFile() throws Exception {
     String emptyFilePath = makeEmptyFile().getPath();
-    ZoneInfoDB.TzData data = new ZoneInfoDB.TzData(emptyFilePath);
+    ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzDataWithFallback(emptyFilePath);
     assertEquals("missing", data.getVersion());
     assertEquals(1, data.getAvailableIDs().length);
     assertEquals("GMT", data.getAvailableIDs()[0]);
   }
 
   // Given a valid override file, we should find ourselves using that.
-  public void testGoodOverrideFile() throws Exception {
+  public void testLoadTzDataWithFallback_goodOverrideFile() throws Exception {
     RandomAccessFile in = new RandomAccessFile(TZDATA_IN_ROOT, "r");
     byte[] content = new byte[(int) in.length()];
     in.readFully(content);
@@ -70,11 +72,11 @@
     content[10] = 'z';
     in.close();
 
-    ZoneInfoDB.TzData data = new ZoneInfoDB.TzData(TZDATA_IN_ROOT);
+    ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(TZDATA_IN_ROOT);
     File goodFile = makeTemporaryFile(content);
     try {
       ZoneInfoDB.TzData dataWithOverride =
-              new ZoneInfoDB.TzData(goodFile.getPath(), TZDATA_IN_ROOT);
+              ZoneInfoDB.TzData.loadTzDataWithFallback(goodFile.getPath(), TZDATA_IN_ROOT);
       assertEquals("9999z", dataWithOverride.getVersion());
       assertEquals(data.getAvailableIDs().length, dataWithOverride.getAvailableIDs().length);
     } finally {
@@ -84,7 +86,7 @@
 
   // Confirms any caching that exists correctly handles TimeZone mutability.
   public void testMakeTimeZone_timeZoneMutability() throws Exception {
-    ZoneInfoDB.TzData data = new ZoneInfoDB.TzData(TZDATA_IN_ROOT);
+    ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(TZDATA_IN_ROOT);
     String tzId = "Europe/London";
     ZoneInfo first = data.makeTimeZone(tzId);
     ZoneInfo second = data.makeTimeZone(tzId);
@@ -101,19 +103,19 @@
   }
 
   public void testMakeTimeZone_notFound() throws Exception {
-    ZoneInfoDB.TzData data = new ZoneInfoDB.TzData(TZDATA_IN_ROOT);
+    ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(TZDATA_IN_ROOT);
     assertNull(data.makeTimeZone("THIS_TZ_DOES_NOT_EXIST"));
     assertFalse(data.hasTimeZone("THIS_TZ_DOES_NOT_EXIST"));
   }
 
   public void testMakeTimeZone_found() throws Exception {
-    ZoneInfoDB.TzData data = new ZoneInfoDB.TzData(TZDATA_IN_ROOT);
+    ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(TZDATA_IN_ROOT);
     assertNotNull(data.makeTimeZone("Europe/London"));
     assertTrue(data.hasTimeZone("Europe/London"));
   }
 
   public void testGetRulesVersion() throws Exception {
-    ZoneInfoDB.TzData data = new ZoneInfoDB.TzData(TZDATA_IN_ROOT);
+    ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(TZDATA_IN_ROOT);
 
     String rulesVersion = ZoneInfoDB.TzData.getRulesVersion(new File(TZDATA_IN_ROOT));
     assertEquals(data.getVersion(), rulesVersion);
diff --git a/non_openjdk_java_files.mk b/non_openjdk_java_files.mk
index c1a7565..3d11475 100644
--- a/non_openjdk_java_files.mk
+++ b/non_openjdk_java_files.mk
@@ -374,7 +374,6 @@
   luni/src/main/java/libcore/internal/StringPool.java \
   luni/src/main/java/libcore/io/AsynchronousCloseMonitor.java \
   luni/src/main/java/libcore/io/ClassPathURLStreamHandler.java \
-  luni/src/main/java/libcore/io/Base64.java \
   luni/src/main/java/libcore/io/BlockGuardOs.java \
   luni/src/main/java/libcore/io/BufferIterator.java \
   luni/src/main/java/libcore/io/DropBox.java \
diff --git a/ojluni/src/main/java/java/net/HttpCookie.java b/ojluni/src/main/java/java/net/HttpCookie.java
index 8aae078..3cdd438 100644
--- a/ojluni/src/main/java/java/net/HttpCookie.java
+++ b/ojluni/src/main/java/java/net/HttpCookie.java
@@ -1013,8 +1013,8 @@
                         long maxAgeInSeconds = 0;
                         if (date != null) {
                             maxAgeInSeconds = (date.getTime() - cookie.whenCreated) / 1000;
-                            // If "expires" is in the past, remove the cookie.
-                            if (maxAgeInSeconds < 0) {
+                            // Avoid MAX_AGE_UNSPECIFIED
+                            if (maxAgeInSeconds == MAX_AGE_UNSPECIFIED) {
                                 maxAgeInSeconds = 0;
                             }
                         }
diff --git a/ojluni/src/main/java/java/nio/ByteBufferAsCharBuffer.java b/ojluni/src/main/java/java/nio/ByteBufferAsCharBuffer.java
index c94bc37..9dbb8a6 100644
--- a/ojluni/src/main/java/java/nio/ByteBufferAsCharBuffer.java
+++ b/ojluni/src/main/java/java/nio/ByteBufferAsCharBuffer.java
@@ -37,7 +37,7 @@
                            int mark, int pos, int lim, int cap,
                            int off, ByteOrder order) {
         super(mark, pos, lim, cap);
-        this.bb = bb;
+        this.bb = bb.duplicate();
         this.isReadOnly = bb.isReadOnly;
         // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
         // HeapByteBuffer. We only have to initialize the field when bb is an instance of
diff --git a/ojluni/src/main/java/java/nio/ByteBufferAsDoubleBuffer.java b/ojluni/src/main/java/java/nio/ByteBufferAsDoubleBuffer.java
index f9c13fa..ff4a6bf 100644
--- a/ojluni/src/main/java/java/nio/ByteBufferAsDoubleBuffer.java
+++ b/ojluni/src/main/java/java/nio/ByteBufferAsDoubleBuffer.java
@@ -38,7 +38,7 @@
                              int mark, int pos, int lim, int cap,
                              int off, ByteOrder order) {
         super(mark, pos, lim, cap);
-        this.bb = bb;
+        this.bb = bb.duplicate();
         this.isReadOnly = bb.isReadOnly;
         // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
         // HeapByteBuffer. We only have to initialize the field when bb is an instance of
diff --git a/ojluni/src/main/java/java/nio/ByteBufferAsFloatBuffer.java b/ojluni/src/main/java/java/nio/ByteBufferAsFloatBuffer.java
index 667c8bd..8e4e2e8 100644
--- a/ojluni/src/main/java/java/nio/ByteBufferAsFloatBuffer.java
+++ b/ojluni/src/main/java/java/nio/ByteBufferAsFloatBuffer.java
@@ -37,7 +37,7 @@
                             int mark, int pos, int lim, int cap,
                             int off, ByteOrder order) {
         super(mark, pos, lim, cap);
-        this.bb = bb;
+        this.bb = bb.duplicate();
         this.isReadOnly = bb.isReadOnly;
         // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
         // HeapByteBuffer. We only have to initialize the field when bb is an instance of
diff --git a/ojluni/src/main/java/java/nio/ByteBufferAsIntBuffer.java b/ojluni/src/main/java/java/nio/ByteBufferAsIntBuffer.java
index 275f37e..e340426 100644
--- a/ojluni/src/main/java/java/nio/ByteBufferAsIntBuffer.java
+++ b/ojluni/src/main/java/java/nio/ByteBufferAsIntBuffer.java
@@ -37,7 +37,7 @@
                           int mark, int pos, int lim, int cap,
                           int off, ByteOrder order) {
         super(mark, pos, lim, cap);
-        this.bb = bb;
+        this.bb = bb.duplicate();
         this.isReadOnly = bb.isReadOnly;
         // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
         // HeapByteBuffer. We only have to initialize the field when bb is an instance of
diff --git a/ojluni/src/main/java/java/nio/ByteBufferAsLongBuffer.java b/ojluni/src/main/java/java/nio/ByteBufferAsLongBuffer.java
index 1ea65e3..70f59c9 100644
--- a/ojluni/src/main/java/java/nio/ByteBufferAsLongBuffer.java
+++ b/ojluni/src/main/java/java/nio/ByteBufferAsLongBuffer.java
@@ -37,7 +37,7 @@
                            int mark, int pos, int lim, int cap,
                            int off, ByteOrder order) {
         super(mark, pos, lim, cap);
-        this.bb = bb;
+        this.bb = bb.duplicate();
         this.isReadOnly = bb.isReadOnly;
         // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
         // HeapByteBuffer. We only have to initialize the field when bb is an instance of
diff --git a/ojluni/src/main/java/java/nio/ByteBufferAsShortBuffer.java b/ojluni/src/main/java/java/nio/ByteBufferAsShortBuffer.java
index 90aec35..5178a7e 100644
--- a/ojluni/src/main/java/java/nio/ByteBufferAsShortBuffer.java
+++ b/ojluni/src/main/java/java/nio/ByteBufferAsShortBuffer.java
@@ -37,7 +37,7 @@
                             int mark, int pos, int lim, int cap,
                             int off, ByteOrder order) {
         super(mark, pos, lim, cap);
-        this.bb = bb;
+        this.bb = bb.duplicate();
         this.isReadOnly = bb.isReadOnly;
         // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
         // HeapByteBuffer. We only have to initialize the field when bb is an instance of
diff --git a/ojluni/src/main/java/java/util/Formatter.java b/ojluni/src/main/java/java/util/Formatter.java
index ebfdd2d..d6d8502 100644
--- a/ojluni/src/main/java/java/util/Formatter.java
+++ b/ojluni/src/main/java/java/util/Formatter.java
@@ -4191,6 +4191,14 @@
                     grpSep = dfs.getGroupingSeparator();
                     DecimalFormat df = (DecimalFormat) NumberFormat.getIntegerInstance(l);
                     grpSize = df.getGroupingSize();
+                    // Android-changed: http://b/33245708 : Some locales have a group separator but
+                    // also patterns without groups. If we do not clear the group separator in these
+                    // cases a divide by zero is thrown when determining where to place the
+                    // separators.
+                    if (!df.isGroupingUsed() || df.getGroupingSize() == 0) {
+                        grpSep = '\0';
+                    }
+                    // Android-changed: end http://b/33245708.
                 }
             }
 
diff --git a/ojluni/src/main/java/java/util/zip/ZipFile.java b/ojluni/src/main/java/java/util/zip/ZipFile.java
old mode 100755
new mode 100644
diff --git a/ojluni/src/main/java/sun/security/pkcs/PKCS9Attribute.java b/ojluni/src/main/java/sun/security/pkcs/PKCS9Attribute.java
index 9ae4a99..d847b10 100644
--- a/ojluni/src/main/java/sun/security/pkcs/PKCS9Attribute.java
+++ b/ojluni/src/main/java/sun/security/pkcs/PKCS9Attribute.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -331,11 +331,11 @@
         {new Byte(DerValue.tag_Sequence)}     // SignatureTimestampToken
     };
 
-    private static final Class[] VALUE_CLASSES = new Class[18];
+    private static final Class<?>[] VALUE_CLASSES = new Class<?>[18];
 
     static {
         try {
-            Class str = Class.forName("[Ljava.lang.String;");
+            Class<?> str = Class.forName("[Ljava.lang.String;");
 
             VALUE_CLASSES[0] = null;  // not used
             VALUE_CLASSES[1] = str;   // EMailAddress
@@ -489,8 +489,8 @@
 
         if (val.length != 2)
             throw new IOException("PKCS9Attribute doesn't have two components");
-        // get the oid
 
+        // get the oid
         oid = val[0].getOID();
         byte[] content = val[1].toByteArray();
         DerValue[] elems = new DerInputStream(content).getSet(1);
diff --git a/ojluni/src/main/java/sun/security/pkcs/SignerInfo.java b/ojluni/src/main/java/sun/security/pkcs/SignerInfo.java
index 3a024b0..e5f3e1d 100644
--- a/ojluni/src/main/java/sun/security/pkcs/SignerInfo.java
+++ b/ojluni/src/main/java/sun/security/pkcs/SignerInfo.java
@@ -327,7 +327,7 @@
                        authenticatedAttributes.getAttributeValue(
                          PKCS9Attribute.CONTENT_TYPE_OID);
                 if (contentType == null ||
-                    !contentType.equals(content.contentType))
+                    !contentType.equals((Object)content.contentType))
                     return null;  // contentType does not match, bad SignerInfo
 
                 // now, check message digest
diff --git a/ojluni/src/main/java/sun/security/provider/X509Factory.java b/ojluni/src/main/java/sun/security/provider/X509Factory.java
index 0c047a6..19e70c0 100644
--- a/ojluni/src/main/java/sun/security/provider/X509Factory.java
+++ b/ojluni/src/main/java/sun/security/provider/X509Factory.java
@@ -25,18 +25,24 @@
 
 package sun.security.provider;
 
+/* BEGIN android-removed
 import java.io.*;
 import java.util.*;
+ * END android-removed */
 import java.security.cert.*;
 import sun.security.x509.X509CertImpl;
 import sun.security.x509.X509CRLImpl;
+/* BEGIN android-removed
 import sun.security.pkcs.PKCS7;
 import sun.security.provider.certpath.X509CertPath;
 import sun.security.provider.certpath.X509CertificatePair;
 import sun.security.util.DerValue;
+ * END android-removed */
 import sun.security.util.Cache;
-import sun.misc.BASE64Decoder;
+/* BEGIN android-removed
+import java.util.Base64;
 import sun.security.pkcs.ParsingException;
+ * END android-removed */
 
 /**
  * This class defines a certificate factory for X.509 v3 certificates &
@@ -57,10 +63,15 @@
  * @see sun.security.x509.X509CRLImpl
  */
 
-public class X509Factory extends CertificateFactorySpi {
+// BEGIN android-changed
+// Was: public class X509Factory extends CertificateFactorySpi {
+public class X509Factory {
+// END android-changed
 
+    /* BEGIN android-removed
     public static final String BEGIN_CERT = "-----BEGIN CERTIFICATE-----";
     public static final String END_CERT = "-----END CERTIFICATE-----";
+     * END android-removed */
 
     private static final int ENC_MAX_LENGTH = 4096 * 1024; // 4 MB MAX
 
@@ -69,6 +80,7 @@
     private static final Cache<Object, X509CRLImpl> crlCache
         = Cache.newSoftMemoryCache(750);
 
+    /* BEGIN android-removed
     /**
      * Generates an X.509 certificate object and initializes it with
      * the data read from the input stream <code>is</code>.
@@ -79,7 +91,7 @@
      * from the input stream.
      *
      * @exception CertificateException on parsing errors.
-     */
+     *
     @Override
     public Certificate engineGenerateCertificate(InputStream is)
         throws CertificateException
@@ -112,7 +124,7 @@
     /**
      * Read from the stream until length bytes have been read or EOF has
      * been reached. Return the number of bytes actually read.
-     */
+     *
     private static int readFully(InputStream in, ByteArrayOutputStream bout,
             int length) throws IOException {
         int read = 0;
@@ -128,6 +140,7 @@
         }
         return read;
     }
+     * END android-removed */
 
     /**
      * Return an interned X509CertImpl for the given certificate.
@@ -231,6 +244,7 @@
         cache.put(key, value);
     }
 
+    /* BEGIN android-removed
     /**
      * Generates a <code>CertPath</code> object and initializes it with
      * the data read from the <code>InputStream</code> inStream. The data
@@ -241,7 +255,7 @@
      *   <code>InputStream</code>
      * @exception CertificateException if an exception occurs while decoding
      * @since 1.4
-     */
+     *
     @Override
     public CertPath engineGenerateCertPath(InputStream inStream)
         throws CertificateException
@@ -273,7 +287,7 @@
      * @exception CertificateException if an exception occurs while decoding or
      *   the encoding requested is not supported
      * @since 1.4
-     */
+     *
     @Override
     public CertPath engineGenerateCertPath(InputStream inStream,
         String encoding) throws CertificateException
@@ -306,7 +320,7 @@
      *   certificates
      * @exception CertificateException if an exception occurs
      * @since 1.4
-     */
+     *
     @Override
     public CertPath
         engineGenerateCertPath(List<? extends Certificate> certificates)
@@ -326,7 +340,7 @@
      * @return an <code>Iterator</code> over the names of the supported
      *         <code>CertPath</code> encodings (as <code>String</code>s)
      * @since 1.4
-     */
+     *
     @Override
     public Iterator<String> engineGetCertPathEncodings() {
         return(X509CertPath.getEncodingsStatic());
@@ -342,7 +356,7 @@
      * initialized with the data from the input stream.
      *
      * @exception CertificateException on parsing errors.
-     */
+     *
     @Override
     public Collection<? extends java.security.cert.Certificate>
             engineGenerateCertificates(InputStream is)
@@ -368,7 +382,7 @@
      * from the input stream.
      *
      * @exception CRLException on parsing errors.
-     */
+     *
     @Override
     public CRL engineGenerateCRL(InputStream is)
         throws CRLException
@@ -406,7 +420,7 @@
      * initialized with the data from the input stream.
      *
      * @exception CRLException on parsing errors.
-     */
+     *
     @Override
     public Collection<? extends java.security.cert.CRL> engineGenerateCRLs(
             InputStream is) throws CRLException
@@ -425,16 +439,35 @@
      * Parses the data in the given input stream as a sequence of DER
      * encoded X.509 certificates (in binary or base 64 encoded format) OR
      * as a single PKCS#7 encoded blob (in binary or base64 encoded format).
-     */
+     *
     private Collection<? extends java.security.cert.Certificate>
         parseX509orPKCS7Cert(InputStream is)
         throws CertificateException, IOException
     {
+        int peekByte;
+        byte[] data;
+        PushbackInputStream pbis = new PushbackInputStream(is);
         Collection<X509CertImpl> coll = new ArrayList<>();
-        byte[] data = readOneBlock(is);
-        if (data == null) {
+
+        // Test the InputStream for end-of-stream.  If the stream's
+        // initial state is already at end-of-stream then return
+        // an empty collection.  Otherwise, push the byte back into the
+        // stream and let readOneBlock look for the first certificate.
+        peekByte = pbis.read();
+        if (peekByte == -1) {
             return new ArrayList<>(0);
+        } else {
+            pbis.unread(peekByte);
+            data = readOneBlock(pbis);
         }
+
+        // If we end up with a null value after reading the first block
+        // then we know the end-of-stream has been reached and no certificate
+        // data has been found.
+        if (data == null) {
+            throw new CertificateException("No certificate data found");
+        }
+
         try {
             PKCS7 pkcs7 = new PKCS7(data);
             X509Certificate[] certs = pkcs7.getCertificates();
@@ -442,13 +475,13 @@
             if (certs != null) {
                 return Arrays.asList(certs);
             } else {
-                // no crls provided
+                // no certificates provided
                 return new ArrayList<>(0);
             }
         } catch (ParsingException e) {
             while (data != null) {
                 coll.add(new X509CertImpl(data));
-                data = readOneBlock(is);
+                data = readOneBlock(pbis);
             }
         }
         return coll;
@@ -458,16 +491,35 @@
      * Parses the data in the given input stream as a sequence of DER encoded
      * X.509 CRLs (in binary or base 64 encoded format) OR as a single PKCS#7
      * encoded blob (in binary or base 64 encoded format).
-     */
+     *
     private Collection<? extends java.security.cert.CRL>
         parseX509orPKCS7CRL(InputStream is)
         throws CRLException, IOException
     {
+        int peekByte;
+        byte[] data;
+        PushbackInputStream pbis = new PushbackInputStream(is);
         Collection<X509CRLImpl> coll = new ArrayList<>();
-        byte[] data = readOneBlock(is);
-        if (data == null) {
+
+        // Test the InputStream for end-of-stream.  If the stream's
+        // initial state is already at end-of-stream then return
+        // an empty collection.  Otherwise, push the byte back into the
+        // stream and let readOneBlock look for the first CRL.
+        peekByte = pbis.read();
+        if (peekByte == -1) {
             return new ArrayList<>(0);
+        } else {
+            pbis.unread(peekByte);
+            data = readOneBlock(pbis);
         }
+
+        // If we end up with a null value after reading the first block
+        // then we know the end-of-stream has been reached and no CRL
+        // data has been found.
+        if (data == null) {
+            throw new CRLException("No CRL data found");
+        }
+
         try {
             PKCS7 pkcs7 = new PKCS7(data);
             X509CRL[] crls = pkcs7.getCRLs();
@@ -481,7 +533,7 @@
         } catch (ParsingException e) {
             while (data != null) {
                 coll.add(new X509CRLImpl(data));
-                data = readOneBlock(is);
+                data = readOneBlock(pbis);
             }
         }
         return coll;
@@ -498,7 +550,7 @@
      * @param is the InputStream
      * @returns byte block or null if end of stream
      * @throws IOException If any parsing error
-     */
+     *
     private static byte[] readOneBlock(InputStream is) throws IOException {
 
         // The first character of a BLOCK.
@@ -595,8 +647,7 @@
 
             checkHeaderFooter(header.toString(), footer.toString());
 
-            BASE64Decoder decoder = new BASE64Decoder();
-            return decoder.decodeBuffer(new String(data, 0, pos));
+            return Base64.getMimeDecoder().decode(new String(data, 0, pos));
         }
     }
 
@@ -627,7 +678,7 @@
      * @param tag   Tag already read (-1 mean not read)
      * @returns     The current tag, used to check EOC in indefinite-length BER
      * @throws IOException Any parsing error
-     */
+     *
     private static int readBERInternal(InputStream is,
             ByteArrayOutputStream bout, int tag) throws IOException {
 
@@ -716,4 +767,5 @@
         }
         return tag;
     }
+     * END android-removed */
 }
diff --git a/ojluni/src/main/java/sun/security/util/DerIndefLenConverter.java b/ojluni/src/main/java/sun/security/util/DerIndefLenConverter.java
index 78d9e30..cbd5ecc 100644
--- a/ojluni/src/main/java/sun/security/util/DerIndefLenConverter.java
+++ b/ojluni/src/main/java/sun/security/util/DerIndefLenConverter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -156,12 +156,18 @@
         }
         if (isLongForm(lenByte)) {
             lenByte &= LEN_MASK;
-            if (lenByte > 4)
+            if (lenByte > 4) {
                 throw new IOException("Too much data");
-            if ((dataSize - dataPos) < (lenByte + 1))
+            }
+            if ((dataSize - dataPos) < (lenByte + 1)) {
                 throw new IOException("Too little data");
-            for (int i = 0; i < lenByte; i++)
+            }
+            for (int i = 0; i < lenByte; i++) {
                 curLen = (curLen << 8) + (data[dataPos++] & 0xff);
+            }
+            if (curLen < 0) {
+                throw new IOException("Invalid length bytes");
+            }
         } else {
            curLen = (lenByte & LEN_MASK);
         }
@@ -188,10 +194,15 @@
         }
         if (isLongForm(lenByte)) {
             lenByte &= LEN_MASK;
-            for (int i = 0; i < lenByte; i++)
+            for (int i = 0; i < lenByte; i++) {
                 curLen = (curLen << 8) + (data[dataPos++] & 0xff);
-        } else
+            }
+            if (curLen < 0) {
+                throw new IOException("Invalid length bytes");
+            }
+        } else {
             curLen = (lenByte & LEN_MASK);
+        }
         writeLength(curLen);
         writeValue(curLen);
     }
diff --git a/ojluni/src/main/java/sun/security/util/DerInputStream.java b/ojluni/src/main/java/sun/security/util/DerInputStream.java
index 8f51439..dae8afd 100644
--- a/ojluni/src/main/java/sun/security/util/DerInputStream.java
+++ b/ojluni/src/main/java/sun/security/util/DerInputStream.java
@@ -604,6 +604,10 @@
                 value <<= 8;
                 value += 0x0ff & in.read();
             }
+            if (value < 0) {
+                throw new IOException("DerInputStream.getLength(): "
+                        + "Invalid length bytes");
+            }
         }
         return value;
     }
diff --git a/ojluni/src/main/java/sun/security/x509/AVA.java b/ojluni/src/main/java/sun/security/x509/AVA.java
index f28ab9b..8a85d7b 100644
--- a/ojluni/src/main/java/sun/security/x509/AVA.java
+++ b/ojluni/src/main/java/sun/security/x509/AVA.java
@@ -379,8 +379,8 @@
 
         // encode as PrintableString unless value contains
         // non-PrintableString chars
-        if (this.oid.equals(PKCS9Attribute.EMAIL_ADDRESS_OID) ||
-            (this.oid.equals(X500Name.DOMAIN_COMPONENT_OID) &&
+        if (this.oid.equals((Object)PKCS9Attribute.EMAIL_ADDRESS_OID) ||
+            (this.oid.equals((Object)X500Name.DOMAIN_COMPONENT_OID) &&
                 PRESERVE_OLD_DC_ENCODING == false)) {
             // EmailAddress and DomainComponent must be IA5String
             return new DerValue(DerValue.tag_IA5String,
@@ -396,7 +396,7 @@
     private DerValue parseString
         (Reader in, int c, int format, StringBuilder temp) throws IOException {
 
-        List<Byte> embeddedHex = new ArrayList<Byte>();
+        List<Byte> embeddedHex = new ArrayList<>();
         boolean isPrintableString = true;
         boolean escape = false;
         boolean leadingChar = true;
@@ -514,8 +514,8 @@
 
         // encode as PrintableString unless value contains
         // non-PrintableString chars
-        if (this.oid.equals(PKCS9Attribute.EMAIL_ADDRESS_OID) ||
-            (this.oid.equals(X500Name.DOMAIN_COMPONENT_OID) &&
+        if (this.oid.equals((Object)PKCS9Attribute.EMAIL_ADDRESS_OID) ||
+            (this.oid.equals((Object)X500Name.DOMAIN_COMPONENT_OID) &&
                 PRESERVE_OLD_DC_ENCODING == false)) {
             // EmailAddress and DomainComponent must be IA5String
             return new DerValue(DerValue.tag_IA5String, temp.toString());
diff --git a/ojluni/src/main/java/sun/security/x509/AlgorithmId.java b/ojluni/src/main/java/sun/security/x509/AlgorithmId.java
index 903a12d..1bdb1b8 100644
--- a/ojluni/src/main/java/sun/security/x509/AlgorithmId.java
+++ b/ojluni/src/main/java/sun/security/x509/AlgorithmId.java
@@ -235,7 +235,7 @@
         if (algName != null) {
             return algName;
         }
-        if ((params != null) && algid.equals(specifiedWithECDSA_oid)) {
+        if ((params != null) && algid.equals((Object)specifiedWithECDSA_oid)) {
             try {
                 AlgorithmId paramsId =
                         AlgorithmId.parse(new DerValue(getEncodedParams()));
@@ -276,7 +276,7 @@
     public boolean equals(AlgorithmId other) {
         boolean paramsEqual =
           (params == null ? other.params == null : params.equals(other.params));
-        return (algid.equals(other.algid) && paramsEqual);
+        return (algid.equals((Object)other.algid) && paramsEqual);
     }
 
     /**
@@ -304,7 +304,7 @@
      * they are the same algorithm, ignoring algorithm parameters.
      */
     public final boolean equals(ObjectIdentifier id) {
-        return algid.equals(id);
+        return algid.equals((Object)id);
     }
 
     /**
@@ -510,6 +510,14 @@
         if (name.equalsIgnoreCase("EC")) {
             return EC_oid;
         }
+        if (name.equalsIgnoreCase("ECDH")) {
+            return AlgorithmId.ECDH_oid;
+        }
+
+        // Secret key algorithms
+        if (name.equalsIgnoreCase("AES")) {
+            return AlgorithmId.AES_oid;
+        }
 
         // Common signature types
         if (name.equalsIgnoreCase("MD5withRSA")
@@ -705,10 +713,17 @@
     public static final ObjectIdentifier DSA_oid;
     public static final ObjectIdentifier DSA_OIW_oid;
     public static final ObjectIdentifier EC_oid = oid(1, 2, 840, 10045, 2, 1);
+    public static final ObjectIdentifier ECDH_oid = oid(1, 3, 132, 1, 12);
     public static final ObjectIdentifier RSA_oid;
     public static final ObjectIdentifier RSAEncryption_oid;
 
     /*
+     * COMMON SECRET KEY TYPES
+     */
+    public static final ObjectIdentifier AES_oid =
+                                            oid(2, 16, 840, 1, 101, 3, 4, 1);
+
+    /*
      * COMMON SIGNATURE ALGORITHMS
      */
     private static final int md2WithRSAEncryption_data[] =
@@ -938,6 +953,10 @@
         nameTable.put(DSA_oid, "DSA");
         nameTable.put(DSA_OIW_oid, "DSA");
         nameTable.put(EC_oid, "EC");
+        nameTable.put(ECDH_oid, "ECDH");
+
+        nameTable.put(AES_oid, "AES");
+
         nameTable.put(sha1WithECDSA_oid, "SHA1withECDSA");
         nameTable.put(sha224WithECDSA_oid, "SHA224withECDSA");
         nameTable.put(sha256WithECDSA_oid, "SHA256withECDSA");
diff --git a/ojluni/src/main/java/sun/security/x509/DistributionPointName.java b/ojluni/src/main/java/sun/security/x509/DistributionPointName.java
index 19d6289..4409dc0 100644
--- a/ojluni/src/main/java/sun/security/x509/DistributionPointName.java
+++ b/ojluni/src/main/java/sun/security/x509/DistributionPointName.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/sun/security/x509/NetscapeCertTypeExtension.java b/ojluni/src/main/java/sun/security/x509/NetscapeCertTypeExtension.java
index 78f731b..735efdd 100644
--- a/ojluni/src/main/java/sun/security/x509/NetscapeCertTypeExtension.java
+++ b/ojluni/src/main/java/sun/security/x509/NetscapeCertTypeExtension.java
@@ -221,7 +221,7 @@
     /**
      * Get the attribute value.
      */
-    public Object get(String name) throws IOException {
+    public Boolean get(String name) throws IOException {
         return Boolean.valueOf(isSet(getPosition(name)));
     }
 
@@ -314,15 +314,15 @@
             if (isSet(getPosition(SSL_CLIENT)) ||
                 isSet(getPosition(S_MIME)) ||
                 isSet(getPosition(OBJECT_SIGNING)))
-                keyUsage.set(keyUsage.DIGITAL_SIGNATURE, val);
+                keyUsage.set(KeyUsageExtension.DIGITAL_SIGNATURE, val);
 
             if (isSet(getPosition(SSL_SERVER)))
-                keyUsage.set(keyUsage.KEY_ENCIPHERMENT, val);
+                keyUsage.set(KeyUsageExtension.KEY_ENCIPHERMENT, val);
 
             if (isSet(getPosition(SSL_CA)) ||
                 isSet(getPosition(S_MIME_CA)) ||
                 isSet(getPosition(OBJECT_SIGNING_CA)))
-                keyUsage.set(keyUsage.KEY_CERTSIGN, val);
+                keyUsage.set(KeyUsageExtension.KEY_CERTSIGN, val);
         } catch (IOException e) { }
         return keyUsage.getBits();
     }
diff --git a/ojluni/src/main/java/sun/security/x509/RDN.java b/ojluni/src/main/java/sun/security/x509/RDN.java
index 1463fd1..ed46abe 100644
--- a/ojluni/src/main/java/sun/security/x509/RDN.java
+++ b/ojluni/src/main/java/sun/security/x509/RDN.java
@@ -26,17 +26,11 @@
 
 package sun.security.x509;
 
-import java.lang.reflect.*;
 import java.io.IOException;
 import java.io.StringReader;
-import java.security.PrivilegedExceptionAction;
-import java.security.AccessController;
-import java.security.Principal;
 import java.util.*;
 
 import sun.security.util.*;
-import sun.security.pkcs.PKCS9Attribute;
-import javax.security.auth.x500.X500Principal;
 
 /**
  * RDNs are a set of {attribute = value} assertions.  Some of those
@@ -328,7 +322,7 @@
      */
     DerValue findAttribute(ObjectIdentifier oid) {
         for (int i = 0; i < assertion.length; i++) {
-            if (assertion[i].oid.equals(oid)) {
+            if (assertion[i].oid.equals((Object)oid)) {
                 return assertion[i].value;
             }
         }
diff --git a/ojluni/src/main/java/sun/security/x509/X500Name.java b/ojluni/src/main/java/sun/security/x509/X500Name.java
index 7b24fa3..6090554 100644
--- a/ojluni/src/main/java/sun/security/x509/X500Name.java
+++ b/ojluni/src/main/java/sun/security/x509/X500Name.java
@@ -28,14 +28,12 @@
 
 import java.lang.reflect.*;
 import java.io.IOException;
-import java.io.StringReader;
 import java.security.PrivilegedExceptionAction;
 import java.security.AccessController;
 import java.security.Principal;
 import java.util.*;
 
 import sun.security.util.*;
-import sun.security.pkcs.PKCS9Attribute;
 import javax.security.auth.x500.X500Principal;
 
 /**
@@ -1392,7 +1390,7 @@
     /**
      * Constructor object for use by asX500Principal().
      */
-    private static final Constructor principalConstructor;
+    private static final Constructor<X500Principal> principalConstructor;
 
     /**
      * Field object for use by asX500Name().
@@ -1407,9 +1405,9 @@
         PrivilegedExceptionAction<Object[]> pa =
                 new PrivilegedExceptionAction<Object[]>() {
             public Object[] run() throws Exception {
-                Class pClass = X500Principal.class;
-                Class[] args = new Class[] {X500Name.class};
-                Constructor cons = ((Class<?>)pClass).getDeclaredConstructor(args);
+                Class<X500Principal> pClass = X500Principal.class;
+                Class<?>[] args = new Class<?>[] { X500Name.class };
+                Constructor<X500Principal> cons = pClass.getDeclaredConstructor(args);
                 cons.setAccessible(true);
                 Field field = pClass.getDeclaredField("thisX500Name");
                 field.setAccessible(true);
@@ -1418,7 +1416,10 @@
         };
         try {
             Object[] result = AccessController.doPrivileged(pa);
-            principalConstructor = (Constructor)result[0];
+            @SuppressWarnings("unchecked")
+            Constructor<X500Principal> constr =
+                    (Constructor<X500Principal>)result[0];
+            principalConstructor = constr;
             principalField = (Field)result[1];
         } catch (Exception e) {
             throw new InternalError("Could not obtain X500Principal access", e);
@@ -1435,8 +1436,7 @@
         if (x500Principal == null) {
             try {
                 Object[] args = new Object[] {this};
-                x500Principal =
-                        (X500Principal)principalConstructor.newInstance(args);
+                x500Principal = principalConstructor.newInstance(args);
             } catch (Exception e) {
                 throw new RuntimeException("Unexpected exception", e);
             }
diff --git a/ojluni/src/main/native/PlainDatagramSocketImpl.c b/ojluni/src/main/native/PlainDatagramSocketImpl.c
index aad8c34..b36e286 100644
--- a/ojluni/src/main/native/PlainDatagramSocketImpl.c
+++ b/ojluni/src/main/native/PlainDatagramSocketImpl.c
@@ -500,6 +500,7 @@
     }
     if (IS_NULL(addressObj)) {
         JNU_ThrowNullPointerException(env, "Null address in peek()");
+        return -1;
     }
     if (timeout) {
         int ret = NET_Timeout(fd, timeout);
@@ -1386,7 +1387,7 @@
         default :
             JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                 "Socket option not supported by PlainDatagramSocketImp");
-            break;
+            return;
 
     }
 
@@ -1608,6 +1609,9 @@
 #ifdef AF_INET6
 #ifdef __linux__
     setTTL(env, fd, ttl);
+    if ((*env)->ExceptionCheck(env)) {
+        return;
+    }
     if (ipv6_available()) {
         setHopLimit(env, fd, ttl);
     }
@@ -1830,6 +1834,7 @@
                     else
                         NET_ThrowCurrent(env, "setsockopt IP_DROP_MEMBERSHIP failed");
                 }
+                return;
             }
         }
 
diff --git a/ojluni/src/main/native/net_util_md.c b/ojluni/src/main/native/net_util_md.c
index 0dd6c09..49c9779 100644
--- a/ojluni/src/main/native/net_util_md.c
+++ b/ojluni/src/main/native/net_util_md.c
@@ -500,7 +500,9 @@
         }
 }
 
-#if defined(__linux__) && defined(AF_INET6)
+#if 0
+// Android-changed: Stripped out unused code. http://b/33250070
+// #if defined(__linux__) && defined(AF_INET6)
 
 
 /* following code creates a list of addresses from the kernel
@@ -1398,9 +1400,12 @@
     return timeout;
 }
 
+#if 0
+// Stripped out unused code.
 // http://b/27301951
 __attribute__((destructor))
 static void netUtilCleanUp() {
     if (loRoutes != 0) free(loRoutes);
     if (localifs != 0) free(localifs);
 }
+#endif
diff --git a/tzdata/update2/src/main/libcore/tzdata/update2/TzDataBundleInstaller.java b/tzdata/update2/src/main/libcore/tzdata/update2/TzDataBundleInstaller.java
index b8e8bdf..127baf8 100644
--- a/tzdata/update2/src/main/libcore/tzdata/update2/TzDataBundleInstaller.java
+++ b/tzdata/update2/src/main/libcore/tzdata/update2/TzDataBundleInstaller.java
@@ -29,18 +29,37 @@
  */
 public final class TzDataBundleInstaller {
 
-    static final String CURRENT_TZ_DATA_DIR_NAME = "current";
-    static final String WORKING_DIR_NAME = "working";
-    static final String OLD_TZ_DATA_DIR_NAME = "old";
+    private static final String CURRENT_TZ_DATA_DIR_NAME = "current";
+    private static final String WORKING_DIR_NAME = "working";
+    private static final String OLD_TZ_DATA_DIR_NAME = "old";
 
     private final String logTag;
     private final File systemTzDataFile;
-    private final File installDir;
+    private final File oldTzDataDir;
+    private final File currentTzDataDir;
+    private final File workingDir;
 
     public TzDataBundleInstaller(String logTag, File systemTzDataFile, File installDir) {
         this.logTag = logTag;
         this.systemTzDataFile = systemTzDataFile;
-        this.installDir = installDir;
+        oldTzDataDir = new File(installDir, OLD_TZ_DATA_DIR_NAME);
+        currentTzDataDir = new File(installDir, CURRENT_TZ_DATA_DIR_NAME);
+        workingDir = new File(installDir, WORKING_DIR_NAME);
+    }
+
+    // VisibleForTesting
+    File getOldTzDataDir() {
+        return oldTzDataDir;
+    }
+
+    // VisibleForTesting
+    File getCurrentTzDataDir() {
+        return currentTzDataDir;
+    }
+
+    // VisibleForTesting
+    File getWorkingDir() {
+        return workingDir;
     }
 
     /**
@@ -51,29 +70,28 @@
      * If the installation completed successfully this method returns {@code true}.
      */
     public boolean install(byte[] content) throws IOException {
-        File oldTzDataDir = new File(installDir, OLD_TZ_DATA_DIR_NAME);
         if (oldTzDataDir.exists()) {
             FileUtils.deleteRecursive(oldTzDataDir);
         }
-
-        File currentTzDataDir = new File(installDir, CURRENT_TZ_DATA_DIR_NAME);
-        File workingDir = new File(installDir, WORKING_DIR_NAME);
+        if (workingDir.exists()) {
+            FileUtils.deleteRecursive(workingDir);
+        }
 
         Slog.i(logTag, "Unpacking / verifying time zone update");
-        File unpackedContentDir = unpackBundle(content, workingDir);
+        unpackBundle(content, workingDir);
         try {
-            if (!checkBundleVersion(unpackedContentDir)) {
+            if (!checkBundleVersion(workingDir)) {
                 Slog.i(logTag, "Update not applied: Bundle format version is incorrect.");
                 return false;
             }
             // This check should not fail if the bundle version check passes, but we're being
             // intentionally paranoid.
-            if (!checkBundleFilesExist(unpackedContentDir)) {
+            if (!checkBundleFilesExist(workingDir)) {
                 Slog.i(logTag, "Update not applied: Bundle is missing files");
                 return false;
             }
 
-            if (!checkBundleRulesNewerThanSystem(systemTzDataFile, unpackedContentDir)) {
+            if (!checkBundleRulesNewerThanSystem(systemTzDataFile, workingDir)) {
                 Slog.i(logTag, "Update not applied: Bundle rules version check failed");
                 return false;
             }
@@ -82,19 +100,52 @@
             // http://b/31008728
 
             Slog.i(logTag, "Applying time zone update");
-            FileUtils.makeDirectoryWorldAccessible(unpackedContentDir);
+            FileUtils.makeDirectoryWorldAccessible(workingDir);
 
             if (currentTzDataDir.exists()) {
                 Slog.i(logTag, "Moving " + currentTzDataDir + " to " + oldTzDataDir);
                 FileUtils.rename(currentTzDataDir, oldTzDataDir);
             }
-            Slog.i(logTag, "Moving " + unpackedContentDir + " to " + currentTzDataDir);
-            FileUtils.rename(unpackedContentDir, currentTzDataDir);
+            Slog.i(logTag, "Moving " + workingDir + " to " + currentTzDataDir);
+            FileUtils.rename(workingDir, currentTzDataDir);
             Slog.i(logTag, "Update applied: " + currentTzDataDir + " successfully created");
             return true;
         } finally {
             deleteBestEffort(oldTzDataDir);
-            deleteBestEffort(unpackedContentDir);
+            deleteBestEffort(workingDir);
+        }
+    }
+
+    /**
+     * Uninstall the current timezone update in /data, returning the device to using data from
+     * /system. Returns {@code true} if uninstallation was successful, {@code false} if there was
+     * nothing installed in /data to uninstall.
+     *
+     * <p>Errors encountered during uninstallation will throw an {@link IOException}.
+     */
+    public boolean uninstall() throws IOException {
+        Slog.i(logTag, "Uninstalling time zone update");
+
+        // Make sure we don't have a dir where we're going to move the currently installed data to.
+        if (oldTzDataDir.exists()) {
+            // If we can't remove this, an exception is thrown and we don't continue.
+            FileUtils.deleteRecursive(oldTzDataDir);
+        }
+
+        if (!currentTzDataDir.exists()) {
+            Slog.i(logTag, "Nothing to uninstall at " + currentTzDataDir);
+            return false;
+        }
+
+        try {
+            Slog.i(logTag, "Moving " + currentTzDataDir + " to " + oldTzDataDir);
+            // Move currentTzDataDir out of the way in one operation so we can't partially delete
+            // the contents, which would leave a partial install.
+            FileUtils.rename(currentTzDataDir, oldTzDataDir);
+            return true;
+        } finally {
+            // Do our best to delete the now uninstalled timezone data.
+            deleteBestEffort(oldTzDataDir);
         }
     }
 
@@ -109,11 +160,10 @@
         }
     }
 
-    private File unpackBundle(byte[] content, File targetDir) throws IOException {
+    private void unpackBundle(byte[] content, File targetDir) throws IOException {
         Slog.i(logTag, "Unpacking update content to: " + targetDir);
         ConfigBundle bundle = new ConfigBundle(content);
         bundle.extractTo(targetDir);
-        return targetDir;
     }
 
     private boolean checkBundleFilesExist(File unpackedContentDir) throws IOException {
diff --git a/tzdata/update2/src/test/libcore/tzdata/update2/TzDataBundleInstallerTest.java b/tzdata/update2/src/test/libcore/tzdata/update2/TzDataBundleInstallerTest.java
index 4c189e0..b55a257 100644
--- a/tzdata/update2/src/test/libcore/tzdata/update2/TzDataBundleInstallerTest.java
+++ b/tzdata/update2/src/test/libcore/tzdata/update2/TzDataBundleInstallerTest.java
@@ -163,7 +163,7 @@
      * Tests that an update will be unpacked even if there is a partial update from a previous run.
      */
     public void testInstallWithWorkingDir() throws Exception {
-        File workingDir = new File(testInstallDir, TzDataBundleInstaller.WORKING_DIR_NAME);
+        File workingDir = installer.getWorkingDir();
         assertTrue(workingDir.mkdir());
         createFile(new File(workingDir, "myFile"));
 
@@ -176,7 +176,7 @@
      * Tests that a bundle without a bundle version file will be rejected.
      */
     public void testInstallWithMissingBundleVersionFile() throws Exception {
-        File workingDir = new File(testInstallDir, TzDataBundleInstaller.WORKING_DIR_NAME);
+        File workingDir = installer.getWorkingDir();
         assertTrue(workingDir.mkdir());
 
         ConfigBundle tzData = createTzDataBundleWithoutFormatVersionFile(NEW_RULES_VERSION);
@@ -214,14 +214,35 @@
      * Tests that a bundle with an incorrect bundle version will be rejected.
      */
     public void testInstallWithInvalidBundleVersionFile() throws Exception {
-        File workingDir = new File(testInstallDir, TzDataBundleInstaller.WORKING_DIR_NAME);
-        assertTrue(workingDir.mkdir());
-
         ConfigBundle tzData = createTzDataBundleWithInvalidBundleVersion(NEW_RULES_VERSION);
         assertFalse(installer.install(tzData.getBundleBytes()));
         assertNoContentInstalled();
     }
 
+    public void testUninstall_noExistingDataBundle() throws Exception {
+        assertFalse(installer.uninstall());
+        assertNoContentInstalled();
+    }
+
+    public void testUninstall_existingDataBundle() throws Exception {
+        File currentDataDir = installer.getCurrentTzDataDir();
+        assertTrue(currentDataDir.mkdir());
+
+        assertTrue(installer.uninstall());
+        assertNoContentInstalled();
+    }
+
+    public void testUninstall_oldDirsAlreadyExists() throws Exception {
+        File oldTzDataDir = installer.getOldTzDataDir();
+        assertTrue(oldTzDataDir.mkdir());
+
+        File currentDataDir = installer.getCurrentTzDataDir();
+        assertTrue(currentDataDir.mkdir());
+
+        assertTrue(installer.uninstall());
+        assertNoContentInstalled();
+    }
+
     private ConfigBundle createTzDataBundleWithInvalidBundleVersion(String tzDataVersion)
             throws IOException {
 
@@ -278,8 +299,7 @@
     private void assertTzDataInstalled(ConfigBundle expectedTzData) throws Exception {
         assertTrue(testInstallDir.exists());
 
-        File currentTzDataDir =
-                new File(testInstallDir, TzDataBundleInstaller.CURRENT_TZ_DATA_DIR_NAME);
+        File currentTzDataDir = installer.getCurrentTzDataDir();
         assertTrue(currentTzDataDir.exists());
 
         File bundleVersionFile = new File(currentTzDataDir,
@@ -297,19 +317,19 @@
         assertTrue(icuFile.exists());
 
         // Also check no working directory is left lying around.
-        File workingDir = new File(testInstallDir, TzDataBundleInstaller.WORKING_DIR_NAME);
+        File workingDir = installer.getWorkingDir();
         assertFalse(workingDir.exists());
     }
 
     private void assertNoContentInstalled() {
-        File currentTzDataDir = new File(testInstallDir, TzDataBundleInstaller.CURRENT_TZ_DATA_DIR_NAME);
+        File currentTzDataDir = installer.getCurrentTzDataDir();
         assertFalse(currentTzDataDir.exists());
 
         // Also check no working directories are left lying around.
-        File workingDir = new File(testInstallDir, TzDataBundleInstaller.WORKING_DIR_NAME);
+        File workingDir = installer.getWorkingDir();
         assertFalse(workingDir.exists());
 
-        File oldDataDir = new File(testInstallDir, TzDataBundleInstaller.OLD_TZ_DATA_DIR_NAME);
+        File oldDataDir = installer.getOldTzDataDir();
         assertFalse(oldDataDir.exists());
     }