Merge "Improve patches to sun.security on top of upstream OpenJDK8u121-b13."
diff --git a/dalvik/src/main/java/dalvik/system/DexFile.java b/dalvik/src/main/java/dalvik/system/DexFile.java
index 6dd1ba6..bbf0d99 100644
--- a/dalvik/src/main/java/dalvik/system/DexFile.java
+++ b/dalvik/src/main/java/dalvik/system/DexFile.java
@@ -526,4 +526,13 @@
      */
     public native static String getNonProfileGuidedCompilerFilter(String filter);
 
+    /**
+     * Returns the version of the compiler filter that is suitable for safe mode.
+     * If the input is not a valid filter, or the filter is already suitable for
+     * safe mode, this returns the input.
+     *
+     * @hide
+     */
+    public native static String getSafeModeCompilerFilter(String filter);
+
 }
diff --git a/expectations/brokentests.txt b/expectations/brokentests.txt
index cd24094..59546b5 100644
--- a/expectations/brokentests.txt
+++ b/expectations/brokentests.txt
@@ -1,145 +1,6 @@
 /*
- * This file contains expectations for tests that we'd like to eventually fix, but aren't urgent.
+ * TODO: Remove this file entirely.
  */
 [
-{
-  description: "libcore.java.io.OldFileTest#test_deleteOnExit fails on IRM05 mysid-user",
-  name: "libcore.java.io.OldFileTest#test_deleteOnExit",
-  bug: 5834665
-},
-{
-  description: "We're retiring the security manager. Unfortunately, tests all over the place
-                need to check that they're secure, so they all fail when we refuse to install
-                a security manager. This suppresses all of these failures.",
-  result: EXEC_FAILED,
-  failure: "disable securityManager",
-  pattern: ".*java.lang.SecurityException\\s+at java.lang.System.setSecurityManager.*",
-  bug: 2585285
-},
-{
-  description: "ignore compilation errors due to different available APIs",
-  result: COMPILE_FAILED,
-  failure: "ignore compilation errors",
-  pattern: ".*\\.java:\\d+: cannot find symbol.*"
-},
-{
-  description: "the average length of possible UTF-8 sequences is 2 bytes.",
-  result: EXEC_FAILED,
-  name: "org.apache.harmony.tests.java.nio.charset.UTFCharsetEncoderTest#testSpecificDefaultValue",
-  substring: "junit.framework.AssertionFailedError: expected:<1.1> but was:<2.0>"
-},
-{
-  description: "Some tests (ExcludedProxyTest) connect to a public webserver to check that the HTTP client works",
-  result: EXEC_FAILED,
-  failure: "connect to the Internet",
-  pattern: ".*java.net.UnknownHostException:.*jcltest.apache.org.*"
-},
-{
-  description: "Some tests (ExcludedProxyTest) connect to a public webserver to check that the HTTP client works",
-  result: EXEC_FAILED,
-  names: [
-    "com.android.org.apache.harmony.luni.tests.java.net.ExcludedProxyTest"
-  ]
-},
-{
-  description: "Some tests depend on ICU data, which has changed. Others make assumptions about floating point rounding",
-  result: EXEC_FAILED,
-  names: [
-    "org.apache.harmony.tests.java.util.FormatterTest#test_formatLjava_lang_String$Ljava_lang_Object_DateTimeConversion",
-    "org.apache.harmony.tests.java.util.FormatterTest#test_formatLjava_lang_String$Ljava_lang_Object_GeneralConversionOther",
-    "org.apache.harmony.tests.java.util.FormatterTest#test_formatLjava_lang_String$Ljava_lang_Object_LineSeparator",
-    "org.apache.harmony.tests.java.util.FormatterTest#test_formatLjava_lang_String$Ljava_lang_Object_Percent"
-  ]
-},
-{
-  description: "(Needs investigation) Some tests make assertions that don't make sense, others use broken port allocation logic.",
-  result: EXEC_FAILED,
-  names: [
-    "org.apache.harmony.tests.java.net.InetAddressTest#test_isReachableLjava_net_NetworkInterfaceII_loopbackInterface"
-  ]
-},
-{
-  description: "Potentially flakey because they rely on a specific local TCP port being free.",
-  result: EXEC_FAILED,
-  names: [
-      "org.apache.harmony.tests.java.nio.channels.ServerSocketChannelTest#test_bind_explicitPort"
-  ]
-},
-{
-  description: "The ResourceBundle code under test is probably not used much on Android and needs a lot of attention.",
-  modes: [device],
-  bug: 13747957,
-  names: [
-      "org.apache.harmony.tests.java.util.ControlTest#test_needsReload_LStringLLocaleLStringLClassLoaderResourceBundleJ"
-  ]
-},
-{
-  description: "Fails in CTS, passes in CoreTestRunner.",
-  result: EXEC_FAILED,
-  modes: [device],
-  names: [
-      "org.apache.harmony.tests.java.net.URLConnection#test_getContentEncoding",
-      "libcore.java.text.OldNumberFormatTest#test_parseLjava_lang_String",
-      "libcore.java.nio.channels.OldSocketChannelTest#test_writeLjava_nio_ByteBuffer_Nonblocking_HugeData",
-      "org.apache.harmony.tests.java.lang.ProcessManagerTest#testSleep",
-      "libcore.java.security.cert.OldPKIXParametersTest#testPKIXParametersKeyStore04"
-  ]
-},
-{
-  description: "Suffers from DH slowness, disabling for now.",
-  result: EXEC_FAILED,
-  names: [
-      "libcore.java.security.OldDHTest#testDHGen",
-      "libcore.java.security.OldKeyPairGeneratorTestDH#testKeyPairGenerator",
-      "libcore.javax.crypto.spec.KeyPairGeneratorTestDH#testKeyPairGenerator",
-      "libcore.javax.crypto.spec.AlgorithmParametersTestDH#testAlgorithmParameters",
-      "libcore.javax.crypto.spec.AlgorithmParameterGeneratorTestDH#testAlgorithmParameterGenerator"
-  ]
-},
-{
-  description: "Destroys MD5 provider, hurts succeeding tests",
-  result: EXEC_FAILED,
-  names: [
-      "org.apache.harmony.tests.api.javax.security.cert.X509CertificateTest#testVerifyPublicKey",
-      "org.apache.harmony.tests.api.javax.security.cert.X509CertificateTest#testVerifyPublicKeyString"
-  ]
-},
-{
-  description: "Support_TestWebServer requires isolation.",
-  result: EXEC_FAILED,
-  names: [
-      "libcore.java.net.OldURLClassLoaderTest#test_findResourceLjava_lang_String"
-  ]
-},
-{
-  description: "Causes OutOfMemoryError to test finalization",
-  result: EXEC_FAILED,
-  names: [
-      "org.apache.harmony.tests.java.lang.ref.SoftReferenceTest#test_get_SoftReference",
-      "org.apache.harmony.crypto.tests.javax.crypto#ExemptionMechanismTest#test_finalize"
-  ]
-},
-{
-  description: "Causes open dex file error",
-  modes: [device],
-  names: [
-      "org.apache.harmony.tests.java.lang.reflect.GenericSignatureFormatErrorTest#test_signatureFormatError"
-  ]
-},
-{
-  description: "Requires functional Support_Jetty",
-  bug: 28535961,
-  result: EXEC_FAILED,
-  names: [
-      "com.android.org.apache.harmony.luni.tests.java.net.URLClassLoaderTest"
-  ]
-},
-{
-  description: "Unable to execute Support_AvailTest",
-  result: EXEC_FAILED,
-  bug: 28535603,
-  names: [
-      "com.android.org.apache.harmony.luni.tests.internal.process.SystemProcessTest#test_interrupt"
-  ]
-}
+
 ]
diff --git a/expectations/icebox.txt b/expectations/icebox.txt
index db9e3ad..59546b5 100644
--- a/expectations/icebox.txt
+++ b/expectations/icebox.txt
@@ -1,149 +1,6 @@
 /*
- * This file contains expectations for tests that we'd like to eventually fix, but aren't urgent.
+ * TODO: Remove this file entirely.
  */
 [
-{
-  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
-  bug: 3268630,
-  name: "libcore.xml.DomTest#testEntityDeclarations",
-  substring: "This implementation does not parse entity declarations"
-},
-{
-  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
-  bug: 3268630,
-  name: "libcore.xml.DomTest#testGetWholeTextWithEntityReference",
-  substring: "This implementation doesn't resolve entity references in getWholeText"
-},
-{
-  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
-  name: "libcore.xml.DomTest#testExpandingEntityReferencesOff",
-  bug: 3268630,
-  substring: "This implementation doesn't include children in entity references"
-},
-{
-  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
-  name: "libcore.xml.DomTest#testExpandingEntityReferencesOn",
-  bug: 3268630,
-  substring: "This implementation doesn't expand entity references"
-},
-{
-  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
-  bug: 3268630,
-  name: "libcore.xml.DomTest#testIsElementContentWhitespaceWithDeclaration",
-  substring: "This implementation does not recognize element content whitespace"
-},
-{
-  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
-  bug: 3268630,
-  name: "libcore.xml.DomTest#testNotations",
-  substring: "This implementation does not parse notations"
-},
-{
-  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
-  bug: 3268630,
-  names: [
-    "tests.org.w3c.dom.HCNotationsRemoveNamedItemNS#testRemoveNamedItemNS",
-    "tests.org.w3c.dom.HCNotationsSetNamedItemNS#testNotationsSetNamedItemNS"
-  ]
-},
-{
-  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
-  bug: 3268630,
-  name: "libcore.xml.DeclarationTest#testGetXmlEncoding",
-  substring: "This implementation doesn't parse the encoding from the XML declaration"
-},
-{
-  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
-  bug: 3268630,
-  name: "libcore.xml.DeclarationTest#testGetXmlStandalone",
-  substring: "This implementation doesn't parse standalone from the XML declaration"
-},
-{
-  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
-  bug: 3268630,
-  name: "libcore.xml.DeclarationTest#testGetXmlVersion",
-  substring: "This implementation doesn't parse the version from the XML declaration"
-},
-{
-  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
-  bug: 3268630,
-  name: "libcore.xml.NormalizeTest#testSchemaTypeDtd",
-  substring: "This implementation's setParameter() supports an unexpected value: schema-type=http://www.w3.org/TR/REC-xml"
-},
-{
-  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
-  bug: 3268630,
-  name: "org.apache.harmony.tests.javax.xml.parsers.DocumentBuilderTest#testSetEntityResolver",
-  substring: "java.lang.ClassCastException: org.apache.harmony.xml.dom.EntityReferenceImpl"
-},
-{
-  description: "many tests attempt to fork a Java executable, but fork the wrong one",
-  result: "EXEC_FAILED",
-  failure: "should fork a dalvikvm, not a JVM",
-  substring: "/system/bin.*IOException"
-},
-{
-  description: "low-impact XML bugs:",
-  result: EXEC_FAILED,
-  name: "libcore.xml.DomTest#testAttributeNamedIdIsNotAnIdByDefault",
-  substring: "This implementation incorrectly interprets the \"id\" attribute as an identifier by default"
-},
-{
-  description: "low-impact XML bugs:",
-  result: EXEC_FAILED,
-  name: "libcore.xml.DomTest#testDocumentAddChild",
-  substring: "Document nodes shouldn't accept child nodes"
-},
-{
-  description: "low-impact XML bugs:",
-  result: EXEC_FAILED,
-  name: "libcore.xml.DomTest#testElementTraversalFeature",
-  substring: "This implementation is expected to support ElementTraversal v. 1.0 but does not."
-},
-{
-  description: "low-impact XML bugs:",
-  result: EXEC_FAILED,
-  name: "libcore.xml.DomTest#testLoadSaveFeature",
-  substring: "This implementation is expected to support LS v. 3.0 but does not."
-},
-{
-  description: "low-impact XML bugs:",
-  result: EXEC_FAILED,
-  name: "libcore.xml.SaxTest#testYesPrefixesYesNamespaces",
-  substring: "The 'namespace-prefix' feature is not supported while the 'namespaces' feature is enabled."
-},
-{
-  description: "low-impact XML bugs:",
-  result: EXEC_FAILED,
-  name: "org.apache.harmony.tests.javax.xml.parsers.SAXParserFactoryTest#test_newInstance",
-  substring: "Expected FactoryConfigurationError was not thrown"
-},
-{
-  description: "low-impact XML bugs:",
-  result: EXEC_FAILED,
-  names: [
-    "org.apache.harmony.tests.javax.xml.parsers.DocumentBuilderFactoryTest#test_isSetXIncludeAware",
-    "org.apache.harmony.tests.javax.xml.parsers.DocumentBuilderTest#testIsXIncludeAware",
-    "org.apache.harmony.tests.javax.xml.parsers.SAXParserFactoryTest#test_setIsXIncludeAware",
-    "org.apache.harmony.tests.javax.xml.parsers.SAXParserTest#testIsXIncludeAware"
-  ],
-  substring: "java.lang.UnsupportedOperationException: This parser does not support specification \"Unknown\" version \"0.0\""
-},
-{
-  description: "a low-impact bug, also present in Crockford's implementation of org.json",
-  result: EXEC_FAILED,
-  name: "org.json.ParsingTest#test64BitHexValues",
-  substring: "Large hex longs shouldn't be yield ints or strings expected:<-1> but was:<0xFFFFFFFFFFFFFFFF>"
-},
-{
-  description: "this test needs to be fixed. We supply optional qnames, but this test doesn't expect them",
-  result: EXEC_FAILED,
-  name: "org.apache.harmony.tests.javax.xml.parsers.SAXParserTest#test_parseLjava_io_InputStreamLorg_xml_sax_helpers_DefaultHandlerLjava_lang_String"
-},
-{
-  description: "BouncyCastle allows unrecognized algorithms, but RI does not, not clear if this is a bug",
-  result: EXEC_FAILED,
-  name: "org.apache.harmony.crypto.tests.javax.crypto.KeyAgreementTest#test_generateSecretLjava_lang_String",
-  substring: "junit.framework.AssertionFailedError: NoSuchAlgorithmException expected"
-}
+
 ]
diff --git a/expectations/knownfailures.txt b/expectations/knownfailures.txt
index 58a4337..2d60453 100644
--- a/expectations/knownfailures.txt
+++ b/expectations/knownfailures.txt
@@ -1,8 +1,49 @@
 /*
- * This file contains expectations for tests that were annotated with @KnownFailure at the time
+ * This file contains test expectations for libcore.
+ * TODO: Rename this file to account for the fact that it has both tags and known failures
  */
 [
 {
+  description: "large tests",
+  result: SUCCESS,
+  names: [
+    /* libcore tests that take over 15 minutes on device because of DHParametersHelper.generateSafePrimes */
+    "org.apache.harmony.crypto.tests.javax.crypto.func.KeyAgreementFunctionalTest",
+    "org.apache.harmony.crypto.tests.javax.crypto.interfaces.DHPrivateKeyTest",
+    "org.apache.harmony.crypto.tests.javax.crypto.interfaces.DHPublicKeyTest",
+    /* non-AOSP tests http://b/8027066 */
+    "java.util.EnumSet.EnumSetBash",
+    "java.io.PipedInputStream.CloseAndAvailableRC",
+    "java.io.PrintStream.OversynchronizedTest",
+    "java.io.PrintWriter.OversynchronizedTest",
+    "java.lang.String.Split",
+    "java.lang.ref.SoftReference.Pin",
+    "java.math.BigInteger.BigIntegerTest",
+    "java.net.MulticastSocket.Test",
+    "java.net.Socket.InheritTimeout",
+    "java.net.Socket.reset.Test",
+    "java.net.URLConnection.TimeoutTest",
+    "java.nio.channels.DatagramChannel.ConnectedSend",
+    "java.nio.channels.FileChannel.ExpandingMap",
+    "java.nio.channels.FileChannel.Transfers",
+    "java.nio.channels.SocketChannel.Open",
+    "java.text.Bidi.Bug6665028",
+    "java.util.Collections.FindSubList",
+    "java.util.Locale.Bug4518797",
+    "java.util.ResourceBundle.Control.StressTest",
+    "java.util.WeakHashMap.GCDuringIteration",
+    "java.util.concurrent.FutureTask.Throw",
+    "java.util.concurrent.locks.ReentrantReadWriteLock.MapLoops",
+    "java.util.zip.LargeZip",
+    "java.util.zip.ZipFile.LargeZipFile",
+    "java.util.zip.ZipFile.ManyEntries",
+    "libcore.java.lang.SystemTest_testArrayCopyConcurrentModification",
+    "sun.nio.cs.FindOneCharEncoderBugs",
+    "sun.nio.cs.SurrogateGB18030Test"
+  ],
+  "tags": [ "large" ]
+},
+{
   description: "can't compile a pattern with negative look-behind and quantifiers with upper bounds",
   result: EXEC_FAILED,
   name: "org.apache.harmony.regex.tests.java.util.regex.PatternTest#test_bug_40103",
@@ -1537,5 +1578,289 @@
   names: [
     "libcore.java.net.SocketTimeoutTest#testSocketWriteNeverTimeouts"
   ]
+},
+{
+  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
+  bug: 3268630,
+  name: "libcore.xml.DomTest#testEntityDeclarations",
+  substring: "This implementation does not parse entity declarations"
+},
+{
+  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
+  bug: 3268630,
+  name: "libcore.xml.DomTest#testGetWholeTextWithEntityReference",
+  substring: "This implementation doesn't resolve entity references in getWholeText"
+},
+{
+  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
+  name: "libcore.xml.DomTest#testExpandingEntityReferencesOff",
+  bug: 3268630,
+  substring: "This implementation doesn't include children in entity references"
+},
+{
+  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
+  name: "libcore.xml.DomTest#testExpandingEntityReferencesOn",
+  bug: 3268630,
+  substring: "This implementation doesn't expand entity references"
+},
+{
+  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
+  bug: 3268630,
+  name: "libcore.xml.DomTest#testIsElementContentWhitespaceWithDeclaration",
+  substring: "This implementation does not recognize element content whitespace"
+},
+{
+  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
+  bug: 3268630,
+  name: "libcore.xml.DomTest#testNotations",
+  substring: "This implementation does not parse notations"
+},
+{
+  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
+  bug: 3268630,
+  names: [
+    "tests.org.w3c.dom.HCNotationsRemoveNamedItemNS#testRemoveNamedItemNS",
+    "tests.org.w3c.dom.HCNotationsSetNamedItemNS#testNotationsSetNamedItemNS"
+  ]
+},
+{
+  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
+  bug: 3268630,
+  name: "libcore.xml.DeclarationTest#testGetXmlEncoding",
+  substring: "This implementation doesn't parse the encoding from the XML declaration"
+},
+{
+  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
+  bug: 3268630,
+  name: "libcore.xml.DeclarationTest#testGetXmlStandalone",
+  substring: "This implementation doesn't parse standalone from the XML declaration"
+},
+{
+  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
+  bug: 3268630,
+  name: "libcore.xml.DeclarationTest#testGetXmlVersion",
+  substring: "This implementation doesn't parse the version from the XML declaration"
+},
+{
+  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
+  bug: 3268630,
+  name: "libcore.xml.NormalizeTest#testSchemaTypeDtd",
+  substring: "This implementation's setParameter() supports an unexpected value: schema-type=http://www.w3.org/TR/REC-xml"
+},
+{
+  description: "Dalvik doesn't support XML Schemas, DTDs or validation",
+  bug: 3268630,
+  name: "org.apache.harmony.tests.javax.xml.parsers.DocumentBuilderTest#testSetEntityResolver",
+  substring: "java.lang.ClassCastException: org.apache.harmony.xml.dom.EntityReferenceImpl"
+},
+{
+  description: "many tests attempt to fork a Java executable, but fork the wrong one",
+  result: "EXEC_FAILED",
+  failure: "should fork a dalvikvm, not a JVM",
+  substring: "/system/bin.*IOException"
+},
+{
+  description: "low-impact XML bugs:",
+  result: EXEC_FAILED,
+  name: "libcore.xml.DomTest#testAttributeNamedIdIsNotAnIdByDefault",
+  substring: "This implementation incorrectly interprets the \"id\" attribute as an identifier by default"
+},
+{
+  description: "low-impact XML bugs:",
+  result: EXEC_FAILED,
+  name: "libcore.xml.DomTest#testDocumentAddChild",
+  substring: "Document nodes shouldn't accept child nodes"
+},
+{
+  description: "low-impact XML bugs:",
+  result: EXEC_FAILED,
+  name: "libcore.xml.DomTest#testElementTraversalFeature",
+  substring: "This implementation is expected to support ElementTraversal v. 1.0 but does not."
+},
+{
+  description: "low-impact XML bugs:",
+  result: EXEC_FAILED,
+  name: "libcore.xml.DomTest#testLoadSaveFeature",
+  substring: "This implementation is expected to support LS v. 3.0 but does not."
+},
+{
+  description: "low-impact XML bugs:",
+  result: EXEC_FAILED,
+  name: "libcore.xml.SaxTest#testYesPrefixesYesNamespaces",
+  substring: "The 'namespace-prefix' feature is not supported while the 'namespaces' feature is enabled."
+},
+{
+  description: "low-impact XML bugs:",
+  result: EXEC_FAILED,
+  name: "org.apache.harmony.tests.javax.xml.parsers.SAXParserFactoryTest#test_newInstance",
+  substring: "Expected FactoryConfigurationError was not thrown"
+},
+{
+  description: "low-impact XML bugs:",
+  result: EXEC_FAILED,
+  names: [
+    "org.apache.harmony.tests.javax.xml.parsers.DocumentBuilderFactoryTest#test_isSetXIncludeAware",
+    "org.apache.harmony.tests.javax.xml.parsers.DocumentBuilderTest#testIsXIncludeAware",
+    "org.apache.harmony.tests.javax.xml.parsers.SAXParserFactoryTest#test_setIsXIncludeAware",
+    "org.apache.harmony.tests.javax.xml.parsers.SAXParserTest#testIsXIncludeAware"
+  ],
+  substring: "java.lang.UnsupportedOperationException: This parser does not support specification \"Unknown\" version \"0.0\""
+},
+{
+  description: "a low-impact bug, also present in Crockford's implementation of org.json",
+  result: EXEC_FAILED,
+  name: "org.json.ParsingTest#test64BitHexValues",
+  substring: "Large hex longs shouldn't be yield ints or strings expected:<-1> but was:<0xFFFFFFFFFFFFFFFF>"
+},
+{
+  description: "this test needs to be fixed. We supply optional qnames, but this test doesn't expect them",
+  result: EXEC_FAILED,
+  name: "org.apache.harmony.tests.javax.xml.parsers.SAXParserTest#test_parseLjava_io_InputStreamLorg_xml_sax_helpers_DefaultHandlerLjava_lang_String"
+},
+{
+  description: "BouncyCastle allows unrecognized algorithms, but RI does not, not clear if this is a bug",
+  result: EXEC_FAILED,
+  name: "org.apache.harmony.crypto.tests.javax.crypto.KeyAgreementTest#test_generateSecretLjava_lang_String",
+  substring: "junit.framework.AssertionFailedError: NoSuchAlgorithmException expected"
+},
+{
+  description: "libcore.java.io.OldFileTest#test_deleteOnExit fails on IRM05 mysid-user",
+  name: "libcore.java.io.OldFileTest#test_deleteOnExit",
+  bug: 5834665
+},
+{
+  description: "We're retiring the security manager. Unfortunately, tests all over the place
+                need to check that they're secure, so they all fail when we refuse to install
+                a security manager. This suppresses all of these failures.",
+  result: EXEC_FAILED,
+  failure: "disable securityManager",
+  pattern: ".*java.lang.SecurityException\\s+at java.lang.System.setSecurityManager.*",
+  bug: 2585285
+},
+{
+  description: "ignore compilation errors due to different available APIs",
+  result: COMPILE_FAILED,
+  failure: "ignore compilation errors",
+  pattern: ".*\\.java:\\d+: cannot find symbol.*"
+},
+{
+  description: "the average length of possible UTF-8 sequences is 2 bytes.",
+  result: EXEC_FAILED,
+  name: "org.apache.harmony.tests.java.nio.charset.UTFCharsetEncoderTest#testSpecificDefaultValue",
+  substring: "junit.framework.AssertionFailedError: expected:<1.1> but was:<2.0>"
+},
+{
+  description: "Some tests (ExcludedProxyTest) connect to a public webserver to check that the HTTP client works",
+  result: EXEC_FAILED,
+  failure: "connect to the Internet",
+  pattern: ".*java.net.UnknownHostException:.*jcltest.apache.org.*"
+},
+{
+  description: "Some tests (ExcludedProxyTest) connect to a public webserver to check that the HTTP client works",
+  result: EXEC_FAILED,
+  names: [
+    "com.android.org.apache.harmony.luni.tests.java.net.ExcludedProxyTest"
+  ]
+},
+{
+  description: "Some tests depend on ICU data, which has changed. Others make assumptions about floating point rounding",
+  result: EXEC_FAILED,
+  names: [
+    "org.apache.harmony.tests.java.util.FormatterTest#test_formatLjava_lang_String$Ljava_lang_Object_DateTimeConversion",
+    "org.apache.harmony.tests.java.util.FormatterTest#test_formatLjava_lang_String$Ljava_lang_Object_GeneralConversionOther",
+    "org.apache.harmony.tests.java.util.FormatterTest#test_formatLjava_lang_String$Ljava_lang_Object_LineSeparator",
+    "org.apache.harmony.tests.java.util.FormatterTest#test_formatLjava_lang_String$Ljava_lang_Object_Percent"
+  ]
+},
+{
+  description: "(Needs investigation) Some tests make assertions that don't make sense, others use broken port allocation logic.",
+  result: EXEC_FAILED,
+  names: [
+    "org.apache.harmony.tests.java.net.InetAddressTest#test_isReachableLjava_net_NetworkInterfaceII_loopbackInterface"
+  ]
+},
+{
+  description: "Potentially flakey because they rely on a specific local TCP port being free.",
+  result: EXEC_FAILED,
+  names: [
+      "org.apache.harmony.tests.java.nio.channels.ServerSocketChannelTest#test_bind_explicitPort"
+  ]
+},
+{
+  description: "The ResourceBundle code under test is probably not used much on Android and needs a lot of attention.",
+  modes: [device],
+  bug: 13747957,
+  names: [
+      "org.apache.harmony.tests.java.util.ControlTest#test_needsReload_LStringLLocaleLStringLClassLoaderResourceBundleJ"
+  ]
+},
+{
+  description: "Fails in CTS, passes in CoreTestRunner.",
+  result: EXEC_FAILED,
+  modes: [device],
+  names: [
+      "org.apache.harmony.tests.java.net.URLConnection#test_getContentEncoding",
+      "libcore.java.text.OldNumberFormatTest#test_parseLjava_lang_String",
+      "libcore.java.nio.channels.OldSocketChannelTest#test_writeLjava_nio_ByteBuffer_Nonblocking_HugeData",
+      "org.apache.harmony.tests.java.lang.ProcessManagerTest#testSleep",
+      "libcore.java.security.cert.OldPKIXParametersTest#testPKIXParametersKeyStore04"
+  ]
+},
+{
+  description: "Suffers from DH slowness, disabling for now.",
+  result: EXEC_FAILED,
+  names: [
+      "libcore.java.security.OldDHTest#testDHGen",
+      "libcore.java.security.OldKeyPairGeneratorTestDH#testKeyPairGenerator",
+      "libcore.javax.crypto.spec.KeyPairGeneratorTestDH#testKeyPairGenerator",
+      "libcore.javax.crypto.spec.AlgorithmParametersTestDH#testAlgorithmParameters",
+      "libcore.javax.crypto.spec.AlgorithmParameterGeneratorTestDH#testAlgorithmParameterGenerator"
+  ]
+},
+{
+  description: "Destroys MD5 provider, hurts succeeding tests",
+  result: EXEC_FAILED,
+  names: [
+      "org.apache.harmony.tests.api.javax.security.cert.X509CertificateTest#testVerifyPublicKey",
+      "org.apache.harmony.tests.api.javax.security.cert.X509CertificateTest#testVerifyPublicKeyString"
+  ]
+},
+{
+  description: "Support_TestWebServer requires isolation.",
+  result: EXEC_FAILED,
+  names: [
+      "libcore.java.net.OldURLClassLoaderTest#test_findResourceLjava_lang_String"
+  ]
+},
+{
+  description: "Causes OutOfMemoryError to test finalization",
+  result: EXEC_FAILED,
+  names: [
+      "org.apache.harmony.tests.java.lang.ref.SoftReferenceTest#test_get_SoftReference",
+      "org.apache.harmony.crypto.tests.javax.crypto#ExemptionMechanismTest#test_finalize"
+  ]
+},
+{
+  description: "Causes open dex file error",
+  modes: [device],
+  names: [
+      "org.apache.harmony.tests.java.lang.reflect.GenericSignatureFormatErrorTest#test_signatureFormatError"
+  ]
+},
+{
+  description: "Requires functional Support_Jetty",
+  bug: 28535961,
+  result: EXEC_FAILED,
+  names: [
+      "com.android.org.apache.harmony.luni.tests.java.net.URLClassLoaderTest"
+  ]
+},
+{
+  description: "Unable to execute Support_AvailTest",
+  result: EXEC_FAILED,
+  bug: 28535603,
+  names: [
+      "com.android.org.apache.harmony.luni.tests.internal.process.SystemProcessTest#test_interrupt"
+  ]
 }
 ]
diff --git a/expectations/taggedtests.txt b/expectations/taggedtests.txt
index cc2a4d6..d13cdd4 100644
--- a/expectations/taggedtests.txt
+++ b/expectations/taggedtests.txt
@@ -1,46 +1,5 @@
 /*
- * This file contains expectations for tests that require support from the test runner to complete
- * successfully.
+ * TODO: Remove this file entirely.
  */
 [
-{
-  description: "large tests",
-  result: SUCCESS,
-  names: [
-    /* libcore tests that take over 15 minutes on device because of DHParametersHelper.generateSafePrimes */
-    "org.apache.harmony.crypto.tests.javax.crypto.func.KeyAgreementFunctionalTest",
-    "org.apache.harmony.crypto.tests.javax.crypto.interfaces.DHPrivateKeyTest",
-    "org.apache.harmony.crypto.tests.javax.crypto.interfaces.DHPublicKeyTest",
-    /* non-AOSP tests http://b/8027066 */
-    "java.util.EnumSet.EnumSetBash",
-    "java.io.PipedInputStream.CloseAndAvailableRC",
-    "java.io.PrintStream.OversynchronizedTest",
-    "java.io.PrintWriter.OversynchronizedTest",
-    "java.lang.String.Split",
-    "java.lang.ref.SoftReference.Pin",
-    "java.math.BigInteger.BigIntegerTest",
-    "java.net.MulticastSocket.Test",
-    "java.net.Socket.InheritTimeout",
-    "java.net.Socket.reset.Test",
-    "java.net.URLConnection.TimeoutTest",
-    "java.nio.channels.DatagramChannel.ConnectedSend",
-    "java.nio.channels.FileChannel.ExpandingMap",
-    "java.nio.channels.FileChannel.Transfers",
-    "java.nio.channels.SocketChannel.Open",
-    "java.text.Bidi.Bug6665028",
-    "java.util.Collections.FindSubList",
-    "java.util.Locale.Bug4518797",
-    "java.util.ResourceBundle.Control.StressTest",
-    "java.util.WeakHashMap.GCDuringIteration",
-    "java.util.concurrent.FutureTask.Throw",
-    "java.util.concurrent.locks.ReentrantReadWriteLock.MapLoops",
-    "java.util.zip.LargeZip",
-    "java.util.zip.ZipFile.LargeZipFile",
-    "java.util.zip.ZipFile.ManyEntries",
-    "libcore.java.lang.SystemTest_testArrayCopyConcurrentModification",
-    "sun.nio.cs.FindOneCharEncoderBugs",
-    "sun.nio.cs.SurrogateGB18030Test"
-  ],
-  "tags": [ "large" ]
-}
 ]
diff --git a/luni/src/test/java/libcore/java/lang/reflect/parameter/README.txt b/luni/src/test/java/libcore/java/lang/reflect/parameter/README.txt
index 6d5a6c2..90a40df 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/parameter/README.txt
+++ b/luni/src/test/java/libcore/java/lang/reflect/parameter/README.txt
@@ -8,7 +8,7 @@
 Regenerate the .dex files with:
 
 make smali
-smali libcore/luni/src/test/java/libcore/java/lang/reflect/parameter/ParameterMetdataTestClasses*.smali \
+smali assemble libcore/luni/src/test/java/libcore/java/lang/reflect/parameter/ParameterMetdataTestClasses*.smali \
     -o libcore/luni/src/test/resources/libcore/java/lang/reflect/parameter/parameter_metadata_test_classes.dex
 
 For reference, the valid smali code should be (roughly) the equivalent of the
diff --git a/luni/src/test/java/libcore/sun/util/logging/PlatformLoggerTest.java b/luni/src/test/java/libcore/sun/util/logging/PlatformLoggerTest.java
new file mode 100644
index 0000000..d48d92a
--- /dev/null
+++ b/luni/src/test/java/libcore/sun/util/logging/PlatformLoggerTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 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.sun.util.logging;
+
+import junit.framework.TestCase;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.logging.Level;
+
+import sun.util.logging.PlatformLogger;
+
+public class PlatformLoggerTest extends TestCase {
+
+    /**
+     * Checks that the values of the private static final int constants in
+     * {@link PlatformLogger} code match the corresponding
+     * {@link Level#intValue()}. This constraint is mentioned in a comment
+     * in PlatformLogger.java.
+     */
+    public void testLogLevelConstants() throws Exception {
+        assertLogLevel("SEVERE", Level.SEVERE);
+        assertLogLevel("WARNING", Level.WARNING);
+        assertLogLevel("INFO", Level.INFO);
+        assertLogLevel("CONFIG", Level.CONFIG);
+        assertLogLevel("FINE", Level.FINE);
+        assertLogLevel("FINER", Level.FINER);
+        assertLogLevel("FINEST", Level.FINEST);
+        assertLogLevel("ALL", Level.ALL);
+        assertLogLevel("OFF", Level.OFF);
+    }
+
+    private void assertLogLevel(String levelName, Level javaUtilLoggingLevel) throws Exception {
+        Field field =  PlatformLogger.class.getDeclaredField(levelName);
+        field.setAccessible(true);
+        int platformLoggerValue = field.getInt(PlatformLogger.class);
+        int javaUtilLoggingValue = javaUtilLoggingLevel.intValue();
+        assertEquals(levelName, javaUtilLoggingValue, platformLoggerValue);
+
+        // Check that the field is a constant (static and final); we don't care about
+        // other modifiers (public/private).
+        int requiredModifiers = Modifier.STATIC | Modifier.FINAL;
+        assertEquals(requiredModifiers, field.getModifiers() & requiredModifiers);
+    }
+
+}
diff --git a/ojluni/src/main/java/java/awt/font/TextAttribute.java b/ojluni/src/main/java/java/awt/font/TextAttribute.java
index 04a921d..7dff4ad 100644
--- a/ojluni/src/main/java/java/awt/font/TextAttribute.java
+++ b/ojluni/src/main/java/java/awt/font/TextAttribute.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2006, 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
@@ -45,6 +45,8 @@
 import java.util.Map;
 import java.util.HashMap;
 
+// Android-removed: List of classes for use with attribute keys; Android doesn't have those.
+// Android-removed: "Summary of attributes" section. Android doesn't have the referenced classes.
 /**
  * The <code>TextAttribute</code> class defines attribute keys and
  * attribute values used for text rendering.
@@ -62,7 +64,7 @@
  *   <LI>a description of the effect.
  * </UL>
  * <p>
- * <H4>Values</H4>
+ * <H3>Values</H3>
  * <UL>
  *   <LI>The values of attributes must always be immutable.
  *   <LI>Where value limitations are given, any value outside of that
@@ -90,178 +92,12 @@
  *
  * </UL>
  *
- * @see java.text.AttributedCharacterIterator
  */
-
-// Android-removed: Removed Summary of Attributes.
-/* <h4>Summary of attributes</h4>
- * <p>
- * <font size="-1">
- * <table align="center" border="0" cellspacing="0" cellpadding="2" width="%95"
- *     summary="Key, value type, principal constants, and default value
- *     behavior of all TextAttributes">
- * <tr bgcolor="#ccccff">
- * <th valign="TOP" align="CENTER">Key</th>
- * <th valign="TOP" align="CENTER">Value Type</th>
- * <th valign="TOP" align="CENTER">Principal Constants</th>
- * <th valign="TOP" align="CENTER">Default Value</th>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #FAMILY}</td>
- * <td valign="TOP">String</td>
- * <td valign="TOP">See Font {@link java.awt.Font#DIALOG DIALOG},
-{@link java.awt.Font#DIALOG_INPUT DIALOG_INPUT},<br> {@link java.awt.Font#SERIF SERIF},
-{@link java.awt.Font#SANS_SERIF SANS_SERIF}, and {@link java.awt.Font#MONOSPACED MONOSPACED}.
-</td>
- * <td valign="TOP">"Default" (use platform default)</td>
- * </tr>
- * <tr bgcolor="#eeeeff">
- * <td valign="TOP">{@link #WEIGHT}</td>
- * <td valign="TOP">Number</td>
- * <td valign="TOP">WEIGHT_REGULAR, WEIGHT_BOLD</td>
- * <td valign="TOP">WEIGHT_REGULAR</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #WIDTH}</td>
- * <td valign="TOP">Number</td>
- * <td valign="TOP">WIDTH_CONDENSED, WIDTH_REGULAR,<br>WIDTH_EXTENDED</td>
- * <td valign="TOP">WIDTH_REGULAR</td>
- * </tr>
- * <tr bgcolor="#eeeeff">
- * <td valign="TOP">{@link #POSTURE}</td>
- * <td valign="TOP">Number</td>
- * <td valign="TOP">POSTURE_REGULAR, POSTURE_OBLIQUE</td>
- * <td valign="TOP">POSTURE_REGULAR</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #SIZE}</td>
- * <td valign="TOP">Number</td>
- * <td valign="TOP">none</td>
- * <td valign="TOP">12.0</td>
- * </tr>
- * <tr bgcolor="#eeeeff">
- * <td valign="TOP">{@link #TRANSFORM}</td>
- * <td valign="TOP">{@link TransformAttribute}</td>
- * <td valign="TOP">See TransformAttribute {@link TransformAttribute#IDENTITY IDENTITY}</td>
- * <td valign="TOP">TransformAttribute.IDENTITY</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #SUPERSCRIPT}</td>
- * <td valign="TOP">Integer</td>
- * <td valign="TOP">SUPERSCRIPT_SUPER, SUPERSCRIPT_SUB</td>
- * <td valign="TOP">0 (use the standard glyphs and metrics)</td>
- * </tr>
- * <tr bgcolor="#eeeeff">
- * <td valign="TOP">{@link #FONT}</td>
- * <td valign="TOP">{@link java.awt.Font}</td>
- * <td valign="TOP">none</td>
- * <td valign="TOP">null (do not override font resolution)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #CHAR_REPLACEMENT}</td>
- * <td valign="TOP">{@link GraphicAttribute}</td>
- * <td valign="TOP">none</td>
- * <td valign="TOP">null (draw text using font glyphs)</td>
- * </tr>
- * <tr bgcolor="#eeeeff">
- * <td valign="TOP">{@link #FOREGROUND}</td>
- * <td valign="TOP">{@link java.awt.Paint}</td>
- * <td valign="TOP">none</td>
- * <td valign="TOP">null (use current graphics paint)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #BACKGROUND}</td>
- * <td valign="TOP">{@link java.awt.Paint}</td>
- * <td valign="TOP">none</td>
- * <td valign="TOP">null (do not render background)</td>
- * </tr>
- * <tr bgcolor="#eeeeff">
- * <td valign="TOP">{@link #UNDERLINE}</td>
- * <td valign="TOP">Integer</td>
- * <td valign="TOP">UNDERLINE_ON</td>
- * <td valign="TOP">-1 (do not render underline)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #STRIKETHROUGH}</td>
- * <td valign="TOP">Boolean</td>
- * <td valign="TOP">STRIKETHROUGH_ON</td>
- * <td valign="TOP">false (do not render strikethrough)</td>
- * </tr>
- * <tr bgcolor="#eeeeff">
- * <td valign="TOP">{@link #RUN_DIRECTION}</td>
- * <td valign="TOP">Boolean</td>
- * <td valign="TOP">RUN_DIRECTION_LTR<br>RUN_DIRECTION_RTL</td>
- * <td valign="TOP">null (use {@link java.text.Bidi} standard default)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #BIDI_EMBEDDING}</td>
- * <td valign="TOP">Integer</td>
- * <td valign="TOP">none</td>
- * <td valign="TOP">0 (use base line direction)</td>
- * </tr>
- * <tr bgcolor="#eeeeff">
- * <td valign="TOP">{@link #JUSTIFICATION}</td>
- * <td valign="TOP">Number</td>
- * <td valign="TOP">JUSTIFICATION_FULL</td>
- * <td valign="TOP">JUSTIFICATION_FULL</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #INPUT_METHOD_HIGHLIGHT}</td>
- * <td valign="TOP">{@link java.awt.im.InputMethodHighlight},<br>{@link java.text.Annotation}</td>
- * <td valign="TOP">(see class)</td>
- * <td valign="TOP">null (do not apply input highlighting)</td>
- * </tr>
- * <tr bgcolor="#eeeeff">
- * <td valign="TOP">{@link #INPUT_METHOD_UNDERLINE}</td>
- * <td valign="TOP">Integer</td>
- * <td valign="TOP">UNDERLINE_LOW_ONE_PIXEL,<br>UNDERLINE_LOW_TWO_PIXEL</td>
- * <td valign="TOP">-1 (do not render underline)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #SWAP_COLORS}</td>
- * <td valign="TOP">Boolean</td>
- * <td valign="TOP">SWAP_COLORS_ON</td>
- * <td valign="TOP">false (do not swap colors)</td>
- * </tr>
- * <tr bgcolor="#eeeeff">
- * <td valign="TOP">{@link #NUMERIC_SHAPING}</td>
- * <td valign="TOP">{@link java.awt.font.NumericShaper}</td>
- * <td valign="TOP">none</td>
- * <td valign="TOP">null (do not shape digits)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #KERNING}</td>
- * <td valign="TOP">Integer</td>
- * <td valign="TOP">KERNING_ON</td>
- * <td valign="TOP">0 (do not request kerning)</td>
- * </tr>
- * <tr bgcolor="#eeeeff">
- * <td valign="TOP">{@link #LIGATURES}</td>
- * <td valign="TOP">Integer</td>
- * <td valign="TOP">LIGATURES_ON</td>
- * <td valign="TOP">0 (do not form optional ligatures)</td>
- * </tr>
- * <tr>
- * <td valign="TOP">{@link #TRACKING}</td>
- * <td valign="TOP">Number</td>
- * <td valign="TOP">TRACKING_LOOSE, TRACKING_TIGHT</td>
- * <td valign="TOP">0 (do not add tracking)</td>
- * </tr>
- * </table>
- * </font>
- *
- * @see java.awt.Font
- * @see java.awt.font.TextLayout
- */
-// Android-removed
-//
-// {@link java.awt.Font Font},
-// {@link java.awt.font.TextLayout TextLayout},
-// {@link java.text.AttributedCharacterIterator AttributedCharacterIterator},
 public final class TextAttribute extends Attribute {
 
     // table of all instances in this class, used by readResolve
-    private static final Map instanceMap = new HashMap(29);
+    private static final Map<String, TextAttribute>
+            instanceMap = new HashMap<String, TextAttribute>(29);
 
     /**
      * Constructs a <code>TextAttribute</code> with the specified name.
@@ -284,7 +120,7 @@
                 "subclass didn't correctly implement readResolve");
         }
 
-        TextAttribute instance = (TextAttribute) instanceMap.get(getName());
+        TextAttribute instance = instanceMap.get(getName());
         if (instance != null) {
             return instance;
         } else {
@@ -302,6 +138,7 @@
     // For use with Font.
     //
 
+    // Android-removed: Don't link to java.awt.Font class, it doesn't exist on Android.
     /**
      * Attribute key for the font name.  Values are instances of
      * <b><code>String</code></b>.  The default value is
@@ -324,13 +161,6 @@
      * The "Bold" in the name is part of the face name, not a separate
      * request that the font's weight be bold.</p>
      */
-    // Android-removed links to font names.
-    //
-    // {@link java.awt.Font#DIALOG DIALOG},
-    // {@link java.awt.Font#DIALOG_INPUT DIALOG_INPUT},
-    // {@link java.awt.Font#SANS_SERIF SANS_SERIF},
-    // {@link java.awt.Font#SERIF SERIF}, and
-    // {@link java.awt.Font#MONOSPACED MONOSPACED}.
     public static final TextAttribute FAMILY =
         new TextAttribute("family");
 
@@ -490,6 +320,7 @@
     public static final Float WIDTH_EXTENDED =
         Float.valueOf(1.5f);
 
+    // Android-removed: Don't link to java.awt.Font class, it doesn't exist on Android.
     /**
      * Attribute key for the posture of a font.  Values are instances
      * of <b><code>Number</code></b>. The default value is
@@ -510,8 +341,6 @@
      * <code>Font.getItalicAngle</code>.
      *
      */
-    // Android-removed.
-    // @see java.awt.Font#getItalicAngle()
     public static final TextAttribute POSTURE =
         new TextAttribute("posture");
 
@@ -548,6 +377,8 @@
     public static final TextAttribute SIZE =
         new TextAttribute("size");
 
+    // Android-removed: References to classes that don't exist on Android.
+    // These classes were AffineTransform, Font, and TransformAttribute.
     /**
      * Attribute key for the transform of a font.  Values are
      * instances of <b><code>TransformAttribute</code></b>.  The
@@ -566,23 +397,6 @@
      * with a rotated TRANSFORM and an unrotated TRANSFORM will measure as
      * having the same ascent, descent, and advance.</p>
      */
-     // Android-removed
-     //
-     // <p>This corresponds to the transform passed to
-     // <code>Font.deriveFont(AffineTransform)</code>.  Since that
-     // transform is mutable and <code>TextAttribute</code> values must
-     // not be, the <code>TransformAttribute</code> wrapper class is
-     // used.
-     //
-     // <p>The <code>TransformAttribute</code> class defines the
-     // constant {@link TransformAttribute#IDENTITY IDENTITY}.
-     // @see TransformAttribute
-     // @see java.awt.geom.AffineTransform
-     //
-     // <p>In styled text, the baselines for each such run are aligned
-     // one after the other to potentially create a non-linear baseline
-     // for the entire run of text. For more information, see {@link
-     // TextLayout#getLayoutPath}.</p>
      public static final TextAttribute TRANSFORM =
         new TextAttribute("transform");
 
@@ -621,6 +435,7 @@
     public static final Integer SUPERSCRIPT_SUB =
         Integer.valueOf(-1);
 
+    // Android-removed: Don't link to java.awt.Font class, it doesn't exist on Android.
     /**
      * Attribute key used to provide the font to use to render text.
      *
@@ -673,17 +488,6 @@
      * <code>Font</code> but can be overridden by other values in the
      * <code>Map</code>.
      */
-    // Android-removed
-    // Values are instances of {@link java.awt.Font}.
-    //
-    // <p><em>Note:</em><code>Font's</code> <code>Map</code>-based
-    // constructor and <code>deriveFont</code> methods do not process
-    // the <code>FONT</code> attribute, as these are used to create
-    // new <code>Font</code> objects.  Instead, {@link
-    // java.awt.Font#getFont(Map) Font.getFont(Map)} should be used to
-    // handle the <code>FONT</code> attribute.
-    //
-    // @see java.awt.Font
     public static final TextAttribute FONT =
         new TextAttribute("font");
 
@@ -900,6 +704,7 @@
     // For use by input method.
     //
 
+    // Android-removed: References to java.awt.im.InputMethodHighlight (doesn't exist on Android).
     /**
      * Attribute key for input method highlight styles.
      *
@@ -909,24 +714,6 @@
      *
      * @see java.text.Annotation
      */
-    // Android-removed
-    //
-    // <p>Values are instances of {@link
-    // java.awt.im.InputMethodHighlight} or {@link
-    // java.text.Annotation}.
-    // 
-    // <p>If adjacent runs of text with the same
-    // <code>InputMethodHighlight</code> need to be rendered
-    // separately, the <code>InputMethodHighlights</code> should be
-    // wrapped in <code>Annotation</code> instances.
-    //
-    // <p>Input method highlights are used while text is being
-    // composed by an input method. Text editing components should
-    // retain them even if they generally only deal with unstyled
-    // text, and make them available to the drawing routines.
-    //
-    // @see java.awt.Font
-    // @see java.awt.im.InputMethodHighlight
     public static final TextAttribute INPUT_METHOD_HIGHLIGHT =
         new TextAttribute("input method highlight");
 
diff --git a/ojluni/src/main/java/java/io/RandomAccessFile.java b/ojluni/src/main/java/java/io/RandomAccessFile.java
index 34eb7ab..f4830c1 100755
--- a/ojluni/src/main/java/java/io/RandomAccessFile.java
+++ b/ojluni/src/main/java/java/io/RandomAccessFile.java
@@ -65,10 +65,12 @@
 
 public class RandomAccessFile implements DataOutput, DataInput, Closeable {
 
+    // BEGIN Android-added: CloseGuard and some helper fields for Android changes in this file.
     private final CloseGuard guard = CloseGuard.get();
     private final byte[] scratch = new byte[8];
     private boolean syncMetadata = false;
     private int mode;
+    // END Android-added: CloseGuard and some helper fields for Android changes in this file.
 
     private FileDescriptor fd;
     private FileChannel channel = null;
@@ -82,11 +84,14 @@
 
     private Object closeLock = new Object();
     private volatile boolean closed = false;
+
+    // BEGIN Android-added: IoTracker.
     /**
      * A single tracker to track both read and write. The tracker resets when the operation
      * performed is different from the operation last performed.
      */
     private final IoTracker ioTracker = new IoTracker();
+    // END Android-added: IoTracker.
 
     /**
      * Creates a random access file stream to read from, and optionally
@@ -216,43 +221,57 @@
         throws FileNotFoundException
     {
         String name = (file != null ? file.getPath() : null);
-        this.mode = -1;
+        int imode = -1;
         if (mode.equals("r")) {
-            this.mode = O_RDONLY;
+            imode = O_RDONLY;
         } else if (mode.startsWith("rw")) {
             // Android-changed: Added. O_CREAT
-            this.mode = O_RDWR | O_CREAT;
+            // imode = O_RDWR;
+            imode = O_RDWR | O_CREAT;
             rw = true;
             if (mode.length() > 2) {
                 if (mode.equals("rws")) {
+                    // Android-changed: Don't use O_SYNC for "rws". Is this correct?
+                    // imode |= O_SYNC;
                     syncMetadata = true;
                 } else if (mode.equals("rwd")) {
-                    // Android-changed: Should this be O_DSYNC and the above O_SYNC ?
-                    this.mode |= O_SYNC;
+                    // Android-changed: Use O_SYNC rather than O_DSYNC for "rwd". Is this correct?
+                    // imode |= O_DSYNC;
+                    imode |= O_SYNC;
                 } else {
-                    this.mode = -1;
+                    imode = -1;
                 }
             }
         }
-
-        if (this.mode < 0) {
+        if (imode < 0) {
             throw new IllegalArgumentException("Illegal mode \"" + mode
                                                + "\" must be one of "
                                                + "\"r\", \"rw\", \"rws\","
                                                + " or \"rwd\"");
         }
-
+        // Android-removed: do not use legacy security code
+        /*
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkRead(name);
+            if (rw) {
+                security.checkWrite(name);
+            }
+        }
+        */
         if (name == null) {
+            // Android-changed: different exception message in ctor when file == null.
+            // throw new NullPointerException();
             throw new NullPointerException("file == null");
         }
-
         if (file.isInvalid()) {
             throw new FileNotFoundException("Invalid file path");
         }
         this.path = name;
+        this.mode = imode;
 
-        // Android-changed: Use IoBridge.open() instead of open.
-        fd = IoBridge.open(file.getPath(), this.mode);
+        // BEGIN Android-changed: Use IoBridge.open() instead of open.
+        fd = IoBridge.open(name, imode);
         if (syncMetadata) {
             try {
                 fd.sync();
@@ -261,6 +280,7 @@
             }
         }
         guard.open("close");
+        // END Android-changed: Use IoBridge.open() instead of open.
     }
 
     /**
@@ -321,6 +341,8 @@
      *                          end-of-file has been reached.
      */
     public int read() throws IOException {
+        // Android-changed: Implement on top of low-level API, not directly natively.
+        // return read0();
         return (read(scratch, 0, 1) != -1) ? scratch[0] & 0xff : -1;
     }
 
@@ -332,6 +354,7 @@
      * @exception IOException If an I/O error has occurred.
      */
     private int readBytes(byte b[], int off, int len) throws IOException {
+        // Android-changed: Implement on top of low-level API, not directly natively.
         ioTracker.trackIo(len, IoTracker.Mode.READ);
         return IoBridge.read(fd, b, off, len);
     }
@@ -474,6 +497,8 @@
      * @exception  IOException  if an I/O error occurs.
      */
     public void write(int b) throws IOException {
+        // Android-changed: Implement on top of low-level API, not directly natively.
+        // write0(b);
         scratch[0] = (byte) (b & 0xff);
         write(scratch, 0, 1);
     }
@@ -481,11 +506,13 @@
     /**
      * Writes a sub array as a sequence of bytes.
      * @param b the data to be written
+
      * @param off the start offset in the data
      * @param len the number of bytes that are written
      * @exception IOException If an I/O error has occurred.
      */
     private void writeBytes(byte b[], int off, int len) throws IOException {
+        // Android-changed: Implement on top of low-level API, not directly natively.
         ioTracker.trackIo(len, IoTracker.Mode.WRITE);
         IoBridge.write(fd, b, off, len);
         // if we are in "rws" mode, attempt to sync file+metadata
@@ -528,6 +555,7 @@
      * @exception  IOException  if an I/O error occurs.
      */
     public long getFilePointer() throws IOException {
+        // Android-changed: Implement on top of low-level API, not directly natively.
         try {
             return Libcore.os.lseek(fd, 0L, SEEK_CUR);
         } catch (ErrnoException errnoException) {
@@ -543,21 +571,26 @@
      * change only by writing after the offset has been set beyond the end
      * of the file.
      *
-     * @param      offset   the offset position, measured in bytes from the
+     * @param      pos   the offset position, measured in bytes from the
      *                   beginning of the file, at which to set the file
      *                   pointer.
      * @exception  IOException  if {@code pos} is less than
      *                          {@code 0} or if an I/O error occurs.
      */
-    public void seek(long offset) throws IOException {
-        if (offset < 0) {
-            throw new IOException("offset < 0: " + offset);
-        }
-        try {
-            Libcore.os.lseek(fd, offset, SEEK_SET);
-            ioTracker.reset();
-        } catch (ErrnoException errnoException) {
-            throw errnoException.rethrowAsIOException();
+    public void seek(long pos) throws IOException {
+        if (pos < 0) {
+            // Android-changed: different exception message for seek(-1).
+            // throw new IOException("Negative seek offset");
+            throw new IOException("offset < 0: " + pos);
+        } else {
+            // Android-changed: Implement on top of low-level API, not directly natively.
+            // seek0(pos);
+            try {
+                Libcore.os.lseek(fd, pos, SEEK_SET);
+                ioTracker.reset();
+            } catch (ErrnoException errnoException) {
+                throw errnoException.rethrowAsIOException();
+            }
         }
     }
 
@@ -568,6 +601,7 @@
      * @exception  IOException  if an I/O error occurs.
      */
     public long length() throws IOException {
+        // Android-changed: Implement on top of low-level API, not directly natively.
         try {
             return Libcore.os.fstat(fd).st_size;
         } catch (ErrnoException errnoException) {
@@ -595,6 +629,7 @@
      * @since      1.2
      */
     public void setLength(long newLength) throws IOException {
+        // BEGIN Android-changed: Implement on top of low-level API, not directly natively.
         if (newLength < 0) {
             throw new IllegalArgumentException("newLength < 0");
         }
@@ -612,6 +647,7 @@
         if (syncMetadata) {
             fd.sync();
         }
+        // END Android-changed: Implement on top of low-level API, not directly natively.
     }
 
 
@@ -638,10 +674,12 @@
             closed = true;
         }
 
+        // BEGIN Android-changed: Implement on top of low-level API, not directly natively.
         if (channel != null && channel.isOpen()) {
             channel.close();
         }
         IoBridge.closeAndSignalBlockedThreads(fd);
+        // END Android-changed: Implement on top of low-level API, not directly natively.
     }
 
     //
@@ -1166,6 +1204,7 @@
         DataOutputStream.writeUTF(str, this);
     }
 
+    // Android-added: use finalize() to detect if not close()d.
     @Override protected void finalize() throws Throwable {
         try {
             if (guard != null) {
diff --git a/ojluni/src/main/java/java/time/zone/IcuZoneRulesProvider.java b/ojluni/src/main/java/java/time/zone/IcuZoneRulesProvider.java
index 0e45290..91d3a4c 100644
--- a/ojluni/src/main/java/java/time/zone/IcuZoneRulesProvider.java
+++ b/ojluni/src/main/java/java/time/zone/IcuZoneRulesProvider.java
@@ -1,18 +1,24 @@
 /*
  * Copyright (C) 2016 The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  The Android Open Source
+ * Project designates this particular file as subject to the "Classpath"
+ * exception as provided by The Android Open Source Project in the LICENSE
+ * file that accompanied this code.
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
  *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  */
+
 package java.time.zone;
 
 import android.icu.impl.OlsonTimeZone;
diff --git a/ojluni/src/main/java/java/util/Calendar.java b/ojluni/src/main/java/java/util/Calendar.java
index 2009123..b846211 100644
--- a/ojluni/src/main/java/java/util/Calendar.java
+++ b/ojluni/src/main/java/java/util/Calendar.java
@@ -1773,11 +1773,11 @@
     public void setTimeInMillis(long millis) {
         // If we don't need to recalculate the calendar field values,
         // do nothing.
-// BEGIN Android-changed: Removed ZoneInfo support
+// BEGIN Android-changed: Android doesn't have sun.util.calendar.ZoneInfo.
 //        if (time == millis && isTimeSet && areFieldsSet && areAllFieldsSet
 //            && (zone instanceof ZoneInfo) && !((ZoneInfo)zone).isDirty()) {
         if (time == millis && isTimeSet && areFieldsSet && areAllFieldsSet) {
-// END Android-changed: Removed ZoneInfo support
+// END Android-changed: Android doesn't have sun.util.calendar.ZoneInfo.
 
             return;
         }
@@ -3508,7 +3508,7 @@
             catch (IllegalArgumentException e) {}
         }
 
-        // Android-changed: Removed ZoneInfo support/workaround.
+        // Android-changed: Android doesn't have sun.util.calendar.ZoneInfo.
         // Write out the 1.1 FCS object.
         stream.defaultWriteObject();
     }
@@ -3560,7 +3560,7 @@
 
         serialVersionOnStream = currentSerialVersion;
 
-        // Android-changed: removed ZoneInfo support.
+        // Android-changed: Android doesn't have sun.util.calendar.ZoneInfo.
 
         // If the deserialized object has a SimpleTimeZone, try to
         // replace it with a ZoneInfo equivalent (as of 1.4) in order
diff --git a/ojluni/src/main/java/java/util/JapaneseImperialCalendar.java b/ojluni/src/main/java/java/util/JapaneseImperialCalendar.java
index fef7eed..c569981 100644
--- a/ojluni/src/main/java/java/util/JapaneseImperialCalendar.java
+++ b/ojluni/src/main/java/java/util/JapaneseImperialCalendar.java
@@ -1574,10 +1574,14 @@
             zoneOffsets = new int[2];
         }
         if (tzMask != (ZONE_OFFSET_MASK|DST_OFFSET_MASK)) {
-            // Android-changed: remove ZoneInfo support.
-            zoneOffset = tz.getOffset(time);
-            zoneOffsets[0] = tz.getRawOffset();
-            zoneOffsets[1] = zoneOffset - zoneOffsets[0];
+            // Android-changed: Android doesn't have sun.util.calendar.ZoneInfo.
+            // if (tz instanceof ZoneInfo) {
+            //     zoneOffset = ((ZoneInfo)tz).getOffsets(time, zoneOffsets);
+            // } else {
+                zoneOffset = tz.getOffset(time);
+                zoneOffsets[0] = tz.getRawOffset();
+                zoneOffsets[1] = zoneOffset - zoneOffsets[0];
+            // }
         }
         if (tzMask != 0) {
             if (isFieldSet(tzMask, ZONE_OFFSET)) {
@@ -1911,8 +1915,12 @@
         }
         int tzMask = fieldMask & (ZONE_OFFSET_MASK|DST_OFFSET_MASK);
         if (tzMask != (ZONE_OFFSET_MASK|DST_OFFSET_MASK)) {
-            // Android-changed: remove ZoneInfo support
-            zone.getOffsets(millis - zone.getRawOffset(), zoneOffsets);
+            // Android-changed: Android doesn't have sun.util.calendar.ZoneInfo.
+            // if (zone instanceof ZoneInfo) {
+            //     ((ZoneInfo)zone).getOffsetsByWall(millis, zoneOffsets);
+            // } else {
+                zone.getOffsets(millis - zone.getRawOffset(), zoneOffsets);
+            // }
         }
         if (tzMask != 0) {
             if (isFieldSet(tzMask, ZONE_OFFSET)) {
diff --git a/ojluni/src/main/java/javax/crypto/CryptoAllPermission.java b/ojluni/src/main/java/javax/crypto/CryptoAllPermission.java
index 24268b8..be2cde4 100644
--- a/ojluni/src/main/java/javax/crypto/CryptoAllPermission.java
+++ b/ojluni/src/main/java/javax/crypto/CryptoAllPermission.java
@@ -25,6 +25,7 @@
 
 package javax.crypto;
 
+// Android-changed: We don't implement this permission system on Android.
 /**
  * Legacy security code; do not use.
  */
diff --git a/ojluni/src/main/java/javax/crypto/CryptoPermission.java b/ojluni/src/main/java/javax/crypto/CryptoPermission.java
index ec09287..41b315f 100644
--- a/ojluni/src/main/java/javax/crypto/CryptoPermission.java
+++ b/ojluni/src/main/java/javax/crypto/CryptoPermission.java
@@ -28,6 +28,7 @@
 import java.security.*;
 import java.security.spec.AlgorithmParameterSpec;
 
+// Android-changed: We don't implement this permission system on Android.
 /**
  * Legacy security code; do not use.
  */
diff --git a/ojluni/src/main/java/javax/crypto/CryptoPermissions.java b/ojluni/src/main/java/javax/crypto/CryptoPermissions.java
index 0e62b18..245492f 100644
--- a/ojluni/src/main/java/javax/crypto/CryptoPermissions.java
+++ b/ojluni/src/main/java/javax/crypto/CryptoPermissions.java
@@ -31,6 +31,7 @@
 import java.io.InputStream;
 import java.io.IOException;
 
+// Android-changed: We don't implement this permission system on Android.
 /**
  * Legacy security code; do not use.
  */
diff --git a/ojluni/src/main/java/javax/crypto/CryptoPolicyParser.java b/ojluni/src/main/java/javax/crypto/CryptoPolicyParser.java
index a5a3818..bf1aebe 100644
--- a/ojluni/src/main/java/javax/crypto/CryptoPolicyParser.java
+++ b/ojluni/src/main/java/javax/crypto/CryptoPolicyParser.java
@@ -29,6 +29,7 @@
 
 import java.security.GeneralSecurityException;
 
+// Android-changed: We don't implement this permission system on Android.
 /**
  * Legacy security code; do not use.
  */
diff --git a/ojluni/src/main/java/javax/crypto/JceSecurityManager.java b/ojluni/src/main/java/javax/crypto/JceSecurityManager.java
index 38d9f19..b29939e 100644
--- a/ojluni/src/main/java/javax/crypto/JceSecurityManager.java
+++ b/ojluni/src/main/java/javax/crypto/JceSecurityManager.java
@@ -25,6 +25,7 @@
 
 package javax.crypto;
 
+// Android-changed: We don't implement this permission system on Android.
 /**
  * Legacy security code; do not use.
  */
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLEngine.java b/ojluni/src/main/java/javax/net/ssl/SSLEngine.java
index 26dc64c..aa15ccc 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLEngine.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLEngine.java
@@ -404,600 +404,600 @@
  *
  * <h4>Cipher suites</h4>
  * <table>
- *     <thead>
- *         <tr>
- *             <th>Cipher suite</th>
- *             <th>Supported (API Levels)</th>
- *             <th>Enabled by default (API Levels)</th>
- *         </tr>
- *     </thead>
- *     <tbody>
- *         <tr class="deprecated">
- *             <td>SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_DHE_DSS_WITH_DES_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_DHE_RSA_WITH_DES_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_DH_anon_EXPORT_WITH_RC4_40_MD5</td>
- *             <td>9&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_DH_anon_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_DH_anon_WITH_DES_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_DH_anon_WITH_RC4_128_MD5</td>
- *             <td>9&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_RSA_EXPORT_WITH_RC4_40_MD5</td>
- *             <td>9&ndash;22</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr>
- *             <td>SSL_RSA_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>9+</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_RSA_WITH_DES_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_RSA_WITH_NULL_MD5</td>
- *             <td>9&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_RSA_WITH_NULL_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_RSA_WITH_RC4_128_MD5</td>
- *             <td>9&ndash;TBD</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_RSA_WITH_RC4_128_SHA</td>
- *             <td>9&ndash;TBD</td>
- *             <td>9&ndash;23</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</td>
- *             <td>1&ndash;8</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>1&ndash;8</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td>9&ndash;22</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_DSS_WITH_AES_128_GCM_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_DSS_WITH_AES_256_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td>20&ndash;22</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_DSS_WITH_AES_256_CBC_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_DSS_WITH_AES_256_GCM_SHA384</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_DSS_WITH_DES_CBC_SHA</td>
- *             <td>1&ndash;8</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
- *             <td>1&ndash;8</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>1&ndash;8</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_RSA_WITH_AES_128_CBC_SHA</td>
- *             <td>9&ndash;TBD</td>
- *             <td>9&ndash;TBD</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_RSA_WITH_AES_128_CBC_SHA256</td>
- *             <td>20&ndash;TBD</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_RSA_WITH_AES_128_GCM_SHA256</td>
- *             <td>20&ndash;TBD</td>
- *             <td>20&ndash;TBD</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_RSA_WITH_AES_256_CBC_SHA</td>
- *             <td>9&ndash;TBD</td>
- *             <td>20&ndash;TBD</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_RSA_WITH_AES_256_CBC_SHA256</td>
- *             <td>20&ndash;TBD</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_RSA_WITH_AES_256_GCM_SHA384</td>
- *             <td>20&ndash;TBD</td>
- *             <td>20&ndash;TBD</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_RSA_WITH_DES_CBC_SHA</td>
- *             <td>1&ndash;8</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA</td>
- *             <td>1&ndash;8</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>1&ndash;8</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DH_DSS_WITH_DES_CBC_SHA</td>
- *             <td>1&ndash;8</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
- *             <td>1&ndash;8</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>1&ndash;8</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DH_RSA_WITH_DES_CBC_SHA</td>
- *             <td>1&ndash;8</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA</td>
- *             <td>1&ndash;8</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DH_anon_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>1&ndash;8</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DH_anon_WITH_AES_128_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DH_anon_WITH_AES_128_CBC_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DH_anon_WITH_AES_128_GCM_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DH_anon_WITH_AES_256_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DH_anon_WITH_AES_256_CBC_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DH_anon_WITH_AES_256_GCM_SHA384</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DH_anon_WITH_DES_CBC_SHA</td>
- *             <td>1&ndash;8</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA</td>
- *             <td>20+</td>
- *             <td>20+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256</td>
- *             <td>20+</td>
- *             <td></td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256</td>
- *             <td>20+</td>
- *             <td>20+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA</td>
- *             <td>20+</td>
- *             <td>20+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384</td>
- *             <td>20+</td>
- *             <td></td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384</td>
- *             <td>20+</td>
- *             <td>20+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256</td>
- *             <td>24+</td>
- *             <td>24+</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDHE_ECDSA_WITH_NULL_SHA</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDHE_ECDSA_WITH_RC4_128_SHA</td>
- *             <td>20&ndash;TBD</td>
- *             <td>20&ndash;23</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA</td>
- *             <td>21+</td>
- *             <td>21+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA</td>
- *             <td>21+</td>
- *             <td>21+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256</td>
- *             <td>24+</td>
- *             <td>24+</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA</td>
- *             <td>20+</td>
- *             <td>20+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256</td>
- *             <td>20+</td>
- *             <td></td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256</td>
- *             <td>20+</td>
- *             <td>20+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA</td>
- *             <td>20+</td>
- *             <td>20+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384</td>
- *             <td>20+</td>
- *             <td></td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384</td>
- *             <td>20+</td>
- *             <td>20+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256</td>
- *             <td>24+</td>
- *             <td>24+</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDHE_RSA_WITH_NULL_SHA</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDHE_RSA_WITH_RC4_128_SHA</td>
- *             <td>20&ndash;TBD</td>
- *             <td>20&ndash;23</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_ECDSA_WITH_NULL_SHA</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_ECDSA_WITH_RC4_128_SHA</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_RSA_WITH_AES_128_CBC_SHA</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_RSA_WITH_AES_256_CBC_SHA</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_RSA_WITH_NULL_SHA</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_RSA_WITH_RC4_128_SHA</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_anon_WITH_AES_128_CBC_SHA</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_anon_WITH_AES_256_CBC_SHA</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_anon_WITH_NULL_SHA</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_anon_WITH_RC4_128_SHA</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr>
- *             <td>TLS_EMPTY_RENEGOTIATION_INFO_SCSV</td>
- *             <td>20+</td>
- *             <td>20+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_FALLBACK_SCSV</td>
- *             <td>21+</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_NULL_WITH_NULL_NULL</td>
- *             <td>1&ndash;8</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_PSK_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>21&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr>
- *             <td>TLS_PSK_WITH_AES_128_CBC_SHA</td>
- *             <td>21+</td>
- *             <td>21+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_PSK_WITH_AES_256_CBC_SHA</td>
- *             <td>21+</td>
- *             <td>21+</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_PSK_WITH_RC4_128_SHA</td>
- *             <td>21&ndash;TBD</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
- *             <td>1&ndash;8</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_RSA_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>1&ndash;8</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_RSA_WITH_AES_128_CBC_SHA</td>
- *             <td>9+</td>
- *             <td>9+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_RSA_WITH_AES_128_CBC_SHA256</td>
- *             <td>20+</td>
- *             <td></td>
- *         </tr>
- *         <tr>
- *             <td>TLS_RSA_WITH_AES_128_GCM_SHA256</td>
- *             <td>20+</td>
- *             <td>20+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_RSA_WITH_AES_256_CBC_SHA</td>
- *             <td>9+</td>
- *             <td>20+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_RSA_WITH_AES_256_CBC_SHA256</td>
- *             <td>20+</td>
- *             <td></td>
- *         </tr>
- *         <tr>
- *             <td>TLS_RSA_WITH_AES_256_GCM_SHA384</td>
- *             <td>20+</td>
- *             <td>20+</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_RSA_WITH_DES_CBC_SHA</td>
- *             <td>1&ndash;8</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_RSA_WITH_NULL_MD5</td>
- *             <td>1&ndash;8</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_RSA_WITH_NULL_SHA</td>
- *             <td>1&ndash;8</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_RSA_WITH_NULL_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *     </tbody>
+ *   <thead>
+ *     <tr>
+ *       <th>Cipher suite</th>
+ *       <th>Supported (API Levels)</th>
+ *       <th>Enabled by default (API Levels)</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr class="deprecated">
+ *       <td>SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_DHE_DSS_WITH_DES_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_DHE_RSA_WITH_DES_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_DH_anon_EXPORT_WITH_RC4_40_MD5</td>
+ *       <td>9-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_DH_anon_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_DH_anon_WITH_DES_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_DH_anon_WITH_RC4_128_MD5</td>
+ *       <td>9-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_RSA_EXPORT_WITH_RC4_40_MD5</td>
+ *       <td>9-22</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SSL_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>9+</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_RSA_WITH_DES_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_RSA_WITH_NULL_MD5</td>
+ *       <td>9-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_RSA_WITH_NULL_SHA</td>
+ *       <td>9-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_RSA_WITH_RC4_128_MD5</td>
+ *       <td>9-25</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_RSA_WITH_RC4_128_SHA</td>
+ *       <td>9-25</td>
+ *       <td>9-23</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</td>
+ *       <td>1-8</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>1-8</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td>9-22</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_DSS_WITH_AES_128_GCM_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_DSS_WITH_AES_256_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td>20-22</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_DSS_WITH_AES_256_CBC_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_DSS_WITH_AES_256_GCM_SHA384</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_DSS_WITH_DES_CBC_SHA</td>
+ *       <td>1-8</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
+ *       <td>1-8</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>1-8</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_RSA_WITH_AES_128_CBC_SHA</td>
+ *       <td>9-25</td>
+ *       <td>9-25</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_RSA_WITH_AES_128_CBC_SHA256</td>
+ *       <td>20-25</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_RSA_WITH_AES_128_GCM_SHA256</td>
+ *       <td>20-25</td>
+ *       <td>20-25</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_RSA_WITH_AES_256_CBC_SHA</td>
+ *       <td>9-25</td>
+ *       <td>20-25</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_RSA_WITH_AES_256_CBC_SHA256</td>
+ *       <td>20-25</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_RSA_WITH_AES_256_GCM_SHA384</td>
+ *       <td>20-25</td>
+ *       <td>20-25</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_RSA_WITH_DES_CBC_SHA</td>
+ *       <td>1-8</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA</td>
+ *       <td>1-8</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>1-8</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DH_DSS_WITH_DES_CBC_SHA</td>
+ *       <td>1-8</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
+ *       <td>1-8</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>1-8</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DH_RSA_WITH_DES_CBC_SHA</td>
+ *       <td>1-8</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA</td>
+ *       <td>1-8</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DH_anon_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>1-8</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DH_anon_WITH_AES_128_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DH_anon_WITH_AES_128_CBC_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DH_anon_WITH_AES_128_GCM_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DH_anon_WITH_AES_256_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DH_anon_WITH_AES_256_CBC_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DH_anon_WITH_AES_256_GCM_SHA384</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DH_anon_WITH_DES_CBC_SHA</td>
+ *       <td>1-8</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA</td>
+ *       <td>20+</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256</td>
+ *       <td>20+</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256</td>
+ *       <td>20+</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA</td>
+ *       <td>20+</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384</td>
+ *       <td>20+</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384</td>
+ *       <td>20+</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256</td>
+ *       <td>24+</td>
+ *       <td>24+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDHE_ECDSA_WITH_NULL_SHA</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDHE_ECDSA_WITH_RC4_128_SHA</td>
+ *       <td>20-25</td>
+ *       <td>20-23</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA</td>
+ *       <td>21+</td>
+ *       <td>21+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA</td>
+ *       <td>21+</td>
+ *       <td>21+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256</td>
+ *       <td>24+</td>
+ *       <td>24+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA</td>
+ *       <td>20+</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256</td>
+ *       <td>20+</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256</td>
+ *       <td>20+</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA</td>
+ *       <td>20+</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384</td>
+ *       <td>20+</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384</td>
+ *       <td>20+</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256</td>
+ *       <td>24+</td>
+ *       <td>24+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDHE_RSA_WITH_NULL_SHA</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDHE_RSA_WITH_RC4_128_SHA</td>
+ *       <td>20-25</td>
+ *       <td>20-23</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_ECDSA_WITH_NULL_SHA</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_ECDSA_WITH_RC4_128_SHA</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_RSA_WITH_AES_128_CBC_SHA</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_RSA_WITH_AES_256_CBC_SHA</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_RSA_WITH_NULL_SHA</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_RSA_WITH_RC4_128_SHA</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_anon_WITH_AES_128_CBC_SHA</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_anon_WITH_AES_256_CBC_SHA</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_anon_WITH_NULL_SHA</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_anon_WITH_RC4_128_SHA</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_EMPTY_RENEGOTIATION_INFO_SCSV</td>
+ *       <td>20+</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_FALLBACK_SCSV</td>
+ *       <td>21+</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_NULL_WITH_NULL_NULL</td>
+ *       <td>1-8</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_PSK_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>21-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_PSK_WITH_AES_128_CBC_SHA</td>
+ *       <td>21+</td>
+ *       <td>21+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_PSK_WITH_AES_256_CBC_SHA</td>
+ *       <td>21+</td>
+ *       <td>21+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_PSK_WITH_RC4_128_SHA</td>
+ *       <td>21-25</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
+ *       <td>1-8</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>1-8</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_RSA_WITH_AES_128_CBC_SHA</td>
+ *       <td>9+</td>
+ *       <td>9+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_RSA_WITH_AES_128_CBC_SHA256</td>
+ *       <td>20+</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_RSA_WITH_AES_128_GCM_SHA256</td>
+ *       <td>20+</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_RSA_WITH_AES_256_CBC_SHA</td>
+ *       <td>9+</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_RSA_WITH_AES_256_CBC_SHA256</td>
+ *       <td>20+</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_RSA_WITH_AES_256_GCM_SHA384</td>
+ *       <td>20+</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_RSA_WITH_DES_CBC_SHA</td>
+ *       <td>1-8</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_RSA_WITH_NULL_MD5</td>
+ *       <td>1-8</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_RSA_WITH_NULL_SHA</td>
+ *       <td>1-8</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_RSA_WITH_NULL_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *   </tbody>
  * </table>
  *
  * <p><em>NOTE</em>: PSK cipher suites are enabled by default only if the {@code SSLContext} through
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLSocket.java b/ojluni/src/main/java/javax/net/ssl/SSLSocket.java
index f2037b4..875ae34 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLSocket.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLSocket.java
@@ -218,495 +218,495 @@
  * below. Prior to API Level 9, non-standard (OpenSSL) names had been used (see
  * the table following this table).
  * <table>
- *     <thead>
- *         <tr>
- *             <th>Cipher suite</th>
- *             <th>Supported (API Levels)</th>
- *             <th>Enabled by default (API Levels)</th>
- *         </tr>
- *     </thead>
- *     <tbody>
- *         <tr class="deprecated">
- *             <td>SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_DHE_DSS_WITH_DES_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_DHE_RSA_WITH_DES_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_DH_anon_EXPORT_WITH_RC4_40_MD5</td>
- *             <td>9&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_DH_anon_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_DH_anon_WITH_DES_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_DH_anon_WITH_RC4_128_MD5</td>
- *             <td>9&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_RSA_EXPORT_WITH_RC4_40_MD5</td>
- *             <td>9&ndash;22</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr>
- *             <td>SSL_RSA_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>9+</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_RSA_WITH_DES_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_RSA_WITH_NULL_MD5</td>
- *             <td>9&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_RSA_WITH_NULL_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_RSA_WITH_RC4_128_MD5</td>
- *             <td>9&ndash;TBD</td>
- *             <td>9&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL_RSA_WITH_RC4_128_SHA</td>
- *             <td>9&ndash;TBD</td>
- *             <td>9&ndash;23</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td>9&ndash;22</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_DSS_WITH_AES_128_GCM_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_DSS_WITH_AES_256_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td>11&ndash;22</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_DSS_WITH_AES_256_CBC_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_DSS_WITH_AES_256_GCM_SHA384</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_RSA_WITH_AES_128_CBC_SHA</td>
- *             <td>9&ndash;TBD</td>
- *             <td>9&ndash;TBD</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_RSA_WITH_AES_128_CBC_SHA256</td>
- *             <td>20&ndash;TBD</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_RSA_WITH_AES_128_GCM_SHA256</td>
- *             <td>20&ndash;TBD</td>
- *             <td>20&ndash;TBD</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_RSA_WITH_AES_256_CBC_SHA</td>
- *             <td>9&ndash;TBD</td>
- *             <td>11&ndash;TBD</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_RSA_WITH_AES_256_CBC_SHA256</td>
- *             <td>20&ndash;TBD</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DHE_RSA_WITH_AES_256_GCM_SHA384</td>
- *             <td>20&ndash;TBD</td>
- *             <td>20&ndash;TBD</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DH_anon_WITH_AES_128_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DH_anon_WITH_AES_128_CBC_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DH_anon_WITH_AES_128_GCM_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DH_anon_WITH_AES_256_CBC_SHA</td>
- *             <td>9&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DH_anon_WITH_AES_256_CBC_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_DH_anon_WITH_AES_256_GCM_SHA384</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>11&ndash;22</td>
- *             <td>11&ndash;19</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA</td>
- *             <td>11+</td>
- *             <td>11+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256</td>
- *             <td>20+</td>
- *             <td></td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256</td>
- *             <td>20+</td>
- *             <td>20+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA</td>
- *             <td>11+</td>
- *             <td>11+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384</td>
- *             <td>20+</td>
- *             <td></td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384</td>
- *             <td>20+</td>
- *             <td>20+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256</td>
- *             <td>24+</td>
- *             <td>24+</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDHE_ECDSA_WITH_NULL_SHA</td>
- *             <td>11&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDHE_ECDSA_WITH_RC4_128_SHA</td>
- *             <td>11&ndash;TBD</td>
- *             <td>11&ndash;23</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA</td>
- *             <td>21+</td>
- *             <td>21+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA</td>
- *             <td>21+</td>
- *             <td>21+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256</td>
- *             <td>24+</td>
- *             <td>24+</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>11&ndash;22</td>
- *             <td>11&ndash;19</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA</td>
- *             <td>11+</td>
- *             <td>11+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256</td>
- *             <td>20+</td>
- *             <td></td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256</td>
- *             <td>20+</td>
- *             <td>20+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA</td>
- *             <td>11+</td>
- *             <td>11+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384</td>
- *             <td>20+</td>
- *             <td></td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384</td>
- *             <td>20+</td>
- *             <td>20+</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDHE_RSA_WITH_NULL_SHA</td>
- *             <td>11&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDHE_RSA_WITH_RC4_128_SHA</td>
- *             <td>11&ndash;TBD</td>
- *             <td>11&ndash;23</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>11&ndash;22</td>
- *             <td>11&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA</td>
- *             <td>11&ndash;22</td>
- *             <td>11&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA</td>
- *             <td>11&ndash;22</td>
- *             <td>11&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_ECDSA_WITH_NULL_SHA</td>
- *             <td>11&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_ECDSA_WITH_RC4_128_SHA</td>
- *             <td>11&ndash;22</td>
- *             <td>11&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>11&ndash;22</td>
- *             <td>11&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_RSA_WITH_AES_128_CBC_SHA</td>
- *             <td>11&ndash;22</td>
- *             <td>11&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_RSA_WITH_AES_256_CBC_SHA</td>
- *             <td>11&ndash;22</td>
- *             <td>11&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_RSA_WITH_NULL_SHA</td>
- *             <td>11&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_RSA_WITH_RC4_128_SHA</td>
- *             <td>11&ndash;22</td>
- *             <td>11&ndash;19</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>11&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_anon_WITH_AES_128_CBC_SHA</td>
- *             <td>11&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_anon_WITH_AES_256_CBC_SHA</td>
- *             <td>11&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_anon_WITH_NULL_SHA</td>
- *             <td>11&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_ECDH_anon_WITH_RC4_128_SHA</td>
- *             <td>11&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr>
- *             <td>TLS_EMPTY_RENEGOTIATION_INFO_SCSV</td>
- *             <td>11+</td>
- *             <td>11+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_FALLBACK_SCSV</td>
- *             <td>21+</td>
- *             <td></td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_PSK_WITH_3DES_EDE_CBC_SHA</td>
- *             <td>21&ndash;22</td>
- *             <td></td>
- *         </tr>
- *         <tr>
- *             <td>TLS_PSK_WITH_AES_128_CBC_SHA</td>
- *             <td>21+</td>
- *             <td>21+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_PSK_WITH_AES_256_CBC_SHA</td>
- *             <td>21+</td>
- *             <td>21+</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_PSK_WITH_RC4_128_SHA</td>
- *             <td>21&ndash;TBD</td>
- *             <td></td>
- *         </tr>
- *         <tr>
- *             <td>TLS_RSA_WITH_AES_128_CBC_SHA</td>
- *             <td>9+</td>
- *             <td>9+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_RSA_WITH_AES_128_CBC_SHA256</td>
- *             <td>20+</td>
- *             <td></td>
- *         </tr>
- *         <tr>
- *             <td>TLS_RSA_WITH_AES_128_GCM_SHA256</td>
- *             <td>20+</td>
- *             <td>20+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_RSA_WITH_AES_256_CBC_SHA</td>
- *             <td>9+</td>
- *             <td>11+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_RSA_WITH_AES_256_CBC_SHA256</td>
- *             <td>20+</td>
- *             <td></td>
- *         </tr>
- *         <tr>
- *             <td>TLS_RSA_WITH_AES_256_GCM_SHA384</td>
- *             <td>20+</td>
- *             <td>20+</td>
- *         </tr>
- *         <tr>
- *             <td>TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256</td>
- *             <td>24+</td>
- *             <td>24+</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>TLS_RSA_WITH_NULL_SHA256</td>
- *             <td>20&ndash;22</td>
- *             <td></td>
- *         </tr>
- *     </tbody>
+ *   <thead>
+ *     <tr>
+ *       <th>Cipher suite</th>
+ *       <th>Supported (API Levels)</th>
+ *       <th>Enabled by default (API Levels)</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr class="deprecated">
+ *       <td>SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_DHE_DSS_WITH_DES_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_DHE_RSA_WITH_DES_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_DH_anon_EXPORT_WITH_RC4_40_MD5</td>
+ *       <td>9-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_DH_anon_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_DH_anon_WITH_DES_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_DH_anon_WITH_RC4_128_MD5</td>
+ *       <td>9-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_RSA_EXPORT_WITH_RC4_40_MD5</td>
+ *       <td>9-22</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SSL_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>9+</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_RSA_WITH_DES_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_RSA_WITH_NULL_MD5</td>
+ *       <td>9-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_RSA_WITH_NULL_SHA</td>
+ *       <td>9-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_RSA_WITH_RC4_128_MD5</td>
+ *       <td>9-25</td>
+ *       <td>9-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSL_RSA_WITH_RC4_128_SHA</td>
+ *       <td>9-25</td>
+ *       <td>9-23</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td>9-22</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_DSS_WITH_AES_128_GCM_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_DSS_WITH_AES_256_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td>11-22</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_DSS_WITH_AES_256_CBC_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_DSS_WITH_AES_256_GCM_SHA384</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_RSA_WITH_AES_128_CBC_SHA</td>
+ *       <td>9-25</td>
+ *       <td>9-25</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_RSA_WITH_AES_128_CBC_SHA256</td>
+ *       <td>20-25</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_RSA_WITH_AES_128_GCM_SHA256</td>
+ *       <td>20-25</td>
+ *       <td>20-25</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_RSA_WITH_AES_256_CBC_SHA</td>
+ *       <td>9-25</td>
+ *       <td>11-25</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_RSA_WITH_AES_256_CBC_SHA256</td>
+ *       <td>20-25</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DHE_RSA_WITH_AES_256_GCM_SHA384</td>
+ *       <td>20-25</td>
+ *       <td>20-25</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DH_anon_WITH_AES_128_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DH_anon_WITH_AES_128_CBC_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DH_anon_WITH_AES_128_GCM_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DH_anon_WITH_AES_256_CBC_SHA</td>
+ *       <td>9-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DH_anon_WITH_AES_256_CBC_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_DH_anon_WITH_AES_256_GCM_SHA384</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>11-22</td>
+ *       <td>11-19</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA</td>
+ *       <td>11+</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256</td>
+ *       <td>20+</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256</td>
+ *       <td>20+</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA</td>
+ *       <td>11+</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384</td>
+ *       <td>20+</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384</td>
+ *       <td>20+</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256</td>
+ *       <td>24+</td>
+ *       <td>24+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDHE_ECDSA_WITH_NULL_SHA</td>
+ *       <td>11-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDHE_ECDSA_WITH_RC4_128_SHA</td>
+ *       <td>11-25</td>
+ *       <td>11-23</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA</td>
+ *       <td>21+</td>
+ *       <td>21+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA</td>
+ *       <td>21+</td>
+ *       <td>21+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256</td>
+ *       <td>24+</td>
+ *       <td>24+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>11-22</td>
+ *       <td>11-19</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA</td>
+ *       <td>11+</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256</td>
+ *       <td>20+</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256</td>
+ *       <td>20+</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA</td>
+ *       <td>11+</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384</td>
+ *       <td>20+</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384</td>
+ *       <td>20+</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256</td>
+ *       <td>24+</td>
+ *       <td>24+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDHE_RSA_WITH_NULL_SHA</td>
+ *       <td>11-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDHE_RSA_WITH_RC4_128_SHA</td>
+ *       <td>11-25</td>
+ *       <td>11-23</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>11-22</td>
+ *       <td>11-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA</td>
+ *       <td>11-22</td>
+ *       <td>11-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA</td>
+ *       <td>11-22</td>
+ *       <td>11-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_ECDSA_WITH_NULL_SHA</td>
+ *       <td>11-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_ECDSA_WITH_RC4_128_SHA</td>
+ *       <td>11-22</td>
+ *       <td>11-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>11-22</td>
+ *       <td>11-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_RSA_WITH_AES_128_CBC_SHA</td>
+ *       <td>11-22</td>
+ *       <td>11-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_RSA_WITH_AES_256_CBC_SHA</td>
+ *       <td>11-22</td>
+ *       <td>11-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_RSA_WITH_NULL_SHA</td>
+ *       <td>11-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_RSA_WITH_RC4_128_SHA</td>
+ *       <td>11-22</td>
+ *       <td>11-19</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>11-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_anon_WITH_AES_128_CBC_SHA</td>
+ *       <td>11-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_anon_WITH_AES_256_CBC_SHA</td>
+ *       <td>11-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_anon_WITH_NULL_SHA</td>
+ *       <td>11-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_ECDH_anon_WITH_RC4_128_SHA</td>
+ *       <td>11-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_EMPTY_RENEGOTIATION_INFO_SCSV</td>
+ *       <td>11+</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_FALLBACK_SCSV</td>
+ *       <td>21+</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_PSK_WITH_3DES_EDE_CBC_SHA</td>
+ *       <td>21-22</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_PSK_WITH_AES_128_CBC_SHA</td>
+ *       <td>21+</td>
+ *       <td>21+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_PSK_WITH_AES_256_CBC_SHA</td>
+ *       <td>21+</td>
+ *       <td>21+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_PSK_WITH_RC4_128_SHA</td>
+ *       <td>21-25</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_RSA_WITH_AES_128_CBC_SHA</td>
+ *       <td>9+</td>
+ *       <td>9+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_RSA_WITH_AES_128_CBC_SHA256</td>
+ *       <td>20+</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_RSA_WITH_AES_128_GCM_SHA256</td>
+ *       <td>20+</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_RSA_WITH_AES_256_CBC_SHA</td>
+ *       <td>9+</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_RSA_WITH_AES_256_CBC_SHA256</td>
+ *       <td>20+</td>
+ *       <td></td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS_RSA_WITH_AES_256_GCM_SHA384</td>
+ *       <td>20+</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>TLS_RSA_WITH_NULL_SHA256</td>
+ *       <td>20-22</td>
+ *       <td></td>
+ *     </tr>
+ *   </tbody>
  * </table>
  *
  * <p><em>NOTE</em>: PSK cipher suites are enabled by default only if the {@code SSLContext} through
diff --git a/ojluni/src/main/java/javax/security/auth/AuthPermission.java b/ojluni/src/main/java/javax/security/auth/AuthPermission.java
index 651e9a3..00eef9e 100644
--- a/ojluni/src/main/java/javax/security/auth/AuthPermission.java
+++ b/ojluni/src/main/java/javax/security/auth/AuthPermission.java
@@ -25,6 +25,7 @@
 
 package javax.security.auth;
 
+// Android-changed: We don't implement this permission system on Android.
 /**
  * Legacy security code; do not use.
  */
diff --git a/ojluni/src/main/java/javax/security/auth/PrivateCredentialPermission.java b/ojluni/src/main/java/javax/security/auth/PrivateCredentialPermission.java
index ca52a1b2..9f5eea9 100644
--- a/ojluni/src/main/java/javax/security/auth/PrivateCredentialPermission.java
+++ b/ojluni/src/main/java/javax/security/auth/PrivateCredentialPermission.java
@@ -29,6 +29,7 @@
 import java.security.Permission;
 import java.security.Principal;
 
+// Android-changed: We don't implement this permission system on Android.
 /**
  * Legacy security code; do not use.
  */
diff --git a/ojluni/src/main/java/javax/security/auth/SubjectDomainCombiner.java b/ojluni/src/main/java/javax/security/auth/SubjectDomainCombiner.java
index 8e07d4b..4ad9a37 100644
--- a/ojluni/src/main/java/javax/security/auth/SubjectDomainCombiner.java
+++ b/ojluni/src/main/java/javax/security/auth/SubjectDomainCombiner.java
@@ -27,6 +27,7 @@
 
 import java.security.ProtectionDomain;
 
+// Android-changed: We don't implement this permission system on Android.
 /**
  * Legacy security code; do not use.
  */
diff --git a/ojluni/src/main/java/sun/misc/Hashing.java b/ojluni/src/main/java/sun/misc/Hashing.java
deleted file mode 100644
index 2b3b144..0000000
--- a/ojluni/src/main/java/sun/misc/Hashing.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.misc;
-
-import java.util.concurrent.ThreadLocalRandom;
-
-/**
- * Hashing utilities.
- *
- * Little endian implementations of Murmur3 hashing.
- */
-public class Hashing {
-
-    /**
-     * Static utility methods only.
-     */
-    private Hashing() {
-        throw new Error("No instances");
-    }
-
-    // Spread bits to regularize both segment and index locations,
-    // using variant of single-word Wang/Jenkins hash.
-    //
-    // Based on commit 1424a2a1a9fc53dc8b859a77c02c924.
-    public static int singleWordWangJenkinsHash(Object k) {
-        int h = k.hashCode();
-
-        h += (h <<  15) ^ 0xffffcd7d;
-        h ^= (h >>> 10);
-        h += (h <<   3);
-        h ^= (h >>>  6);
-        h += (h <<   2) + (h << 14);
-        return h ^ (h >>> 16);
-    }
-}
diff --git a/ojluni/src/main/java/sun/util/calendar/AbstractCalendar.java b/ojluni/src/main/java/sun/util/calendar/AbstractCalendar.java
index 96e2e3d..ead18de 100644
--- a/ojluni/src/main/java/sun/util/calendar/AbstractCalendar.java
+++ b/ojluni/src/main/java/sun/util/calendar/AbstractCalendar.java
@@ -123,9 +123,15 @@
         TimeZone zi = date.getZone();
         if (zi != null) {
             int[] offsets = new int[2];
-            zoneOffset = zi.getOffset(millis);
-            offsets[0] = zi.getRawOffset();
-            offsets[1] = zoneOffset - offsets[0];
+            // BEGIN Android-changed: Android doesn't have sun.util.calendar.ZoneInfo.
+            // if (zi instanceof ZoneInfo) {
+            //    zoneOffset = ((ZoneInfo)zi).getOffsets(millis, offsets);
+            // } else {
+                zoneOffset = zi.getOffset(millis);
+                offsets[0] = zi.getRawOffset();
+                offsets[1] = zoneOffset - offsets[0];
+            // }
+            // END Android-changed: Android doesn't have sun.util.calendar.ZoneInfo.
 
             // We need to calculate the given millis and time zone
             // offset separately for java.util.GregorianCalendar
@@ -185,14 +191,25 @@
                 // 2) 5:00pm during DST is still interpreted as 5:00pm ST
                 // 3) 1:30am during ending-DST transition is interpreted
                 //    as 1:30am ST (after transition)
-                zoneOffset = zi.getOffset(ms - zi.getRawOffset());
+                // Android-changed: Android doesn't have sun.util.calendar.ZoneInfo.
+                // if (zi instanceof ZoneInfo) {
+                //     ((ZoneInfo)zi).getOffsetsByStandard(ms, offsets);
+                //     zoneOffset = offsets[0];
+                // } else {
+                    zoneOffset = zi.getOffset(ms - zi.getRawOffset());
+                // }
             } else {
                 // 1) 2:30am during starting-DST transition is
                 //    intrepreted as 3:30am DT
                 // 2) 5:00pm during DST is intrepreted as 5:00pm DT
                 // 3) 1:30am during ending-DST transition is interpreted
                 //    as 1:30am DT/0:30am ST (before transition)
-                zoneOffset = zi.getOffset(ms - zi.getRawOffset());
+                // Android-changed: Android doesn't have sun.util.calendar.ZoneInfo.
+                // if (zi instanceof ZoneInfo) {
+                //     zoneOffset = ((ZoneInfo)zi).getOffsetsByWall(ms, offsets);
+                // } else {
+                    zoneOffset = zi.getOffset(ms - zi.getRawOffset());
+                // }
             }
         }
         ms -= zoneOffset;
diff --git a/ojluni/src/main/java/sun/util/calendar/BaseCalendar.java b/ojluni/src/main/java/sun/util/calendar/BaseCalendar.java
index 908bec8..a7e763a 100644
--- a/ojluni/src/main/java/sun/util/calendar/BaseCalendar.java
+++ b/ojluni/src/main/java/sun/util/calendar/BaseCalendar.java
@@ -25,7 +25,6 @@
 
 package sun.util.calendar;
 
-import java.util.Locale;
 import java.util.TimeZone;
 
 /**
diff --git a/ojluni/src/main/java/sun/util/calendar/CalendarDate.java b/ojluni/src/main/java/sun/util/calendar/CalendarDate.java
index 205415e..b8e736c 100644
--- a/ojluni/src/main/java/sun/util/calendar/CalendarDate.java
+++ b/ojluni/src/main/java/sun/util/calendar/CalendarDate.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -435,7 +435,7 @@
             return super.clone();
         } catch (CloneNotSupportedException e) {
             // this shouldn't happen
-            throw new InternalError();
+            throw new InternalError(e);
         }
     }
 
diff --git a/ojluni/src/main/java/sun/util/calendar/CalendarSystem.java b/ojluni/src/main/java/sun/util/calendar/CalendarSystem.java
index 17ad0e8..3b9cbf7 100644
--- a/ojluni/src/main/java/sun/util/calendar/CalendarSystem.java
+++ b/ojluni/src/main/java/sun/util/calendar/CalendarSystem.java
@@ -75,25 +75,53 @@
 
     /////////////////////// Calendar Factory Methods /////////////////////////
 
+    // BEGIN Android-changed: avoid reflection for loading calendar classes.
+    // // Map of calendar names and calendar class names
+    // private static ConcurrentMap<String, String> names;
     // Map of calendar names and calendar classes;
     private static final Map<String, Class<?>> names;
 
-    // Android-changed: Don't use reflection for Class.forName every time.
+    // Map of calendar names and CalendarSystem instances
+    private static final ConcurrentMap<String, CalendarSystem> calendars =
+            new ConcurrentHashMap<>();
 
     static {
         names = new HashMap<>();
         names.put("gregorian", Gregorian.class);
         names.put("japanese", LocalGregorianCalendar.class);
         names.put("julian", JulianCalendar.class);
-        // names.put("hebrew", "HebrewCalendar");
-        // names.put("iso8601", "ISOCalendar");
-        // names.put("taiwanese", "LocalGregorianCalendar");
-        // names.put("thaibuddhist", "LocalGregorianCalendar");
+    // END Android-changed: avoid reflection for loading calendar classes.
+        /*
+        "hebrew", "HebrewCalendar",
+        "iso8601", "ISOCalendar",
+        "taiwanese", "LocalGregorianCalendar",
+        "thaibuddhist", "LocalGregorianCalendar",
+        */
     }
 
-    // Map of calendar names and CalendarSystem instances
-    private static final ConcurrentMap<String, CalendarSystem> calendars =
-            new ConcurrentHashMap<>();
+    // BEGIN Android-removed: avoid reflection for loading calendar classes.
+    /*
+    private static void initNames() {
+        ConcurrentMap<String,String> nameMap = new ConcurrentHashMap<>();
+
+        // Associate a calendar name with its class name and the
+        // calendar class name with its date class name.
+        StringBuilder clName = new StringBuilder();
+        for (int i = 0; i < namePairs.length; i += 2) {
+            clName.setLength(0);
+            String cl = clName.append(PACKAGE_NAME).append(namePairs[i+1]).toString();
+            nameMap.put(namePairs[i], cl);
+        }
+        synchronized (CalendarSystem.class) {
+            if (!initialized) {
+                names = nameMap;
+                calendars = new ConcurrentHashMap<>();
+                initialized = true;
+            }
+        }
+    }
+    */
+    // END Android-removed: avoid reflection for loading calendar classes.
 
     private final static Gregorian GREGORIAN_INSTANCE = new Gregorian();
 
@@ -141,13 +169,12 @@
             try {
                 cal = (CalendarSystem) calendarClass.newInstance();
             } catch (Exception e) {
-                throw new RuntimeException("internal error", e);
+                throw new InternalError(e);
             }
         }
         if (cal == null) {
             return null;
         }
-
         CalendarSystem cs =  calendars.putIfAbsent(calendarName, cal);
         return (cs == null) ? cal : cs;
     }
@@ -161,7 +188,7 @@
      *                                  Unicode escape sequences
      */
     public static Properties getCalendarProperties() throws IOException {
-        // Android-changed: load from resources.
+        // Android-changed: load calendar Properties from resources.
         Properties calendarProps = new Properties();
         try (InputStream is = ClassLoader.getSystemResourceAsStream("calendars.properties")) {
             calendarProps.load(is);
diff --git a/ojluni/src/main/java/sun/util/calendar/LocalGregorianCalendar.java b/ojluni/src/main/java/sun/util/calendar/LocalGregorianCalendar.java
index 4d0922d..3c969a7 100644
--- a/ojluni/src/main/java/sun/util/calendar/LocalGregorianCalendar.java
+++ b/ojluni/src/main/java/sun/util/calendar/LocalGregorianCalendar.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -25,13 +25,7 @@
 
 package sun.util.calendar;
 
-import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Properties;
@@ -60,6 +54,7 @@
 
         private int gregorianYear = FIELD_UNDEFINED;
 
+        @Override
         public Date setEra(Era era) {
             if (getEra() != era) {
                 super.setEra(era);
@@ -68,12 +63,14 @@
             return this;
         }
 
+        @Override
         public Date addYear(int localYear) {
             super.addYear(localYear);
             gregorianYear += localYear;
             return this;
         }
 
+        @Override
         public Date setYear(int localYear) {
             if (getYear() != localYear) {
                 super.setYear(localYear);
@@ -82,10 +79,12 @@
             return this;
         }
 
+        @Override
         public int getNormalizedYear() {
             return gregorianYear;
         }
 
+        @Override
         public void setNormalizedYear(int normalizedYear) {
             this.gregorianYear = normalizedYear;
         }
@@ -98,6 +97,7 @@
             super.setYear(year);
         }
 
+        @Override
         public String toString() {
             String time = super.toString();
             time = time.substring(time.indexOf('T'));
@@ -118,20 +118,18 @@
     }
 
     static LocalGregorianCalendar getLocalGregorianCalendar(String name) {
-        // Android-changed: use getCalendarProperties()
         Properties calendarProps;
         try {
-            calendarProps = getCalendarProperties();
-        } catch (IOException e) {
-            throw new RuntimeException(e);
+            calendarProps = CalendarSystem.getCalendarProperties();
+        } catch (IOException | IllegalArgumentException e) {
+            throw new InternalError(e);
         }
-
         // Parse calendar.*.eras
         String props = calendarProps.getProperty("calendar." + name + ".eras");
         if (props == null) {
             return null;
         }
-        List<Era> eras = new ArrayList<Era>();
+        List<Era> eras = new ArrayList<>();
         StringTokenizer eraTokens = new StringTokenizer(props, ";");
         while (eraTokens.hasMoreTokens()) {
             String items = eraTokens.nextToken().trim();
@@ -168,11 +166,12 @@
             Era era = new Era(eraName, abbr, since, localTime);
             eras.add(era);
         }
-        // Android-changed: Throw if no eras were found, as other code depends on there being
-        // at least one era.
+        // BEGIN Android-changed: Require at least one era.
+        // Other code depends on there being at least one era.
         if (eras.isEmpty()) {
             throw new RuntimeException("No eras for " + name);
         }
+        // END Android-changed: Require at least one era.
         Era[] eraArray = new Era[eras.size()];
         eras.toArray(eraArray);
 
@@ -185,22 +184,27 @@
         setEras(eras);
     }
 
+    @Override
     public String getName() {
         return name;
     }
 
+    @Override
     public Date getCalendarDate() {
         return getCalendarDate(System.currentTimeMillis(), newCalendarDate());
     }
 
+    @Override
     public Date getCalendarDate(long millis) {
         return getCalendarDate(millis, newCalendarDate());
     }
 
+    @Override
     public Date getCalendarDate(long millis, TimeZone zone) {
         return getCalendarDate(millis, newCalendarDate(zone));
     }
 
+    @Override
     public Date getCalendarDate(long millis, CalendarDate date) {
         Date ldate = (Date) super.getCalendarDate(millis, date);
         return adjustYear(ldate, millis, ldate.getZoneOffset());
@@ -229,14 +233,17 @@
         return ldate;
     }
 
+    @Override
     public Date newCalendarDate() {
         return new Date();
     }
 
+    @Override
     public Date newCalendarDate(TimeZone zone) {
         return new Date(zone);
     }
 
+    @Override
     public boolean validate(CalendarDate date) {
         Date ldate = (Date) date;
         Era era = ldate.getEra();
@@ -270,6 +277,7 @@
         return false;
     }
 
+    @Override
     public boolean normalize(CalendarDate date) {
         if (date.isNormalized()) {
             return true;
@@ -343,6 +351,7 @@
         return true;
     }
 
+    @Override
     void normalizeMonth(CalendarDate date) {
         normalizeYear(date);
         super.normalizeMonth(date);
@@ -364,6 +373,7 @@
      * Returns whether the specified Gregorian year is a leap year.
      * @see #isLeapYear(Era, int)
      */
+    @Override
     public boolean isLeapYear(int gregorianYear) {
         return CalendarUtils.isGregorianLeapYear(gregorianYear);
     }
@@ -376,6 +386,7 @@
         return isLeapYear(gyear);
     }
 
+    @Override
     public void getCalendarDateFromFixedDate(CalendarDate date, long fixedDate) {
         Date ldate = (Date) date;
         super.getCalendarDateFromFixedDate(ldate, fixedDate);
diff --git a/ojluni/src/main/java/sun/util/locale/BaseLocale.java b/ojluni/src/main/java/sun/util/locale/BaseLocale.java
index 6eee582..e0e9ed0 100644
--- a/ojluni/src/main/java/sun/util/locale/BaseLocale.java
+++ b/ojluni/src/main/java/sun/util/locale/BaseLocale.java
@@ -31,6 +31,7 @@
  */
 
 package sun.util.locale;
+import java.lang.ref.SoftReference;
 
 
 public final class BaseLocale {
@@ -163,11 +164,11 @@
         return h;
     }
 
-    private static final class Key implements Comparable<Key> {
-        private final String lang;
-        private final String scrt;
-        private final String regn;
-        private final String vart;
+    private static final class Key {
+        private final SoftReference<String> lang;
+        private final SoftReference<String> scrt;
+        private final SoftReference<String> regn;
+        private final SoftReference<String> vart;
         private final boolean normalized;
         private final int hash;
 
@@ -179,10 +180,10 @@
             assert language.intern() == language
                    && region.intern() == region;
 
-            lang = language;
-            scrt = "";
-            regn = region;
-            vart = "";
+            lang = new SoftReference(language);
+            scrt = new SoftReference("");
+            regn = new SoftReference(region);
+            vart = new SoftReference("");
             this.normalized = true;
 
             int h = language.hashCode();
@@ -203,40 +204,40 @@
                     String variant, boolean normalized) {
             int h = 0;
             if (language != null) {
-                lang = language;
+                lang = new SoftReference(language);
                 int len = language.length();
                 for (int i = 0; i < len; i++) {
                     h = 31*h + LocaleUtils.toLower(language.charAt(i));
                 }
             } else {
-                lang = "";
+                lang = new SoftReference("");
             }
             if (script != null) {
-                scrt = script;
+                scrt = new SoftReference(script);
                 int len = script.length();
                 for (int i = 0; i < len; i++) {
                     h = 31*h + LocaleUtils.toLower(script.charAt(i));
                 }
             } else {
-                scrt = "";
+                scrt = new SoftReference("");
             }
             if (region != null) {
-                regn = region;
+                regn = new SoftReference(region);
                 int len = region.length();
                 for (int i = 0; i < len; i++) {
                     h = 31*h + LocaleUtils.toLower(region.charAt(i));
                 }
             } else {
-                regn = "";
+                regn = new SoftReference("");
             }
             if (variant != null) {
-                vart = variant;
+                vart = new SoftReference(variant);
                 int len = variant.length();
                 for (int i = 0; i < len; i++) {
                     h = 31*h + variant.charAt(i);
                 }
             } else {
-                vart = "";
+                vart = new SoftReference("");
             }
             hash = h;
             this.normalized = normalized;
@@ -244,28 +245,31 @@
 
         @Override
         public boolean equals(Object obj) {
-            return (this == obj) ||
-                    (obj instanceof Key)
-                    && this.hash == ((Key)obj).hash
-                    && LocaleUtils.caseIgnoreMatch(((Key)obj).lang, this.lang)
-                    && LocaleUtils.caseIgnoreMatch(((Key)obj).scrt, this.scrt)
-                    && LocaleUtils.caseIgnoreMatch(((Key)obj).regn, this.regn)
-                    && ((Key)obj).vart.equals(vart); // variant is case sensitive in JDK!
+            if (this == obj) {
+                return true;
         }
 
-        @Override
-        public int compareTo(Key other) {
-            int res = LocaleUtils.caseIgnoreCompare(this.lang, other.lang);
-            if (res == 0) {
-                res = LocaleUtils.caseIgnoreCompare(this.scrt, other.scrt);
-                if (res == 0) {
-                    res = LocaleUtils.caseIgnoreCompare(this.regn, other.regn);
-                    if (res == 0) {
-                        res = this.vart.compareTo(other.vart);
+            if (obj instanceof Key && this.hash == ((Key)obj).hash) {
+                String tl = this.lang.get();
+                String ol = ((Key)obj).lang.get();
+                if (tl != null && ol != null &&
+                    LocaleUtils.caseIgnoreMatch(ol, tl)) {
+                    String ts = this.scrt.get();
+                    String os = ((Key)obj).scrt.get();
+                    if (ts != null && os != null &&
+                        LocaleUtils.caseIgnoreMatch(os, ts)) {
+                        String tr = this.regn.get();
+                        String or = ((Key)obj).regn.get();
+                        if (tr != null && or != null &&
+                            LocaleUtils.caseIgnoreMatch(or, tr)) {
+                            String tv = this.vart.get();
+                            String ov = ((Key)obj).vart.get();
+                            return (ov != null && ov.equals(tv));
                     }
                 }
             }
-            return res;
+            }
+            return false;
         }
 
         @Override
@@ -278,10 +282,10 @@
                 return key;
             }
 
-            String lang = LocaleUtils.toLowerString(key.lang).intern();
-            String scrt = LocaleUtils.toTitleString(key.scrt).intern();
-            String regn = LocaleUtils.toUpperString(key.regn).intern();
-            String vart = key.vart.intern(); // preserve upper/lower cases
+            String lang = LocaleUtils.toLowerString(key.lang.get()).intern();
+            String scrt = LocaleUtils.toTitleString(key.scrt.get()).intern();
+            String regn = LocaleUtils.toUpperString(key.regn.get()).intern();
+            String vart = key.vart.get().intern(); // preserve upper/lower cases
 
             return new Key(lang, scrt, regn, vart, true);
         }
@@ -294,12 +298,18 @@
 
         @Override
         protected Key normalizeKey(Key key) {
+            assert key.lang.get() != null &&
+                   key.scrt.get() != null &&
+                   key.regn.get() != null &&
+                   key.vart.get() != null;
+
             return Key.normalize(key);
         }
 
         @Override
         protected BaseLocale createObject(Key key) {
-            return new BaseLocale(key.lang, key.scrt, key.regn, key.vart);
+            return new BaseLocale(key.lang.get(), key.scrt.get(),
+                                  key.regn.get(), key.vart.get());
         }
     }
 }
diff --git a/ojluni/src/main/java/sun/util/locale/InternalLocaleBuilder.java b/ojluni/src/main/java/sun/util/locale/InternalLocaleBuilder.java
index 378fb6c..81fa86e 100644
--- a/ojluni/src/main/java/sun/util/locale/InternalLocaleBuilder.java
+++ b/ojluni/src/main/java/sun/util/locale/InternalLocaleBuilder.java
@@ -419,8 +419,9 @@
         }
 
         if (variant.length() > 0) {
-            // normalize separators to "_"
+            // BEGIN Android-added: normalize separators to "_"
             variant = variant.replaceAll(LanguageTag.SEP, BaseLocale.SEP);
+            // END Android-added: normalize separators to "_"
             int errIdx = checkVariants(variant, BaseLocale.SEP);
             if (errIdx != -1) {
                 throw new LocaleSyntaxException("Ill-formed variant: " + variant, errIdx);
diff --git a/ojluni/src/main/java/sun/util/locale/LanguageTag.java b/ojluni/src/main/java/sun/util/locale/LanguageTag.java
index fc7b07b..2247398 100644
--- a/ojluni/src/main/java/sun/util/locale/LanguageTag.java
+++ b/ojluni/src/main/java/sun/util/locale/LanguageTag.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -134,7 +134,7 @@
     }
 
     /*
-     * BNF in RFC5464
+     * BNF in RFC5646
      *
      * Language-Tag  = langtag             ; normal language tags
      *               / privateuse          ; private use tag
diff --git a/ojluni/src/main/java/sun/util/locale/LocaleMatcher.java b/ojluni/src/main/java/sun/util/locale/LocaleMatcher.java
index 6b5f597..70fabc7 100644
--- a/ojluni/src/main/java/sun/util/locale/LocaleMatcher.java
+++ b/ojluni/src/main/java/sun/util/locale/LocaleMatcher.java
@@ -212,7 +212,7 @@
             if (range.equals("*")) {
                 continue;
             }
-
+            // Android-changed: backport OpenJDK 9 fix for JDK-8166994
             String rangeForRegex = range.replace("*", "\\p{Alnum}*");
             while (rangeForRegex.length() > 0) {
                 for (String tag : tags) {
@@ -242,6 +242,7 @@
     }
 
     public static List<LanguageRange> parse(String ranges) {
+        // Android-changed: backport OpenJDK 9 fix for JDK-8166994
         ranges = ranges.replace(" ", "").toLowerCase();
         if (ranges.startsWith("accept-language:")) {
             ranges = ranges.substring(16); // delete unnecessary prefix
@@ -331,6 +332,7 @@
         return list;
     }
 
+    // BEGIN Android-added: backport OpenJDK 9 fix for JDK-8166994
     /**
      * A faster alternative approach to String.replaceFirst(), if the given
      * string is a literal String, not a regex.
@@ -345,6 +347,7 @@
                     + range.substring(pos + substr.length());
         }
     }
+    // END Android-added: backport OpenJDK 9 fix for JDK-8166994
 
     private static String[] getEquivalentsForLanguage(String range) {
         String r = range;
@@ -354,6 +357,9 @@
                 String equiv = LocaleEquivalentMaps.singleEquivMap.get(r);
                 // Return immediately for performance if the first matching
                 // subtag is found.
+// BEGIN Android-added: backport OpenJDK 9 fix for JDK-8166994
+// Upstream bug: https://bugs.openjdk.java.net/browse/JDK-8166994
+// Upstream fix: http://hg.openjdk.java.net/jdk9/dev/jdk/rev/60837db5d445
                 return new String[]{replaceFirstSubStringMatch(range,
                     r, equiv)};
             } else if (LocaleEquivalentMaps.multiEquivsMap.containsKey(r)) {
@@ -364,6 +370,7 @@
                             r, equivs[i]);
                 }
                 return result;
+// END Android-added: backport OpenJDK 9 fix for JDK-8166994
             }
 
             // Truncate the last subtag simply.
diff --git a/ojluni/src/main/java/sun/util/locale/LocaleObjectCache.java b/ojluni/src/main/java/sun/util/locale/LocaleObjectCache.java
index 88920aa..eae1480 100644
--- a/ojluni/src/main/java/sun/util/locale/LocaleObjectCache.java
+++ b/ojluni/src/main/java/sun/util/locale/LocaleObjectCache.java
@@ -57,8 +57,10 @@
             value = entry.get();
         }
         if (value == null) {
-            key = normalizeKey(key);
             V newVal = createObject(key);
+            // make sure key is normalized *after* the object creation
+            // so that newVal is assured to be created from a valid key.
+            key = normalizeKey(key);
             if (key == null || newVal == null) {
                 // subclass must return non-null key/value object
                 return null;
diff --git a/ojluni/src/main/java/sun/util/locale/LocaleUtils.java b/ojluni/src/main/java/sun/util/locale/LocaleUtils.java
index 9a89dc0..ead48fc 100644
--- a/ojluni/src/main/java/sun/util/locale/LocaleUtils.java
+++ b/ojluni/src/main/java/sun/util/locale/LocaleUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
diff --git a/ojluni/src/main/java/sun/util/logging/LoggingProxy.java b/ojluni/src/main/java/sun/util/logging/LoggingProxy.java
index 9fbcc73..c044a5a 100644
--- a/ojluni/src/main/java/sun/util/logging/LoggingProxy.java
+++ b/ojluni/src/main/java/sun/util/logging/LoggingProxy.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/sun/util/logging/LoggingSupport.java b/ojluni/src/main/java/sun/util/logging/LoggingSupport.java
index dd65b74..67b617d 100644
--- a/ojluni/src/main/java/sun/util/logging/LoggingSupport.java
+++ b/ojluni/src/main/java/sun/util/logging/LoggingSupport.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/sun/util/logging/PlatformLogger.java b/ojluni/src/main/java/sun/util/logging/PlatformLogger.java
index f9849c5..1ed8811 100644
--- a/ojluni/src/main/java/sun/util/logging/PlatformLogger.java
+++ b/ojluni/src/main/java/sun/util/logging/PlatformLogger.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -84,22 +84,18 @@
  * @since 1.7
  */
 public class PlatformLogger {
-    /*
-     * These constants should be shortcuts to Level enum constants that
-     * the clients of sun.util.logging.PlatformLogger require no source
-     * modification and avoid the conversion from int to Level enum.
-     *
-     * This can be done when JavaFX is converted to use the new PlatformLogger.Level API.
-     */
-    public static final int OFF     = Integer.MAX_VALUE;
-    public static final int SEVERE  = 1000;
-    public static final int WARNING = 900;
-    public static final int INFO    = 800;
-    public static final int CONFIG  = 700;
-    public static final int FINE    = 500;
-    public static final int FINER   = 400;
-    public static final int FINEST  = 300;
-    public static final int ALL     = Integer.MIN_VALUE;
+
+    // The integer values must match that of {@code java.util.logging.Level}
+    // objects.
+    private static final int OFF     = Integer.MAX_VALUE;
+    private static final int SEVERE  = 1000;
+    private static final int WARNING = 900;
+    private static final int INFO    = 800;
+    private static final int CONFIG  = 700;
+    private static final int FINE    = 500;
+    private static final int FINER   = 400;
+    private static final int FINEST  = 300;
+    private static final int ALL     = Integer.MIN_VALUE;
 
     /**
      * PlatformLogger logging levels.
@@ -126,19 +122,19 @@
         /* java.util.logging.Level */ Object javaLevel;
 
         // ascending order for binary search matching the list of enum constants
-        private static final int[] levelValues = new int[] {
+        private static final int[] LEVEL_VALUES = new int[] {
             PlatformLogger.ALL, PlatformLogger.FINEST, PlatformLogger.FINER,
             PlatformLogger.FINE, PlatformLogger.CONFIG, PlatformLogger.INFO,
             PlatformLogger.WARNING, PlatformLogger.SEVERE, PlatformLogger.OFF
         };
 
         public int intValue() {
-            return levelValues[this.ordinal()];
+            return LEVEL_VALUES[this.ordinal()];
         }
 
         static Level valueOf(int level) {
             switch (level) {
-                // ordering per the highest occurences in the jdk source
+                // ordering per the highest occurrences in the jdk source
                 // finest, fine, finer, info first
                 case PlatformLogger.FINEST  : return Level.FINEST;
                 case PlatformLogger.FINE    : return Level.FINE;
@@ -152,7 +148,7 @@
             }
             // return the nearest Level value >= the given level,
             // for level > SEVERE, return SEVERE and exclude OFF
-            int i = Arrays.binarySearch(levelValues, 0, levelValues.length-2, level);
+            int i = Arrays.binarySearch(LEVEL_VALUES, 0, LEVEL_VALUES.length-2, level);
             return values()[i >= 0 ? i : (-i-1)];
         }
     }
@@ -169,23 +165,22 @@
                 }
             });
 
-        // Android-removed: Unnecessary on android, and gets in the way of obfuscated
-        // releases.
-        //
+        // Android-removed: JavaLoggerProxy is unneeded, complicates obfuscated releases.
+        /*
         // force loading of all JavaLoggerProxy (sub)classes to make JIT de-optimizations
         // less probable.  Don't initialize JavaLoggerProxy class since
         // java.util.logging may not be enabled.
-        //
-        // try {
-        //     Class.forName("sun.util.logging.PlatformLogger$DefaultLoggerProxy",
-        //                   false,
-        //                   PlatformLogger.class.getClassLoader());
-        //     Class.forName("sun.util.logging.PlatformLogger$JavaLoggerProxy",
-        //                   false,   // do not invoke class initializer
-        //                   PlatformLogger.class.getClassLoader());
-        // } catch (ClassNotFoundException ex) {
-        //     throw new InternalError(ex.getMessage());
-        // }
+        try {
+            Class.forName("sun.util.logging.PlatformLogger$DefaultLoggerProxy",
+                          false,
+                          PlatformLogger.class.getClassLoader());
+            Class.forName("sun.util.logging.PlatformLogger$JavaLoggerProxy",
+                          false,   // do not invoke class initializer
+                          PlatformLogger.class.getClassLoader());
+        } catch (ClassNotFoundException ex) {
+            throw new InternalError(ex);
+        }
+        */
     }
 
     // Table of known loggers.  Maps names to PlatformLoggers.
@@ -267,39 +262,6 @@
     /**
      * Returns true if a message of the given level would actually
      * be logged by this logger.
-     *
-     * @deprecated Use isLoggable(Level) instead.
-     */
-    @Deprecated
-    public boolean isLoggable(int levelValue) {
-        return isLoggable(Level.valueOf(levelValue));
-    }
-
-    /**
-     * Gets the current log level. Returns 0 if the current effective level is
-     * not set (equivalent to Logger.getLevel() returns null).
-     *
-     * @deprecated Use level() instead
-     */
-    @Deprecated
-    public int getLevel() {
-        Level level = loggerProxy.getLevel();
-        return level != null ? level.intValue() : 0;
-    }
-
-    /**
-     * Sets the log level.
-     *
-     * @deprecated Use setLevel(Level) instead
-     */
-    @Deprecated
-    public void setLevel(int newLevel) {
-        loggerProxy.setLevel(newLevel == 0 ? null : Level.valueOf(newLevel));
-    }
-
-    /**
-     * Returns true if a message of the given level would actually
-     * be logged by this logger.
      */
     public boolean isLoggable(Level level) {
         if (level == null) {
@@ -588,6 +550,16 @@
 
             String logClassName = "sun.util.logging.PlatformLogger";
             boolean lookingForLogger = true;
+            // Android-changed: Different way to access throwable.getStackTrace()
+            // OpenJDK's faster way via SharedSecrets.getJavaLangAccess()
+            // is not available on Android.
+            /*
+            for (int ix = 0; ix < depth; ix++) {
+                // Calling getStackTraceElement directly prevents the VM
+                // from paying the cost of building the entire stack frame.
+                StackTraceElement frame =
+                    access.getStackTraceElement(throwable, ix);
+            */
             for (StackTraceElement frame : throwable.getStackTrace()) {
                 String cname = frame.getClassName();
                 if (lookingForLogger) {
diff --git a/ojluni/src/main/java/sun/util/resources/OpenListResourceBundle.java b/ojluni/src/main/java/sun/util/resources/OpenListResourceBundle.java
index 86a91f8..462b0a7 100644
--- a/ojluni/src/main/java/sun/util/resources/OpenListResourceBundle.java
+++ b/ojluni/src/main/java/sun/util/resources/OpenListResourceBundle.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -42,6 +42,7 @@
 
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.ResourceBundle;
 import java.util.Set;
@@ -66,7 +67,8 @@
     }
 
     // Implements java.util.ResourceBundle.handleGetObject; inherits javadoc specification.
-    public Object handleGetObject(String key) {
+    @Override
+    protected Object handleGetObject(String key) {
         if (key == null) {
             throw new NullPointerException();
         }
@@ -78,26 +80,39 @@
     /**
      * Implementation of ResourceBundle.getKeys.
      */
+    @Override
     public Enumeration<String> getKeys() {
-        ResourceBundle parent = this.parent;
-        return new ResourceBundleEnumeration(handleGetKeys(),
-                (parent != null) ? parent.getKeys() : null);
-    }
+        ResourceBundle parentBundle = this.parent;
+        return new ResourceBundleEnumeration(handleKeySet(),
+                (parentBundle != null) ? parentBundle.getKeys() : null);
+     }
 
     /**
-     * Returns a set of keys provided in this resource bundle
+     * Returns a set of keys provided in this resource bundle,
+     * including no parents.
      */
-    public Set<String> handleGetKeys() {
+    @Override
+    protected Set<String> handleKeySet() {
         loadLookupTablesIfNecessary();
-
         return lookup.keySet();
     }
 
-    /**
-     * Returns the parent bundle
-     */
-    public OpenListResourceBundle getParent() {
-        return (OpenListResourceBundle)parent;
+    @Override
+    public Set<String> keySet() {
+        if (keyset != null) {
+            return keyset;
+        }
+        Set<String> ks = createSet();
+        ks.addAll(handleKeySet());
+        if (parent != null) {
+            ks.addAll(parent.keySet());
+        }
+        synchronized (this) {
+            if (keyset == null) {
+                keyset = ks;
+            }
+        }
+        return keyset;
     }
 
     /**
@@ -118,12 +133,9 @@
      * We lazily load the lookup hashtable.  This function does the
      * loading.
      */
-    private synchronized void loadLookup() {
-        if (lookup != null)
-            return;
-
+    private void loadLookup() {
         Object[][] contents = getContents();
-        Map temp = createMap(contents.length);
+        Map<String, Object> temp = createMap(contents.length);
         for (int i = 0; i < contents.length; ++i) {
             // key must be non-null String, value must be non-null
             String key = (String) contents[i][0];
@@ -133,16 +145,25 @@
             }
             temp.put(key, value);
         }
-        lookup = temp;
+        synchronized (this) {
+            if (lookup == null) {
+                lookup = temp;
+            }
+        }
     }
 
     /**
      * Lets subclasses provide specialized Map implementations.
      * Default uses HashMap.
      */
-    protected Map createMap(int size) {
-        return new HashMap(size);
+    protected <K, V> Map<K, V> createMap(int size) {
+        return new HashMap<>(size);
     }
 
-    private Map lookup = null;
+    protected <E> Set<E> createSet() {
+        return new HashSet<>();
+    }
+
+    private volatile Map<String, Object> lookup = null;
+    private volatile Set<String> keyset;
 }
diff --git a/openjdk_java_files.mk b/openjdk_java_files.mk
index 7c13ca6..e500bd86 100644
--- a/openjdk_java_files.mk
+++ b/openjdk_java_files.mk
@@ -1398,7 +1398,6 @@
     ojluni/src/main/java/sun/misc/FloatConsts.java \
     ojluni/src/main/java/sun/misc/FormattedFloatingDecimal.java \
     ojluni/src/main/java/sun/misc/FpUtils.java \
-    ojluni/src/main/java/sun/misc/Hashing.java \
     ojluni/src/main/java/sun/misc/HexDumpEncoder.java \
     ojluni/src/main/java/sun/misc/InvalidJarIndexException.java \
     ojluni/src/main/java/sun/misc/IOUtils.java \
diff --git a/tools/docs/crypto/README b/tools/docs/crypto/README
index cc6b6eb..9a34b7f 100644
--- a/tools/docs/crypto/README
+++ b/tools/docs/crypto/README
@@ -2,7 +2,8 @@
 
 The central file is data/crypto_support.json, which is a JSON file that contains
 the supported API levels for each crypto algorithm that has ever been supported
-by Android.  The categories are identified as described in the JCA.
+by Android.  The categories are identified as described in the JCA, along with
+a couple extra classes.
 
 Each algorithm has up to three properties:
 
@@ -24,9 +25,8 @@
 
 Getting the set of supported algorithms is done using
 src/java/libcore/java/security/ListProviders.java.  It's important that this is
-run using vogar (in mode=device, the default) rather than in an app container,
-as this documentation only includes the libcore-supported crypto support, but
-the Android frameworks (in particular, Android KeyStore) can add additional
+run using vogar in mode=activity rather than the default of mode=device, as
+the Android frameworks (in particular, Android Keystore) can add additional
 support.
 
 The data from ListProviders is fed into update_crypto_support.py, which rewrites
@@ -38,4 +38,5 @@
 
 Finally, format_supported_algorithm_table.py reads the data file and outputs
 a collection of HTML tables suitable for copying-and-pasting into the docs
-to stdout.
+to stdout.  Add --javadoc to produce output appropriate for inclusion in
+Javadoc.
diff --git a/tools/docs/crypto/crypto_docs.py b/tools/docs/crypto/crypto_docs.py
index d1f220d..482e38e 100644
--- a/tools/docs/crypto/crypto_docs.py
+++ b/tools/docs/crypto/crypto_docs.py
@@ -29,3 +29,11 @@
     data = json.loads(stripped_contents)
     f.close()
     return data
+
+
+def find_by_name(seq, name):
+    """Returns the first element in seq with the given name."""
+    for item in seq:
+        if item['name'] == name:
+            return item
+    return None
diff --git a/tools/docs/crypto/data/crypto_support.json b/tools/docs/crypto/data/crypto_support.json
index 38834d9..124a457 100644
--- a/tools/docs/crypto/data/crypto_support.json
+++ b/tools/docs/crypto/data/crypto_support.json
@@ -887,6 +887,1500 @@
     {
       "algorithms": [
         {
+          "deprecated": "true",
+          "name": "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_DSS_WITH_DES_CBC_SHA",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_RSA_WITH_DES_CBC_SHA",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_WITH_DES_CBC_SHA",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_WITH_RC4_128_MD5",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_WITH_RC4_128_SHA",
+          "supported_api_levels": "9-23"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_WITH_DES_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "9-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "20-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_DES_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
+          "supported_api_levels": "24+"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
+          "supported_api_levels": "20-23"
+        },
+        {
+          "name": "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "21+"
+        },
+        {
+          "name": "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "21+"
+        },
+        {
+          "name": "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256",
+          "supported_api_levels": "24+"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
+          "supported_api_levels": "24+"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
+          "supported_api_levels": "20-23"
+        },
+        {
+          "name": "TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
+          "supported_api_levels": "20+"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_PSK_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": ""
+        },
+        {
+          "name": "TLS_PSK_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "21+"
+        },
+        {
+          "name": "TLS_PSK_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "21+"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "name": "TLS_RSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "9+"
+        },
+        {
+          "name": "TLS_RSA_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_RSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_RSA_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20+"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_RSA_WITH_DES_CBC_SHA",
+          "supported_api_levels": "1-8"
+        }
+      ],
+      "name": "SSLEngine.Enabled"
+    },
+    {
+      "algorithms": [
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_DSS_WITH_DES_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_RSA_WITH_DES_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DH_anon_WITH_DES_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DH_anon_WITH_RC4_128_MD5",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "name": "SSL_RSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "9+"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_WITH_DES_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_WITH_NULL_MD5",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_WITH_NULL_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_WITH_RC4_128_MD5",
+          "supported_api_levels": "9-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_WITH_RC4_128_SHA",
+          "supported_api_levels": "9-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_WITH_DES_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "9-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",
+          "supported_api_levels": "20-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "9-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",
+          "supported_api_levels": "20-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_DES_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DH_DSS_WITH_DES_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DH_RSA_WITH_DES_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DH_anon_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DH_anon_WITH_AES_128_CBC_SHA256",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DH_anon_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DH_anon_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DH_anon_WITH_AES_256_CBC_SHA256",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DH_anon_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DH_anon_WITH_DES_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
+          "supported_api_levels": "24+"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDHE_ECDSA_WITH_NULL_SHA",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
+          "supported_api_levels": "20-25"
+        },
+        {
+          "name": "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "21+"
+        },
+        {
+          "name": "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "21+"
+        },
+        {
+          "name": "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256",
+          "supported_api_levels": "24+"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
+          "supported_api_levels": "24+"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDHE_RSA_WITH_NULL_SHA",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
+          "supported_api_levels": "20-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_NULL_SHA",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_NULL_SHA",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_RC4_128_SHA",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_anon_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_anon_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_anon_WITH_NULL_SHA",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_anon_WITH_RC4_128_SHA",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "name": "TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_FALLBACK_SCSV",
+          "supported_api_levels": "21+"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_NULL_WITH_NULL_NULL",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_PSK_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "21-22"
+        },
+        {
+          "name": "TLS_PSK_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "21+"
+        },
+        {
+          "name": "TLS_PSK_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "21+"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_PSK_WITH_RC4_128_SHA",
+          "supported_api_levels": "21-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "name": "TLS_RSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "9+"
+        },
+        {
+          "name": "TLS_RSA_WITH_AES_128_CBC_SHA256",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_RSA_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_RSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "9+"
+        },
+        {
+          "name": "TLS_RSA_WITH_AES_256_CBC_SHA256",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_RSA_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20+"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_RSA_WITH_DES_CBC_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_RSA_WITH_NULL_MD5",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_RSA_WITH_NULL_SHA",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_RSA_WITH_NULL_SHA256",
+          "supported_api_levels": "20-22"
+        }
+      ],
+      "name": "SSLEngine.Supported"
+    },
+    {
+      "algorithms": [
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_DSS_WITH_DES_CBC_SHA",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_RSA_WITH_DES_CBC_SHA",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_WITH_DES_CBC_SHA",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_WITH_RC4_128_MD5",
+          "supported_api_levels": "9-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_WITH_RC4_128_SHA",
+          "supported_api_levels": "9-23"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "11-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "9-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "11-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "11-19"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "11+"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "11+"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
+          "supported_api_levels": "24+"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
+          "supported_api_levels": "11-23"
+        },
+        {
+          "name": "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "21+"
+        },
+        {
+          "name": "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "21+"
+        },
+        {
+          "name": "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256",
+          "supported_api_levels": "24+"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "11-19"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "11+"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "11+"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
+          "supported_api_levels": "24+"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
+          "supported_api_levels": "11-23"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "11-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "11-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "11-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
+          "supported_api_levels": "11-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "11-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "11-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "11-19"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_RC4_128_SHA",
+          "supported_api_levels": "11-19"
+        },
+        {
+          "name": "TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
+          "supported_api_levels": "11+"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_PSK_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": ""
+        },
+        {
+          "name": "TLS_PSK_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "21+"
+        },
+        {
+          "name": "TLS_PSK_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "21+"
+        },
+        {
+          "name": "TLS_RSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "9+"
+        },
+        {
+          "name": "TLS_RSA_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_RSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "11+"
+        },
+        {
+          "name": "TLS_RSA_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20+"
+        }
+      ],
+      "name": "SSLSocket.Enabled"
+    },
+    {
+      "algorithms": [
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_DSS_WITH_DES_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DHE_RSA_WITH_DES_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DH_anon_WITH_DES_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_DH_anon_WITH_RC4_128_MD5",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "name": "SSL_RSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "9+"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_WITH_DES_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_WITH_NULL_MD5",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_WITH_NULL_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_WITH_RC4_128_MD5",
+          "supported_api_levels": "9-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "SSL_RSA_WITH_RC4_128_SHA",
+          "supported_api_levels": "9-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "9-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",
+          "supported_api_levels": "20-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "9-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",
+          "supported_api_levels": "20-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DH_anon_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DH_anon_WITH_AES_128_CBC_SHA256",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DH_anon_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DH_anon_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "9-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DH_anon_WITH_AES_256_CBC_SHA256",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_DH_anon_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "11-22"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "11+"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "11+"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
+          "supported_api_levels": "24+"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDHE_ECDSA_WITH_NULL_SHA",
+          "supported_api_levels": "11-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
+          "supported_api_levels": "11-25"
+        },
+        {
+          "name": "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "21+"
+        },
+        {
+          "name": "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "21+"
+        },
+        {
+          "name": "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256",
+          "supported_api_levels": "24+"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "11-22"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "11+"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "11+"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
+          "supported_api_levels": "24+"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDHE_RSA_WITH_NULL_SHA",
+          "supported_api_levels": "11-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
+          "supported_api_levels": "11-25"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "11-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "11-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "11-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_NULL_SHA",
+          "supported_api_levels": "11-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
+          "supported_api_levels": "11-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "11-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "11-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "11-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_NULL_SHA",
+          "supported_api_levels": "11-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_RSA_WITH_RC4_128_SHA",
+          "supported_api_levels": "11-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "11-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_anon_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "11-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_anon_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "11-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_anon_WITH_NULL_SHA",
+          "supported_api_levels": "11-22"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_ECDH_anon_WITH_RC4_128_SHA",
+          "supported_api_levels": "11-22"
+        },
+        {
+          "name": "TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
+          "supported_api_levels": "11+"
+        },
+        {
+          "name": "TLS_FALLBACK_SCSV",
+          "supported_api_levels": "21+"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_PSK_WITH_3DES_EDE_CBC_SHA",
+          "supported_api_levels": "21-22"
+        },
+        {
+          "name": "TLS_PSK_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "21+"
+        },
+        {
+          "name": "TLS_PSK_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "21+"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_PSK_WITH_RC4_128_SHA",
+          "supported_api_levels": "21-25"
+        },
+        {
+          "name": "TLS_RSA_WITH_AES_128_CBC_SHA",
+          "supported_api_levels": "9+"
+        },
+        {
+          "name": "TLS_RSA_WITH_AES_128_CBC_SHA256",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_RSA_WITH_AES_128_GCM_SHA256",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_RSA_WITH_AES_256_CBC_SHA",
+          "supported_api_levels": "9+"
+        },
+        {
+          "name": "TLS_RSA_WITH_AES_256_CBC_SHA256",
+          "supported_api_levels": "20+"
+        },
+        {
+          "name": "TLS_RSA_WITH_AES_256_GCM_SHA384",
+          "supported_api_levels": "20+"
+        },
+        {
+          "deprecated": "true",
+          "name": "TLS_RSA_WITH_NULL_SHA256",
+          "supported_api_levels": "20-22"
+        }
+      ],
+      "name": "SSLSocket.Supported"
+    },
+    {
+      "algorithms": [
+        {
           "name": "AES",
           "supported_api_levels": "23+"
         },
@@ -1227,5 +2721,5 @@
       "name": "TrustManagerFactory"
     }
   ],
-  "last_updated": "2017-03-21 16:04:30 UTC"
+  "last_updated": "2017-05-05 07:40:17 UTC"
 }
\ No newline at end of file
diff --git a/tools/docs/crypto/format_supported_algorithm_table.py b/tools/docs/crypto/format_supported_algorithm_table.py
index 3b23066..5a6dd15 100755
--- a/tools/docs/crypto/format_supported_algorithm_table.py
+++ b/tools/docs/crypto/format_supported_algorithm_table.py
@@ -26,6 +26,9 @@
 import crypto_docs
 
 
+find_by_name = crypto_docs.find_by_name
+
+
 def sort_by_name(seq):
     return sorted(seq, key=lambda x: x['name'])
 
@@ -46,10 +49,14 @@
     output.append('')
     output.append('<ul>')
     for category in categories:
-        output.append('  <li><a href="#Supported{name}">'
-               '<code>{name}</code></a></li>'.format(**category))
+        if not category['name'].endswith('.Enabled'):
+            output.append('  <li><a href="#Supported{name}">'
+                   '<code>{name}</code></a></li>'.format(**category))
     output.append('</ul>')
     for category in categories:
+        if category['name'].endswith('.Enabled'):
+            # These are handled in the "Supported" section below
+            continue
         if category['name'] == 'Cipher':
             # We display ciphers in a four-column table to conserve space and
             # so that it's more comprehensible.  To do this, we have to
@@ -155,6 +162,39 @@
                 i += 1
             output.append('  </tbody>')
             output.append('</table>')
+        elif category['name'].endswith('.Supported'):
+            # Some categories come with a "Supported" and "Enabled" list, and we
+            # group those together in one table for display.  Every entry that's enabled
+            # must be supported, so we can just look up the enabled version for each
+            # supported item
+            basename = category['name'][:-len('.Supported')]
+            supported = sort_by_name(category['algorithms'])
+            enabled = sort_by_name(find_by_name(categories, basename + '.Enabled')['algorithms'])
+            output.append('<h3 id="Supported{0}">{0}</h3>'.format(basename))
+            output.append('<table>')
+            output.append('  <thead>')
+            output.append('    <tr>')
+            output.append('      <th>Algorithm</th>')
+            output.append('      <th>Supported API Levels</th>')
+            output.append('      <th>Enabled By Default</th>')
+            output.append('    </tr>')
+            output.append('  </thead>')
+            output.append('  <tbody>')
+            for algorithm in supported:
+                if 'deprecated' in algorithm and algorithm['deprecated']:
+                    output.append('    <tr class="deprecated">')
+                else:
+                    output.append('    <tr>')
+                output.append('      <td>{name}</td>'.format(**algorithm))
+                output.append('      <td>{supported_api_levels}</td>'.format(**algorithm))
+                enabled_alg = find_by_name(enabled, algorithm['name'])
+                if enabled_alg is None:
+                    output.append('      <td></td>')
+                else:
+                    output.append('      <td>{supported_api_levels}</td>'.format(**enabled_alg))
+                output.append('    </tr>')
+            output.append('  </tbody>')
+            output.append('</table>')
         else:
             output.append('<h3 id="Supported{name}">{name}</h3>'.format(**category))
             output.append('<table>')
diff --git a/tools/docs/crypto/run_update_crypto_support.sh b/tools/docs/crypto/run_update_crypto_support.sh
index 5908fcc..501891c 100755
--- a/tools/docs/crypto/run_update_crypto_support.sh
+++ b/tools/docs/crypto/run_update_crypto_support.sh
@@ -13,5 +13,5 @@
   exit 1
 fi
 
-make -j48 vogar
+make -j48 vogar dx
 vogar --mode=activity --toolchain=jdk --multidex=false libcore/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java | libcore/tools/docs/crypto/update_crypto_support.py --api_level=$1 --rewrite_file libcore/tools/docs/crypto/data/crypto_support.json
diff --git a/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java b/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java
index 1cd86467..ab25382 100644
--- a/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java
+++ b/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java
@@ -16,18 +16,22 @@
 
 package libcore.java.security;
 
+import android.net.PskKeyManager;
+
 import java.security.NoSuchAlgorithmException;
 import java.security.Provider;
 import java.security.Security;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Comparator;
-import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 import java.util.TreeSet;
 import javax.crypto.Cipher;
 import javax.crypto.NoSuchPaddingException;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
 
 /**
  * Prints a list of all algorithms provided by security providers.  Intended to be run
@@ -81,7 +85,7 @@
         System.out.println((SHOW_PROVIDER ? p.getName() + ": " : "") + type + " " + algorithm);
     }
 
-    public static void main(String[] argv) {
+    public static void main(String[] argv) throws Exception {
         System.out.println("BEGIN ALGORITHM LIST");
         for (Provider p : Security.getProviders()) {
             Set<Provider.Service> services = new TreeSet<Provider.Service>(
@@ -126,6 +130,31 @@
                 }
             }
         }
+        // SSLEngine and SSLSocket algorithms are handled outside the default provider system
+        SSLContext defaultContext = SSLContext.getDefault();
+        // PSK cipher suites are only enabled when a PskKeyManager is available, but some other
+        // suites are disabled in that case, so check for both
+        SSLContext pskContext = SSLContext.getInstance("TLS");
+        pskContext.init(
+                new KeyManager[] {new PskKeyManager(){}},
+                new TrustManager[0],
+                null);
+        for (SSLContext sslContext : new SSLContext[] {defaultContext, pskContext}) {
+            SSLEngine engine = sslContext.createSSLEngine();
+            for (String suite : engine.getSupportedCipherSuites()) {
+                print(sslContext.getProvider(), "SSLEngine.Supported", suite);
+            }
+            for (String suite : engine.getEnabledCipherSuites()) {
+                print(sslContext.getProvider(), "SSLEngine.Enabled", suite);
+            }
+            SSLSocketFactory socketFactory = sslContext.getSocketFactory();
+            for (String suite : socketFactory.getSupportedCipherSuites()) {
+                print(sslContext.getProvider(), "SSLSocket.Supported", suite);
+            }
+            for (String suite : socketFactory.getDefaultCipherSuites()) {
+                print(sslContext.getProvider(), "SSLSocket.Enabled", suite);
+            }
+        }
         System.out.println("END ALGORITHM LIST");
     }
 }
\ No newline at end of file
diff --git a/tools/docs/crypto/update_crypto_support.py b/tools/docs/crypto/update_crypto_support.py
index 207e0f4..3138d7d 100755
--- a/tools/docs/crypto/update_crypto_support.py
+++ b/tools/docs/crypto/update_crypto_support.py
@@ -51,16 +51,24 @@
     'SecureRandom',
     'Signature',
     'SSLContext',
+    'SSLEngine.Enabled',
+    'SSLEngine.Supported',
+    'SSLSocket.Enabled',
+    'SSLSocket.Supported',
     'TrustManagerFactory',
 ]
 
+# For these categories, we really want to maintain the casing that was in the
+# original data, so avoid changing it.
+CASE_SENSITIVE_CATEGORIES = [
+    'SSLEngine.Enabled',
+    'SSLEngine.Supported',
+    'SSLSocket.Enabled',
+    'SSLSocket.Supported',
+]
 
-def find_by_name(seq, name):
-    """Returns the first element in seq with the given name."""
-    for item in seq:
-        if item['name'] == name:
-            return item
-    return None
+
+find_by_name = crypto_docs.find_by_name
 
 
 def find_by_normalized_name(seq, name):
@@ -193,7 +201,8 @@
                 new_algorithm = {'name': prev_alg['name']}
             else:
                 new_algorithm = {'name': alg}
-            new_algorithm['name'] = fix_name_caps_for_output(new_algorithm['name'])
+            if category not in CASE_SENSITIVE_CATEGORIES:
+                new_algorithm['name'] = fix_name_caps_for_output(new_algorithm['name'])
             new_level = None
             if alg in current_category and alg in prev_algorithms:
                 # Both old and new have it, just ensure the API level is right
diff --git a/tzdata/prototype_data/Android.mk b/tzdata/prototype_data/Android.mk
new file mode 100644
index 0000000..568bbaf
--- /dev/null
+++ b/tzdata/prototype_data/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2017 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := optional
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_PACKAGE_NAME := PrototypeTimeZoneDataApp
+LOCAL_CERTIFICATE := platform
+LOCAL_PRIVILEGED_MODULE := true
+include $(BUILD_PACKAGE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := optional
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_PACKAGE_NAME := PrototypeTimeZoneDataApp_data
+LOCAL_CERTIFICATE := platform
+# Needed to ensure the .apk can be installed. Without it the .apk is missing a .dex.
+LOCAL_DEX_PREOPT := false
+include $(BUILD_PACKAGE)
diff --git a/tzdata/prototype_data/AndroidManifest.xml b/tzdata/prototype_data/AndroidManifest.xml
new file mode 100644
index 0000000..ae0fe6b
--- /dev/null
+++ b/tzdata/prototype_data/AndroidManifest.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2017 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="libcore.tzdata.prototype_data"
+          android:versionCode="1">
+
+    <application
+        android:allowBackup="false"
+        android:label="@string/app_name">
+
+        <provider
+                android:name="libcore.tzdata.prototypedata.TimeZoneRulesDataProvider"
+                android:authorities="com.android.timezone"
+                android:grantUriPermissions="true"
+                android:readPermission="android.permission.UPDATE_TIME_ZONE_RULES"
+                android:exported="true">
+            <meta-data android:name="android.timezoneprovider.OPERATION"
+                     android:value="INSTALL"/>
+            <meta-data android:name="android.timezoneprovider.DATA_ASSET"
+                     android:value="test_2030a.zip"/>
+            <meta-data android:name="android.timezoneprovider.DISTRO_MAJOR_VERSION"
+                     android:value="1"/>
+            <meta-data android:name="android.timezoneprovider.DISTRO_MINOR_VERSION"
+                     android:value="1"/>
+            <meta-data android:name="android.timezoneprovider.RULES_VERSION"
+                     android:value="2030a"/>
+            <meta-data android:name="android.timezoneprovider.REVISION"
+                     android:value="1"/>
+        </provider>
+    </application>
+</manifest>
diff --git a/tzdata/prototype_data/assets/test_2030a.zip b/tzdata/prototype_data/assets/test_2030a.zip
new file mode 100644
index 0000000..ae274cd
--- /dev/null
+++ b/tzdata/prototype_data/assets/test_2030a.zip
Binary files differ
diff --git a/tzdata/prototype_data/res/values/strings.xml b/tzdata/prototype_data/res/values/strings.xml
new file mode 100644
index 0000000..e25341c
--- /dev/null
+++ b/tzdata/prototype_data/res/values/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2017 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.
+ -->
+
+<resources>
+    <string name="app_name">DataPrototypeApp</string>
+</resources>
diff --git a/tzdata/prototype_data/src/libcore/tzdata/prototypedata/TimeZoneRulesDataProvider.java b/tzdata/prototype_data/src/libcore/tzdata/prototypedata/TimeZoneRulesDataProvider.java
new file mode 100644
index 0000000..c7be72a
--- /dev/null
+++ b/tzdata/prototype_data/src/libcore/tzdata/prototypedata/TimeZoneRulesDataProvider.java
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2017 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.tzdata.prototypedata;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
+import android.database.AbstractCursor;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.ParcelFileDescriptor;
+import android.provider.TimeZoneRulesDataContract;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import libcore.io.Streams;
+
+import static android.content.res.AssetManager.ACCESS_STREAMING;
+import static android.provider.TimeZoneRulesDataContract.COLUMN_DISTRO_MAJOR_VERSION;
+import static android.provider.TimeZoneRulesDataContract.COLUMN_DISTRO_MINOR_VERSION;
+import static android.provider.TimeZoneRulesDataContract.COLUMN_OPERATION;
+import static android.provider.TimeZoneRulesDataContract.COLUMN_REVISION;
+import static android.provider.TimeZoneRulesDataContract.COLUMN_RULES_VERSION;
+import static android.provider.TimeZoneRulesDataContract.OPERATION_INSTALL;
+
+/**
+ * A basic implementation of a time zone data provider that can be used by OEMs to implement
+ * an APK asset-based solution for time zone updates.
+ */
+public final class TimeZoneRulesDataProvider extends ContentProvider {
+
+    static final String TAG = "TimeZoneRulesDataProvider";
+
+    private static final String METADATA_KEY_OPERATION = "android.timezoneprovider.OPERATION";
+    private static final String METADATA_KEY_ASSET = "android.timezoneprovider.DATA_ASSET";
+    private static final String METADATA_KEY_DISTRO_MAJOR_VERSION
+            = "android.timezoneprovider.DISTRO_MAJOR_VERSION";
+    private static final String METADATA_KEY_DISTRO_MINOR_VERSION
+            = "android.timezoneprovider.DISTRO_MINOR_VERSION";
+    private static final String METADATA_KEY_RULES_VERSION
+            = "android.timezoneprovider.RULES_VERSION";
+    private static final String METADATA_KEY_REVISION
+            = "android.timezoneprovider.REVISION";
+
+    private static final Set<String> KNOWN_COLUMN_NAMES;
+    private static final Map<String, Class<?>> KNOWN_COLUMN_TYPES;
+    static {
+        Set<String> columnNames = new HashSet<>();
+        columnNames.add(COLUMN_OPERATION);
+        columnNames.add(COLUMN_DISTRO_MAJOR_VERSION);
+        columnNames.add(COLUMN_DISTRO_MINOR_VERSION);
+        columnNames.add(COLUMN_RULES_VERSION);
+        columnNames.add(COLUMN_REVISION);
+        KNOWN_COLUMN_NAMES = Collections.unmodifiableSet(columnNames);
+
+        Map<String, Class<?>> columnTypes = new HashMap<>();
+        columnTypes.put(COLUMN_OPERATION, String.class);
+        columnTypes.put(COLUMN_DISTRO_MAJOR_VERSION, Integer.class);
+        columnTypes.put(COLUMN_DISTRO_MINOR_VERSION, Integer.class);
+        columnTypes.put(COLUMN_RULES_VERSION, String.class);
+        columnTypes.put(COLUMN_REVISION, Integer.class);
+        KNOWN_COLUMN_TYPES = Collections.unmodifiableMap(columnTypes);
+    }
+
+    private Map<String, Object> mColumnData = new HashMap<>();
+    private String mAssetName;
+
+    @Override
+    public boolean onCreate() {
+        return true;
+    }
+
+    @Override
+    public void attachInfo(Context context, ProviderInfo info) {
+        super.attachInfo(context, info);
+
+        // Sanity check our security
+        if (!TimeZoneRulesDataContract.AUTHORITY.equals(info.authority)) {
+            // The authority looked for by the time zone updater is fixed.
+            throw new SecurityException(
+                    "android:authorities must be \"" + TimeZoneRulesDataContract.AUTHORITY + "\"");
+        }
+        if (!info.grantUriPermissions) {
+            throw new SecurityException("Provider must grant uri permissions");
+        }
+        if (!info.exported) {
+            // The content provider is accessed directly so must be exported.
+            throw new SecurityException("android:exported must be \"true\"");
+        }
+        if (info.pathPermissions != null || info.writePermission != null) {
+            // Use readPermission only to implement permissions.
+            throw new SecurityException("Use android:readPermission only");
+        }
+        if (!android.Manifest.permission.UPDATE_TIME_ZONE_RULES.equals(info.readPermission)) {
+            // Writing is not supported.
+            throw new SecurityException("android:readPermission must be set to \""
+                    + android.Manifest.permission.UPDATE_TIME_ZONE_RULES
+                    + "\" is: " + info.readPermission);
+        }
+
+        // info.metadata is not filled in by default. Must ask for it again.
+        final ProviderInfo infoWithMetadata = context.getPackageManager()
+                .resolveContentProvider(info.authority, PackageManager.GET_META_DATA);
+        Bundle metaData = infoWithMetadata.metaData;
+        if (metaData == null) {
+            throw new SecurityException("meta-data must be set");
+        }
+
+        String operation;
+        try {
+            operation = getMandatoryMetaDataString(metaData, METADATA_KEY_OPERATION);
+            mColumnData.put(COLUMN_OPERATION, operation);
+        } catch (IllegalArgumentException e) {
+            throw new SecurityException(METADATA_KEY_OPERATION + " meta-data not set.");
+        }
+        if (OPERATION_INSTALL.equals(operation)) {
+            mColumnData.put(
+                    COLUMN_DISTRO_MAJOR_VERSION,
+                    getMandatoryMetaDataInt(metaData, METADATA_KEY_DISTRO_MAJOR_VERSION));
+            mColumnData.put(
+                    COLUMN_DISTRO_MINOR_VERSION,
+                    getMandatoryMetaDataInt(metaData, METADATA_KEY_DISTRO_MINOR_VERSION));
+            mColumnData.put(
+                    COLUMN_RULES_VERSION,
+                    getMandatoryMetaDataString(metaData, METADATA_KEY_RULES_VERSION));
+            mColumnData.put(
+                    COLUMN_REVISION,
+                    getMandatoryMetaDataInt(metaData, METADATA_KEY_REVISION));
+
+            // Make sure the asset containing the data to install exists.
+            String assetName = getMandatoryMetaDataString(metaData, METADATA_KEY_ASSET);
+            try {
+                InputStream is = context.getAssets().open(assetName);
+                // An exception is thrown if the asset does not exist. list(assetName) appears not
+                // to work with file paths.
+                is.close();
+            } catch (IOException e) {
+                throw new SecurityException("Unable to open asset:" + assetName);
+            }
+            mAssetName = assetName;
+        }
+    }
+
+    @Override
+    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection,
+            @Nullable String[] selectionArgs, @Nullable String sortOrder) {
+        if (!TimeZoneRulesDataContract.OPERATION_URI.equals(uri)) {
+            return null;
+        }
+        final List<String> projectionList = Arrays.asList(projection);
+        if (projection != null && !KNOWN_COLUMN_NAMES.containsAll(projectionList)) {
+            throw new UnsupportedOperationException(
+                    "Only " + KNOWN_COLUMN_NAMES + " columns supported.");
+        }
+
+        return new AbstractCursor() {
+            @Override
+            public int getCount() {
+                return 1;
+            }
+
+            @Override
+            public String[] getColumnNames() {
+                return projectionList.toArray(new String[0]);
+            }
+
+            @Override
+            public int getType(int column) {
+                String columnName = projectionList.get(column);
+                Class<?> columnJavaType = KNOWN_COLUMN_TYPES.get(columnName);
+                if (columnJavaType == String.class) {
+                    return Cursor.FIELD_TYPE_STRING;
+                } else if (columnJavaType == Integer.class) {
+                    return Cursor.FIELD_TYPE_INTEGER;
+                } else {
+                    throw new UnsupportedOperationException(
+                            "Unsupported type: " + columnJavaType + " for " + columnName);
+                }
+            }
+
+            @Override
+            public String getString(int column) {
+                checkPosition();
+                String columnName = projectionList.get(column);
+                if (KNOWN_COLUMN_TYPES.get(columnName) != String.class) {
+                    throw new UnsupportedOperationException();
+                }
+                return (String) mColumnData.get(columnName);
+            }
+
+            @Override
+            public short getShort(int column) {
+                checkPosition();
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public int getInt(int column) {
+                checkPosition();
+                String columnName = projectionList.get(column);
+                if (KNOWN_COLUMN_TYPES.get(columnName) != Integer.class) {
+                    throw new UnsupportedOperationException();
+                }
+                return (Integer) mColumnData.get(columnName);
+            }
+
+            @Override
+            public long getLong(int column) {
+                return getInt(column);
+            }
+
+            @Override
+            public float getFloat(int column) {
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public double getDouble(int column) {
+                checkPosition();
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public boolean isNull(int column) {
+                checkPosition();
+                return column != 0;
+            }
+        };
+    }
+
+    @Override
+    public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode)
+            throws FileNotFoundException {
+        if (!TimeZoneRulesDataContract.DATA_URI.equals(uri)) {
+            return null;
+        }
+        if (mAssetName == null) {
+            throw new FileNotFoundException();
+        }
+        if (!mode.equals("r")) {
+            throw new SecurityException("Only read-only access supported.");
+        }
+
+        // Extract the asset to a local dir. We do it every time: we don't make assumptions that the
+        // current copy (if any) is valid.
+        File localFile = extractAssetToLocalFile();
+
+        // Create a read-only ParcelFileDescriptor that can be passed to the caller process.
+        try {
+            return ParcelFileDescriptor.open(localFile, ParcelFileDescriptor.MODE_READ_ONLY,
+                    new Handler(Looper.getMainLooper()),
+                    e -> {
+                        if (e != null) {
+                            Log.w(TAG, "Error in OnCloseListener for " + localFile, e);
+                        }
+                        localFile.delete();
+                    });
+        } catch (IOException e) {
+            throw new RuntimeException("Unable to open asset file", e);
+        }
+    }
+
+    private File extractAssetToLocalFile() throws FileNotFoundException {
+        File extractedFile = new File(getContext().getFilesDir(), "timezone_data.zip");
+        InputStream is;
+        try {
+            is = getContext().getAssets().open(mAssetName, ACCESS_STREAMING);
+        } catch (FileNotFoundException e) {
+            throw e;
+        } catch (IOException e) {
+            FileNotFoundException fnfe = new FileNotFoundException("Problem reading asset");
+            fnfe.initCause(e);
+            throw fnfe;
+        }
+
+        try (InputStream fis = is;
+                FileOutputStream fos = new FileOutputStream(extractedFile, false /* append */)) {
+            Streams.copy(fis, fos);
+        } catch (IOException e) {
+            throw new RuntimeException("Unable to create asset storage file: " + extractedFile, e);
+        }
+        return extractedFile;
+    }
+
+    @Override
+    public String getType(@NonNull Uri uri) {
+        return null;
+    }
+
+    @Override
+    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int delete(@NonNull Uri uri, @Nullable String selection,
+            @Nullable String[] selectionArgs) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection,
+            @Nullable String[] selectionArgs) {
+        throw new UnsupportedOperationException();
+    }
+
+    private static String getMandatoryMetaDataString(Bundle metaData, String key) {
+        if (!metaData.containsKey(key)) {
+            throw new SecurityException("No metadata with key " + key + " found.");
+        }
+        return metaData.getString(key);
+    }
+
+    private static int getMandatoryMetaDataInt(Bundle metaData, String key) {
+        if (!metaData.containsKey(key)) {
+            throw new SecurityException("No metadata with key " + key + " found.");
+        }
+        return metaData.getInt(key, -1);
+    }
+}
diff --git a/tzdata/prototype_updater/Android.mk b/tzdata/prototype_updater/Android.mk
new file mode 100644
index 0000000..0ddaa45
--- /dev/null
+++ b/tzdata/prototype_updater/Android.mk
@@ -0,0 +1,24 @@
+# Copyright (C) 2017 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := optional
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_PACKAGE_NAME := PrototypeTimeZoneUpdaterApp
+LOCAL_CERTIFICATE := platform
+LOCAL_PRIVILEGED_MODULE := true
+include $(BUILD_PACKAGE)
diff --git a/tzdata/prototype_updater/AndroidManifest.xml b/tzdata/prototype_updater/AndroidManifest.xml
new file mode 100644
index 0000000..9b73b0b
--- /dev/null
+++ b/tzdata/prototype_updater/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2017 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="libcore.tzdata.prototype_updater"
+    android:versionCode="1">
+
+    <uses-permission android:name="android.permission.UPDATE_TIME_ZONE_RULES" />
+
+    <application
+        android:allowBackup="false"
+        android:label="@string/app_name">
+
+        <receiver android:name=".RulesCheckReceiver"
+                android:permission="android.permission.TRIGGER_TIME_ZONE_RULES_CHECK"
+                android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.timezone.TRIGGER_RULES_UPDATE_CHECK" />
+            </intent-filter>
+        </receiver>
+
+    </application>
+
+</manifest>
diff --git a/tzdata/prototype_updater/res/values/strings.xml b/tzdata/prototype_updater/res/values/strings.xml
new file mode 100644
index 0000000..204ae27
--- /dev/null
+++ b/tzdata/prototype_updater/res/values/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2017 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.
+ -->
+
+<resources>
+    <string name="app_name">PrototypeUpdaterApp</string>
+</resources>
diff --git a/tzdata/prototype_updater/src/libcore/tzdata/prototype_updater/RulesCheckReceiver.java b/tzdata/prototype_updater/src/libcore/tzdata/prototype_updater/RulesCheckReceiver.java
new file mode 100644
index 0000000..9f3a3b8
--- /dev/null
+++ b/tzdata/prototype_updater/src/libcore/tzdata/prototype_updater/RulesCheckReceiver.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2017 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.tzdata.prototype_updater;
+
+import android.app.timezone.Callback;
+import android.app.timezone.DistroFormatVersion;
+import android.app.timezone.DistroRulesVersion;
+import android.app.timezone.RulesManager;
+import android.app.timezone.RulesState;
+import android.app.timezone.RulesUpdaterContract;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.os.ParcelFileDescriptor;
+import android.provider.TimeZoneRulesDataContract;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import libcore.io.Streams;
+
+// TODO(nfuller): Prevent multiple broadcasts being handled at once?
+// TODO(nfuller): Improve logging
+// TODO(nfuller): Make the rules check async?
+// TODO(nfuller): Need async generally for SystemService calls from BroadcastReceiver?
+public class RulesCheckReceiver extends BroadcastReceiver {
+    final static String TAG = "RulesCheckReceiver";
+
+    private RulesManager mRulesManager;
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if (!RulesUpdaterContract.ACTION_TRIGGER_RULES_UPDATE_CHECK.equals(intent.getAction())) {
+            // Unknown. Do nothing.
+            Log.w(TAG, "Unrecognized intent action received: " + intent
+                    + ", action=" + intent.getAction());
+            return;
+        }
+
+        mRulesManager = (RulesManager) context.getSystemService("timezone");
+
+        byte[] token = intent.getByteArrayExtra(RulesUpdaterContract.EXTRA_CHECK_TOKEN);
+
+        // Note: We rely on the system server to check that the configured data application is the
+        // one that exposes the content provider with the well-known authority, and is a privileged
+        // application as required. It is *not* checked here and it is assumed the updater can trust
+        // the data application.
+
+        // Obtain the information about what the data app is telling us to do.
+        String operation = getOperation(context);
+        if (operation == null) {
+            // TODO Log
+            boolean success = true; // No point in retrying.
+            handleCheckComplete(token, success);
+            return;
+        }
+        switch (operation) {
+            case TimeZoneRulesDataContract.OPERATION_NO_OP:
+                // TODO Log
+                // No-op. Just acknowledge the check.
+                handleCheckComplete(token, true /* success */);
+                break;
+            case TimeZoneRulesDataContract.OPERATION_UNINSTALL:
+                // TODO Log
+                handleUninstall(token);
+                break;
+            case TimeZoneRulesDataContract.OPERATION_INSTALL:
+                // TODO Log
+                DistroVersionInfo distroVersionInfo = getDistroVersionInfo(context);
+                handleCopyAndInstall(context, token, distroVersionInfo);
+                break;
+            default:
+                // TODO Log
+                final boolean success = true; // No point in retrying.
+                handleCheckComplete(token, success);
+        }
+    }
+
+    private String getOperation(Context context) {
+        Cursor cursor = context.getContentResolver()
+                .query(TimeZoneRulesDataContract.OPERATION_URI,
+                        new String[] { TimeZoneRulesDataContract.COLUMN_OPERATION },
+                        null /* selection */, null /* selectionArgs */, null /* sortOrder */);
+        if (cursor == null) {
+            Log.e(TAG, "getOperation: query returned null");
+            return null;
+        }
+        if (!cursor.moveToFirst()) {
+            Log.e(TAG, "getOperation: query returned empty results");
+            return null;
+        }
+
+        try {
+            return cursor.getString(0);
+        } catch (Exception e) {
+            Log.e(TAG, "getOperation: getString() threw an exception", e);
+            return null;
+        }
+    }
+
+    private DistroVersionInfo getDistroVersionInfo(Context context) {
+        Cursor cursor = context.getContentResolver()
+                .query(TimeZoneRulesDataContract.OPERATION_URI,
+                        new String[] {
+                                TimeZoneRulesDataContract.COLUMN_DISTRO_MAJOR_VERSION,
+                                TimeZoneRulesDataContract.COLUMN_DISTRO_MINOR_VERSION,
+                                TimeZoneRulesDataContract.COLUMN_RULES_VERSION,
+                                TimeZoneRulesDataContract.COLUMN_REVISION},
+                        null /* selection */, null /* selectionArgs */, null /* sortOrder */);
+        if (cursor == null) {
+            Log.e(TAG, "getDistroVersionInfo: query returned null");
+            return null;
+        }
+        if (!cursor.moveToFirst()) {
+            Log.e(TAG, "getDistroVersionInfo: query returned empty results");
+            return null;
+        }
+
+        try {
+            return new DistroVersionInfo(
+                    cursor.getInt(0),
+                    cursor.getInt(1),
+                    cursor.getString(2),
+                    cursor.getInt(3));
+        } catch (Exception e) {
+            Log.e(TAG, "getDistroVersionInfo: getInt()/getString() threw an exception", e);
+            return null;
+        }
+    }
+
+    private void handleCopyAndInstall(Context context, byte[] checkToken,
+            DistroVersionInfo distroVersionInfo) {
+
+        // Decide whether to proceed with the install.
+        RulesState rulesState = mRulesManager.getRulesState();
+        if (!(rulesState.isDistroFormatVersionSupported(distroVersionInfo.mDistroFormatVersion)
+            && rulesState.isSystemVersionOlderThan(distroVersionInfo.mDistroRulesVersion))) {
+            // Nothing to do.
+            handleCheckComplete(checkToken, true /* success */);
+            return;
+        }
+
+        // Copy the data locally before passing it on....security and whatnot.
+        // TODO(nfuller): Need to do the copy here?
+        File file = copyDataToLocalFile(context);
+        if (file == null) {
+            // It's possible this may get better if the problem is related to storage space.
+            boolean success = false;
+            handleCheckComplete(checkToken, success);
+            return;
+        }
+        handleInstall(checkToken, file);
+    }
+
+    private static File copyDataToLocalFile(Context context) {
+        File extractedFile = new File(context.getFilesDir(), "temp.zip");
+        ParcelFileDescriptor fileDescriptor;
+        try {
+            fileDescriptor = context.getContentResolver().openFileDescriptor(
+                    TimeZoneRulesDataContract.DATA_URI, "r");
+            if (fileDescriptor == null) {
+                throw new FileNotFoundException("ContentProvider returned null");
+            }
+        } catch (FileNotFoundException e) {
+            Log.e(TAG, "copyDataToLocalFile: Unable to open file descriptor"
+                    + TimeZoneRulesDataContract.DATA_URI, e);
+            return null;
+        }
+
+        try (ParcelFileDescriptor pfd = fileDescriptor;
+             InputStream fis = new FileInputStream(pfd.getFileDescriptor());
+             FileOutputStream fos = new FileOutputStream(extractedFile, false /* append */)) {
+            Streams.copy(fis, fos);
+        } catch (IOException e) {
+            Log.e(TAG, "Unable to create asset storage file: " + extractedFile, e);
+            return null;
+        }
+        return extractedFile;
+    }
+
+    private void handleInstall(final byte[] checkToken, final File contentFile) {
+        // Convert the distroFile to a ParcelFileDescriptor.
+        final ParcelFileDescriptor distroFileDescriptor;
+        try {
+            distroFileDescriptor =
+                    ParcelFileDescriptor.open(contentFile, ParcelFileDescriptor.MODE_READ_ONLY);
+        } catch (FileNotFoundException e) {
+            Log.e(TAG, "Unable to create ParcelFileDescriptor from " + contentFile);
+            handleCheckComplete(checkToken, false /* success */);
+            return;
+        }
+
+        Callback callback = new Callback() {
+            @Override
+            public void onFinished(int status) {
+                Log.i(TAG, "onFinished: Finished install: " + status);
+
+                // TODO(nfuller): Can this be closed sooner?
+                try {
+                    distroFileDescriptor.close();
+                } catch (IOException e) {
+                    Log.e(TAG, "Unable to close ParcelFileDescriptor for " + contentFile, e);
+                } finally {
+                    // Delete the file we no longer need.
+                    contentFile.delete();
+                }
+            }
+        };
+
+        try {
+            int requestStatus =
+                    mRulesManager.requestInstall(distroFileDescriptor, checkToken, callback);
+            Log.i(TAG, "handleInstall: Request sent:" + requestStatus);
+        } catch (Exception e) {
+            Log.e(TAG, "handleInstall: Error", e);
+        }
+    }
+
+    private void handleUninstall(byte[] checkToken) {
+        Callback callback = new Callback() {
+            @Override
+            public void onFinished(int status) {
+                Log.i(TAG, "onFinished: Finished uninstall: " + status);
+            }
+        };
+
+        try {
+            int requestStatus =
+                    mRulesManager.requestUninstall(checkToken, callback);
+            Log.i(TAG, "handleUninstall: Request sent" + requestStatus);
+        } catch (Exception e) {
+            Log.e(TAG, "handleUninstall: Error", e);
+        }
+    }
+
+    private void handleCheckComplete(final byte[] token, final boolean success) {
+        try {
+            mRulesManager.requestNothing(token, success);
+            Log.i(TAG, "doInBackground: Called checkComplete: token="
+                    + Arrays.toString(token) + ", success=" + success);
+        } catch (Exception e) {
+            Log.e(TAG, "doInBackground: Error calling checkComplete()", e);
+        }
+    }
+
+    private static class DistroVersionInfo {
+
+        final DistroFormatVersion mDistroFormatVersion;
+        final DistroRulesVersion mDistroRulesVersion;
+
+        DistroVersionInfo(int distroMajorVersion, int distroMinorVersion,
+                String rulesVersion, int revision) {
+            mDistroFormatVersion = new DistroFormatVersion(distroMajorVersion, distroMinorVersion);
+            mDistroRulesVersion = new DistroRulesVersion(rulesVersion, revision);
+        }
+    }
+}
diff --git a/tzdata/update_test_app2/Android.mk b/tzdata/update_test_app2/Android.mk
new file mode 100644
index 0000000..c1ae636
--- /dev/null
+++ b/tzdata/update_test_app2/Android.mk
@@ -0,0 +1,25 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_PACKAGE_NAME := UpdateTestApp2
+LOCAL_CERTIFICATE := platform
+include $(BUILD_PACKAGE)
diff --git a/tzdata/update_test_app2/AndroidManifest.xml b/tzdata/update_test_app2/AndroidManifest.xml
new file mode 100644
index 0000000..fd42bb5
--- /dev/null
+++ b/tzdata/update_test_app2/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="libcore.tzdata.update_test_app2.installupdatetestapp" >
+
+    <uses-permission android:name="android.permission.UPDATE_TIME_ZONE_RULES" />
+
+    <application
+        android:allowBackup="false"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@android:style/Theme.Holo.Light">
+        <activity
+            android:name=".MainActivity"
+            android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
diff --git a/tzdata/update_test_app2/res/drawable/ic_launcher.png b/tzdata/update_test_app2/res/drawable/ic_launcher.png
new file mode 100644
index 0000000..96a442e
--- /dev/null
+++ b/tzdata/update_test_app2/res/drawable/ic_launcher.png
Binary files differ
diff --git a/tzdata/update_test_app2/res/layout/activity_main.xml b/tzdata/update_test_app2/res/layout/activity_main.xml
new file mode 100644
index 0000000..16e4b11
--- /dev/null
+++ b/tzdata/update_test_app2/res/layout/activity_main.xml
@@ -0,0 +1,98 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    tools:context=".MainActivity">
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/content_path"
+            android:id="@+id/content_path_label" />
+
+        <EditText
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/default_content_path"
+            android:id="@+id/content_path" />
+
+    </LinearLayout>
+
+    <Button
+        android:id="@+id/trigger_install_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:layout_centerVertical="true"
+        android:text="@string/trigger_install" />
+
+    <View
+            android:layout_width="fill_parent"
+            android:layout_height="2dip"
+            android:background="#FF00FF00" />
+
+    <Button
+        android:id="@+id/trigger_uninstall_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:layout_centerVertical="true"
+        android:text="@string/trigger_uninstall" />
+
+    <View
+            android:layout_width="fill_parent"
+            android:layout_height="2dip"
+            android:background="#FF00FF00" />
+
+    <CheckBox android:id="@+id/success_checkbox"
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:text="@string/success" />
+
+    <Button
+        android:id="@+id/trigger_nothing"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:layout_centerVertical="true"
+        android:text="@string/trigger_nothing" />
+
+    <View
+            android:layout_width="fill_parent"
+            android:layout_height="2dip"
+            android:background="#FF00FF00" />
+
+    <Button
+        android:id="@+id/get_rules_state_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:layout_centerVertical="true"
+        android:text="@string/get_rules_state" />
+
+    <View
+            android:layout_width="fill_parent"
+            android:layout_height="2dip"
+            android:background="#FF00FF00" />
+
+    <ScrollView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:scrollbars="vertical"
+            android:fillViewport="true">
+
+        <TextView
+                android:layout_width="fill_parent"
+                android:layout_height="fill_parent"
+                android:id="@+id/log"
+                android:singleLine="false" />
+
+    </ScrollView>
+
+</LinearLayout>
diff --git a/tzdata/update_test_app2/res/values/strings.xml b/tzdata/update_test_app2/res/values/strings.xml
new file mode 100644
index 0000000..9bb5f57
--- /dev/null
+++ b/tzdata/update_test_app2/res/values/strings.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">InstallUpdateTestApp2</string>
+    <string name="content_path">Content Path</string>
+    <string name="default_content_path">/data/local/tmp/out.zip</string>
+    <string name="trigger_install">Request Install</string>
+    <string name="trigger_uninstall">Request Uninstall</string>
+    <string name="trigger_nothing">Request Nothing</string>
+    <string name="success">Success</string>
+    <string name="get_rules_state">Get rules state</string>
+</resources>
diff --git a/tzdata/update_test_app2/src/libcore/tzdata/update_test_app2/installupdatetestapp/MainActivity.java b/tzdata/update_test_app2/src/libcore/tzdata/update_test_app2/installupdatetestapp/MainActivity.java
new file mode 100644
index 0000000..caa52c4
--- /dev/null
+++ b/tzdata/update_test_app2/src/libcore/tzdata/update_test_app2/installupdatetestapp/MainActivity.java
@@ -0,0 +1,211 @@
+/*
+ * 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.tzdata.update_test_app2.installupdatetestapp;
+
+import android.app.Activity;
+import android.app.timezone.Callback;
+import android.app.timezone.RulesManager;
+import android.app.timezone.RulesState;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Date;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class MainActivity extends Activity implements View.OnClickListener {
+
+    private EditText contentPathEditText;
+    private TextView logView;
+
+    private RulesManager rulesManager;
+    private Callback callback;
+    private ExecutorService executor;
+    private CheckBox successCheckbox;
+
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+        Button triggerInstallButton = (Button) findViewById(R.id.trigger_install_button);
+        triggerInstallButton.setOnClickListener(this);
+        Button triggerUninstallButton = (Button) findViewById(R.id.trigger_uninstall_button);
+        triggerUninstallButton.setOnClickListener(this);
+        Button triggerCheckCompleteButton = (Button) findViewById(R.id.trigger_nothing);
+        triggerCheckCompleteButton.setOnClickListener(this);
+        successCheckbox = (CheckBox) findViewById(R.id.success_checkbox);
+
+        Button getRulesStateButton = (Button) findViewById(R.id.get_rules_state_button);
+        getRulesStateButton.setOnClickListener(this);
+
+        contentPathEditText = (EditText) findViewById(R.id.content_path);
+        logView = (TextView) findViewById(R.id.log);
+        executor = Executors.newFixedThreadPool(1);
+        rulesManager = (RulesManager) getSystemService("timezone");
+        callback = new Callback() {
+            @Override
+            public void onFinished(int status) {
+                logString("Operation finished. Status=" + status);
+            }
+        };
+    }
+
+    private abstract class MyAsyncTask extends AsyncTask<Void, String, Void> {
+        @Override
+        protected void onProgressUpdate(String... values) {
+            for (String message : values) {
+                addToLog(message, null);
+            }
+        }
+    }
+
+    @Override
+    public void onClick(View v) {
+        MyAsyncTask task;
+        if (v.getId() == R.id.trigger_install_button) {
+            final String contentPath = contentPathEditText.getText().toString();
+            final File contentFile = new File(contentPath);
+
+            // Convert the contentFile to a ParcelFileDescriptor.
+            final ParcelFileDescriptor distroFileDescriptor =
+                    createParcelFileDescriptor(contentFile);
+            if (distroFileDescriptor == null) {
+                return;
+            }
+
+            Callback callback = new Callback() {
+                @Override
+                public void onFinished(int status) {
+                    logString("onFinished: Finished install: " + status);
+
+                    // TODO(nfuller): Can this be closed sooner?
+                    try {
+                        distroFileDescriptor.close();
+                    } catch (IOException e) {
+                        logString("Unable to close ParcelFileDescriptor for " + contentFile + ": "
+                                + exceptionToString(e));
+                    }
+                }
+            };
+
+            task = new MyAsyncTask() {
+                @Override
+                protected Void doInBackground(Void... params) {
+                    if (!contentFile.exists()) {
+                        publishProgress("Error: " +  contentFile + " does not exist.");
+                        return null;
+                    }
+                    try {
+                        int requestStatus = rulesManager.requestInstall(
+                                distroFileDescriptor, null /* checkToken */, callback);
+                        publishProgress("Request sent:" + requestStatus);
+                    } catch (Exception e) {
+                        publishProgress("Error", exceptionToString(e));
+                    }
+                    return null;
+               }
+            };
+        } else if (v.getId() == R.id.trigger_uninstall_button) {
+            task = new MyAsyncTask() {
+                @Override
+                protected Void doInBackground(Void... params) {
+                    try {
+                        int requestStatus = rulesManager.requestUninstall(
+                                null /* checkToken */, callback);
+                        publishProgress("Request sent:" + requestStatus);
+                    } catch (Exception e) {
+                        publishProgress("Error", exceptionToString(e));
+                    }
+                    return null;
+                }
+            };
+        } else if (v.getId() == R.id.trigger_nothing) {
+            final boolean success = successCheckbox.isChecked();
+            task = new MyAsyncTask() {
+                @Override
+                protected Void doInBackground(Void... params) {
+                    try {
+                        rulesManager.requestNothing(null /* checkToken */, success);
+                        publishProgress("Request sent");
+                    } catch (Exception e) {
+                        publishProgress("Error", exceptionToString(e));
+                    }
+                    return null;
+                }
+            };
+        } else if (v.getId() == R.id.get_rules_state_button) {
+            task = new MyAsyncTask() {
+                @Override
+                protected Void doInBackground(Void... params) {
+                    try {
+                        RulesState rulesState = rulesManager.getRulesState();
+                        publishProgress("Rules state: " + rulesState);
+                    } catch (Exception e) {
+                        publishProgress("Error", exceptionToString(e));
+                    }
+                    return null;
+                }
+            };
+        } else {
+            addToLog("Unknown button", null);
+            return;
+        }
+        task.executeOnExecutor(executor);
+    }
+
+    private ParcelFileDescriptor createParcelFileDescriptor(File contentFile) {
+        try {
+            return ParcelFileDescriptor.open(contentFile, ParcelFileDescriptor.MODE_READ_ONLY);
+        } catch (FileNotFoundException e) {
+            logString("Unable to create ParcelFileDescriptor from " + contentFile + ": "
+                    + exceptionToString(e));
+            return null;
+        }
+    }
+
+    private void addToLog(String message, Exception e) {
+        logString(message);
+        if (e != null) {
+            String text = exceptionToString(e);
+            logString(text);
+        }
+    }
+
+    private void logString(String value) {
+        logView.append(new Date() + " " + value + "\n");
+        int scrollAmount =
+                logView.getLayout().getLineTop(logView.getLineCount()) - logView.getHeight();
+        logView.scrollTo(0, scrollAmount);
+    }
+
+    private static String exceptionToString(Exception e) {
+        StringWriter writer = new StringWriter();
+        e.printStackTrace(new PrintWriter(writer));
+        return writer.getBuffer().toString();
+    }
+}