Merge "Fix an ntohs/htons issue."
diff --git a/dalvik/src/main/java/dalvik/system/CloseGuard.java b/dalvik/src/main/java/dalvik/system/CloseGuard.java
index df36867..a45ffa1 100644
--- a/dalvik/src/main/java/dalvik/system/CloseGuard.java
+++ b/dalvik/src/main/java/dalvik/system/CloseGuard.java
@@ -40,6 +40,7 @@
  *
  *       protected void finalize() throws Throwable {
  *           try {
+ *               // Note that guard could be null if the constructor threw.
  *               if (guard != null) {
  *                   guard.warnIfOpen();
  *               }
@@ -76,6 +77,7 @@
  *
  *       protected void finalize() throws Throwable {
  *           try {
+ *               // Note that guard could be null if the constructor threw.
  *               if (guard != null) {
  *                   guard.warnIfOpen();
  *               }
@@ -94,12 +96,6 @@
  * in a method, the call to {@code open} should occur just after
  * resource acquisition.
  *
- * <p>
- *
- * Note that the null check on {@code guard} in the finalizer is to
- * cover cases where a constructor throws an exception causing the
- * {@code guard} to be uninitialized.
- *
  * @hide
  */
 public final class CloseGuard {
diff --git a/luni/src/main/java/android/system/Os.java b/luni/src/main/java/android/system/Os.java
index ee683d2..fcecf18 100644
--- a/luni/src/main/java/android/system/Os.java
+++ b/luni/src/main/java/android/system/Os.java
@@ -410,6 +410,11 @@
   public static int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { return Libcore.os.sendto(fd, bytes, byteOffset, byteCount, flags, inetAddress, port); }
 
   /**
+   * See <a href="http://man7.org/linux/man-pages/man2/sendto.2.html">sendto(2)</a>.
+   */
+  /** @hide */ public static int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, SocketAddress address) throws ErrnoException, SocketException { return Libcore.os.sendto(fd, bytes, byteOffset, byteCount, flags, address); }
+
+  /**
    * See <a href="http://man7.org/linux/man-pages/man2/setegid.2.html">setegid(2)</a>.
    */
   public static void setegid(int egid) throws ErrnoException { Libcore.os.setegid(egid); }
diff --git a/luni/src/main/java/java/io/BufferedInputStream.java b/luni/src/main/java/java/io/BufferedInputStream.java
index 85236b6..ec43720 100644
--- a/luni/src/main/java/java/io/BufferedInputStream.java
+++ b/luni/src/main/java/java/io/BufferedInputStream.java
@@ -150,7 +150,7 @@
             if (result > 0) {
                 markpos = -1;
                 pos = 0;
-                count = result == -1 ? 0 : result;
+                count = result;
             }
             return result;
         }
diff --git a/luni/src/main/java/java/security/Signature.java b/luni/src/main/java/java/security/Signature.java
index a39d59b..b720b41 100644
--- a/luni/src/main/java/java/security/Signature.java
+++ b/luni/src/main/java/java/security/Signature.java
@@ -193,7 +193,7 @@
             if (service == null) {
                 return null;
             }
-            return tryAlgorithmWithProvider(key, service);
+            return tryAlgorithmWithProvider(null, service);
         }
         ArrayList<Provider.Service> services = ENGINE.getServices(algorithm);
         if (services == null) {
diff --git a/luni/src/main/java/javax/crypto/Cipher.java b/luni/src/main/java/javax/crypto/Cipher.java
index 889ac9f..a6df1e6 100644
--- a/luni/src/main/java/javax/crypto/Cipher.java
+++ b/luni/src/main/java/javax/crypto/Cipher.java
@@ -419,7 +419,7 @@
             if (service == null) {
                 return null;
             }
-            return tryTransformWithProvider(key, transformParts, type, service);
+            return tryTransformWithProvider(null, transformParts, type, service);
         }
         ArrayList<Provider.Service> services = ENGINE.getServices(transform);
         if (services == null) {
diff --git a/luni/src/main/java/javax/crypto/KeyAgreement.java b/luni/src/main/java/javax/crypto/KeyAgreement.java
index abcfd0e..53ce136 100644
--- a/luni/src/main/java/javax/crypto/KeyAgreement.java
+++ b/luni/src/main/java/javax/crypto/KeyAgreement.java
@@ -195,7 +195,7 @@
             if (service == null) {
                 return null;
             }
-            return tryAlgorithmWithProvider(key, service);
+            return tryAlgorithmWithProvider(null, service);
         }
         ArrayList<Provider.Service> services = ENGINE.getServices(algorithm);
         if (services == null) {
diff --git a/luni/src/main/java/javax/crypto/Mac.java b/luni/src/main/java/javax/crypto/Mac.java
index 5a73dc5..3166032 100644
--- a/luni/src/main/java/javax/crypto/Mac.java
+++ b/luni/src/main/java/javax/crypto/Mac.java
@@ -199,7 +199,7 @@
             if (service == null) {
                 return null;
             }
-            return tryAlgorithmWithProvider(key, service);
+            return tryAlgorithmWithProvider(null, service);
         }
         ArrayList<Provider.Service> services = ENGINE.getServices(algorithm);
         if (services == null) {
diff --git a/luni/src/main/java/javax/xml/datatype/FactoryFinder.java b/luni/src/main/java/javax/xml/datatype/FactoryFinder.java
index b65f412..1fbca2f 100644
--- a/luni/src/main/java/javax/xml/datatype/FactoryFinder.java
+++ b/luni/src/main/java/javax/xml/datatype/FactoryFinder.java
@@ -47,11 +47,30 @@
     /** <p>Debug flag to trace loading process.</p> */
     private static boolean debug = false;
 
-    /** <p>Cache properties for performance.</p> */
-    private static Properties cacheProps = new Properties();
+    /**
+     * <p>Cache properties for performance. Use a static class to avoid double-checked
+     * locking.</p>
+     */
+    private static class CacheHolder {
 
-    /** <p>First time requires initialization overhead.</p> */
-    private static boolean firstTime = true;
+        private static Properties cacheProps = new Properties();
+
+        static {
+            String javah = System.getProperty("java.home");
+            String configFile = javah + File.separator + "lib" + File.separator + "jaxp.properties";
+            File f = new File(configFile);
+            if (f.exists()) {
+                if (debug) debugPrintln("Read properties file " + f);
+                try {
+                    cacheProps.load(new FileInputStream(f));
+                } catch (Exception ex) {
+                    if (debug) {
+                        ex.printStackTrace();
+                    }
+                }
+            }
+        }
+    }
 
     /** Default columns per line. */
     private static final int DEFAULT_LINE_LENGTH = 80;
@@ -177,22 +196,7 @@
 
         // try to read from $java.home/lib/jaxp.properties
         try {
-            String javah = System.getProperty("java.home");
-            String configFile = javah + File.separator + "lib" + File.separator + "jaxp.properties";
-            String factoryClassName = null;
-            if (firstTime) {
-                synchronized (cacheProps) {
-                    if (firstTime) {
-                        File f = new File(configFile);
-                        firstTime = false;
-                        if (f.exists()) {
-                            if (debug) debugPrintln("Read properties file " + f);
-                            cacheProps.load(new FileInputStream(f));
-                        }
-                    }
-                }
-            }
-            factoryClassName = cacheProps.getProperty(factoryId);
+            String factoryClassName = CacheHolder.cacheProps.getProperty(factoryId);
             if (debug) debugPrintln("found " + factoryClassName + " in $java.home/jaxp.properties");
 
             if (factoryClassName != null) {
diff --git a/luni/src/main/java/javax/xml/validation/SchemaFactoryFinder.java b/luni/src/main/java/javax/xml/validation/SchemaFactoryFinder.java
index 636777c..0060612 100644
--- a/luni/src/main/java/javax/xml/validation/SchemaFactoryFinder.java
+++ b/luni/src/main/java/javax/xml/validation/SchemaFactoryFinder.java
@@ -49,14 +49,29 @@
     private static boolean debug = false;
 
     /**
-     * <p>Cache properties for performance.</p>
+     * <p>Cache properties for performance. Use a static class to avoid double-checked
+     * locking.</p>
      */
-    private static Properties cacheProps = new Properties();
+    private static class CacheHolder {
 
-    /**
-     * <p>First time requires initialization overhead.</p>
-     */
-    private static boolean firstTime = true;
+        private static Properties cacheProps = new Properties();
+
+        static {
+            String javah = System.getProperty("java.home");
+            String configFile = javah + File.separator + "lib" + File.separator + "jaxp.properties";
+            File f = new File(configFile);
+            if (f.exists()) {
+                if (debug) debugPrintln("Read properties file " + f);
+                try {
+                    cacheProps.load(new FileInputStream(f));
+                } catch (Exception ex) {
+                    if (debug) {
+                        ex.printStackTrace();
+                    }
+                }
+            }
+        }
+    }
 
     /**
      * Default columns per line.
@@ -184,27 +199,9 @@
             }
         }
 
-        String javah = System.getProperty("java.home");
-        String configFile = javah + File.separator +
-        "lib" + File.separator + "jaxp.properties";
-
-        String factoryClassName = null ;
-
         // try to read from $java.home/lib/jaxp.properties
         try {
-            if(firstTime){
-                synchronized(cacheProps){
-                    if(firstTime){
-                        File f=new File( configFile );
-                        firstTime = false;
-                        if(f.exists()){
-                            if (debug) debugPrintln("Read properties file " + f);
-                            cacheProps.load(new FileInputStream(f));
-                        }
-                    }
-                }
-            }
-            factoryClassName = cacheProps.getProperty(propertyName);
+            String factoryClassName = CacheHolder.cacheProps.getProperty(propertyName);
             if (debug) debugPrintln("found " + factoryClassName + " in $java.home/jaxp.properties");
 
             if (factoryClassName != null) {
diff --git a/luni/src/main/java/javax/xml/xpath/XPathFactoryFinder.java b/luni/src/main/java/javax/xml/xpath/XPathFactoryFinder.java
index 0113e7d..5a7663c 100644
--- a/luni/src/main/java/javax/xml/xpath/XPathFactoryFinder.java
+++ b/luni/src/main/java/javax/xml/xpath/XPathFactoryFinder.java
@@ -56,14 +56,29 @@
     }
 
     /**
-     * <p>Cache properties for performance.</p>
+     * <p>Cache properties for performance. Use a static class to avoid double-checked
+     * locking.</p>
      */
-    private static Properties cacheProps = new Properties();
+    private static class CacheHolder {
 
-    /**
-     * <p>First time requires initialization overhead.</p>
-     */
-    private static boolean firstTime = true;
+        private static Properties cacheProps = new Properties();
+
+        static {
+            String javah = System.getProperty("java.home");
+            String configFile = javah + File.separator + "lib" + File.separator + "jaxp.properties";
+            File f = new File(configFile);
+            if (f.exists()) {
+                if (debug) debugPrintln("Read properties file " + f);
+                try {
+                    cacheProps.load(new FileInputStream(f));
+                } catch (Exception ex) {
+                    if (debug) {
+                        ex.printStackTrace();
+                    }
+                }
+            }
+        }
+    }
 
     /**
      * <p>Conditional debug printing.</p>
@@ -164,27 +179,9 @@
             e.printStackTrace();
         }
 
-        String javah = System.getProperty("java.home");
-        String configFile = javah + File.separator +
-        "lib" + File.separator + "jaxp.properties";
-
-        String factoryClassName = null ;
-
         // try to read from $java.home/lib/jaxp.properties
         try {
-            if(firstTime){
-                synchronized(cacheProps){
-                    if(firstTime){
-                        File f=new File( configFile );
-                        firstTime = false;
-                        if (f.exists()) {
-                            if (debug) debugPrintln("Read properties file " + f);
-                            cacheProps.load(new FileInputStream(f));
-                        }
-                    }
-                }
-            }
-            factoryClassName = cacheProps.getProperty(propertyName);
+            String factoryClassName = CacheHolder.cacheProps.getProperty(propertyName);
             if (debug) debugPrintln("found " + factoryClassName + " in $java.home/jaxp.properties");
 
             if (factoryClassName != null) {
diff --git a/luni/src/main/java/org/apache/harmony/security/utils/WrappedX509Certificate.java b/luni/src/main/java/org/apache/harmony/security/utils/WrappedX509Certificate.java
index 2b09309..1c07915 100644
--- a/luni/src/main/java/org/apache/harmony/security/utils/WrappedX509Certificate.java
+++ b/luni/src/main/java/org/apache/harmony/security/utils/WrappedX509Certificate.java
@@ -160,7 +160,7 @@
     public void verify(PublicKey key, String sigProvider) throws CertificateException,
             NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,
             SignatureException {
-        verify(key, sigProvider);
+        wrapped.verify(key, sigProvider);
     }
 
     @Override
diff --git a/luni/src/main/native/java_lang_StringToReal.cpp b/luni/src/main/native/java_lang_StringToReal.cpp
old mode 100755
new mode 100644
diff --git a/luni/src/test/java/libcore/icu/RelativeDateTimeFormatterTest.java b/luni/src/test/java/libcore/icu/RelativeDateTimeFormatterTest.java
index 07166bf..9a79429 100644
--- a/luni/src/test/java/libcore/icu/RelativeDateTimeFormatterTest.java
+++ b/luni/src/test/java/libcore/icu/RelativeDateTimeFormatterTest.java
@@ -344,65 +344,63 @@
   }
 
   public void test_getRelativeTimeSpanStringGerman() throws Exception {
+    // Bug: 19744876
+    // We need to specify the timezone and the time explicitly. Otherwise it
+    // may not always give a correct answer of "tomorrow" by using
+    // (now + DAY_IN_MILLIS).
     Locale de_DE = new Locale("de", "DE");
-    final long now = System.currentTimeMillis();
-    TimeZone tz = TimeZone.getDefault();
+    TimeZone tz = TimeZone.getTimeZone("Europe/Berlin");
+    Calendar cal = Calendar.getInstance(tz, de_DE);
+    // Feb 5, 2015 at 10:50 CET
+    cal.set(2015, Calendar.FEBRUARY, 5, 10, 50, 0);
+    final long now = cal.getTimeInMillis();
 
     // 42 minutes ago
-    assertEquals("vor 42 Minuten",
-      getRelativeTimeSpanString(de_DE, tz, now - 42 * MINUTE_IN_MILLIS, now,
-                                MINUTE_IN_MILLIS, 0));
+    assertEquals("vor 42 Minuten", getRelativeTimeSpanString(de_DE, tz,
+        now - 42 * MINUTE_IN_MILLIS, now, MINUTE_IN_MILLIS, 0));
     // in 42 minutes
-    assertEquals("in 42 Minuten",
-      getRelativeTimeSpanString(de_DE, tz, now + 42 * MINUTE_IN_MILLIS, now,
-                                MINUTE_IN_MILLIS, 0));
+    assertEquals("in 42 Minuten", getRelativeTimeSpanString(de_DE, tz,
+        now + 42 * MINUTE_IN_MILLIS, now, MINUTE_IN_MILLIS, 0));
     // yesterday
-    assertEquals("Gestern",
-                 getRelativeTimeSpanString(de_DE, tz, now - DAY_IN_MILLIS, now,
-                                           DAY_IN_MILLIS, 0));
+    assertEquals("Gestern", getRelativeTimeSpanString(de_DE, tz,
+        now - DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
     // the day before yesterday
-    assertEquals("Vorgestern",
-                 getRelativeTimeSpanString(de_DE, tz, now - 2 * DAY_IN_MILLIS, now,
-                                           DAY_IN_MILLIS, 0));
+    assertEquals("Vorgestern", getRelativeTimeSpanString(de_DE, tz,
+        now - 2 * DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
     // tomorrow
-    assertEquals("Morgen",
-                 getRelativeTimeSpanString(de_DE, tz, now + DAY_IN_MILLIS, now,
-                                           DAY_IN_MILLIS, 0));
+    assertEquals("Morgen", getRelativeTimeSpanString(de_DE, tz,
+        now + DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
     // the day after tomorrow
-    assertEquals("Übermorgen",
-                 getRelativeTimeSpanString(de_DE, tz, now + 2 * DAY_IN_MILLIS, now,
-                                           DAY_IN_MILLIS, 0));
+    assertEquals("Übermorgen", getRelativeTimeSpanString(de_DE, tz,
+        now + 2 * DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
   }
 
   public void test_getRelativeTimeSpanStringFrench() throws Exception {
     Locale fr_FR = new Locale("fr", "FR");
-    final long now = System.currentTimeMillis();
-    TimeZone tz = TimeZone.getDefault();
+    TimeZone tz = TimeZone.getTimeZone("Europe/Paris");
+    Calendar cal = Calendar.getInstance(tz, fr_FR);
+    // Feb 5, 2015 at 10:50 CET
+    cal.set(2015, Calendar.FEBRUARY, 5, 10, 50, 0);
+    final long now = cal.getTimeInMillis();
 
     // 42 minutes ago
-    assertEquals("il y a 42 minutes",
-                 getRelativeTimeSpanString(fr_FR, tz, now - (42 * MINUTE_IN_MILLIS), now,
-                                           MINUTE_IN_MILLIS, 0));
+    assertEquals("il y a 42 minutes", getRelativeTimeSpanString(fr_FR, tz,
+        now - (42 * MINUTE_IN_MILLIS), now, MINUTE_IN_MILLIS, 0));
     // in 42 minutes
-    assertEquals("dans 42 minutes",
-                 getRelativeTimeSpanString(fr_FR, tz, now + (42 * MINUTE_IN_MILLIS), now,
-                                           MINUTE_IN_MILLIS, 0));
+    assertEquals("dans 42 minutes", getRelativeTimeSpanString(fr_FR, tz,
+        now + (42 * MINUTE_IN_MILLIS), now, MINUTE_IN_MILLIS, 0));
     // yesterday
-    assertEquals("Hier",
-                 getRelativeTimeSpanString(fr_FR, tz, now - DAY_IN_MILLIS, now,
-                                           DAY_IN_MILLIS, 0));
+    assertEquals("Hier", getRelativeTimeSpanString(fr_FR, tz,
+        now - DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
     // the day before yesterday
-    assertEquals("Avant-hier",
-                 getRelativeTimeSpanString(fr_FR, tz, now - 2 * DAY_IN_MILLIS, now,
-                                           DAY_IN_MILLIS, 0));
+    assertEquals("Avant-hier", getRelativeTimeSpanString(fr_FR, tz,
+        now - 2 * DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
     // tomorrow
-    assertEquals("Demain",
-                 getRelativeTimeSpanString(fr_FR, tz, now + DAY_IN_MILLIS, now,
-                                           DAY_IN_MILLIS, 0));
+    assertEquals("Demain", getRelativeTimeSpanString(fr_FR, tz,
+        now + DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
     // the day after tomorrow
-    assertEquals("Après-demain",
-                 getRelativeTimeSpanString(fr_FR, tz, now + 2 * DAY_IN_MILLIS, now,
-                                           DAY_IN_MILLIS, 0));
+    assertEquals("Après-demain", getRelativeTimeSpanString(fr_FR, tz,
+        now + 2 * DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
   }
 
   // Tests adopted from CTS tests for DateUtils.getRelativeDateTimeString.
diff --git a/luni/src/test/java/libcore/java/security/ProviderTest.java b/luni/src/test/java/libcore/java/security/ProviderTest.java
index 994214b..0be558e 100644
--- a/luni/src/test/java/libcore/java/security/ProviderTest.java
+++ b/luni/src/test/java/libcore/java/security/ProviderTest.java
@@ -160,7 +160,7 @@
     public void test_Provider_Properties() throws Exception {
         /*
          * A useful reference on Provider properties
-         * <a href="http://java.sun.com/javase/6/docs/technotes/guides/security/crypto/HowToImplAProvider.html>
+         * <a href="http://java.sun.com/javase/6/docs/technotes/guides/security/crypto/HowToImplAProvider.html">
          * How to Implement a Provider in the Java &trade; Cryptography Architecture
          * </a>
          */
diff --git a/luni/src/test/java/libcore/java/security/SignatureTest.java b/luni/src/test/java/libcore/java/security/SignatureTest.java
index 5e02f10..e546f4f 100644
--- a/luni/src/test/java/libcore/java/security/SignatureTest.java
+++ b/luni/src/test/java/libcore/java/security/SignatureTest.java
@@ -71,6 +71,24 @@
         }
     }
 
+    public void testSignature_getInstance_DoesNotSupportKeyClass_Success() throws Exception {
+        Provider mockProvider = new MockProvider("MockProvider") {
+            public void setup() {
+                put("Signature.FOO", MockSignatureSpi.AllKeyTypes.class.getName());
+                put("Signature.FOO SupportedKeyClasses", "None");
+            }
+        };
+
+        Security.addProvider(mockProvider);
+        try {
+            Signature s = Signature.getInstance("FOO", mockProvider);
+            s.initSign(new MockPrivateKey());
+            assertEquals(mockProvider, s.getProvider());
+        } finally {
+            Security.removeProvider(mockProvider.getName());
+        }
+    }
+
     public void testSignature_getInstance_OnlyUsesSpecifiedProvider_SameNameAndClass_Success()
             throws Exception {
         Provider mockProvider = new MockProvider("MockProvider") {
diff --git a/luni/src/test/java/libcore/java/sql/TimestampTest.java b/luni/src/test/java/libcore/java/sql/TimestampTest.java
index 2985848..71ac8c8 100644
--- a/luni/src/test/java/libcore/java/sql/TimestampTest.java
+++ b/luni/src/test/java/libcore/java/sql/TimestampTest.java
@@ -144,4 +144,12 @@
     } catch (IllegalArgumentException expected) { }
   }
 
+  // http://b/19756610
+  public void testAsymmetricEquals() {
+    Timestamp timestamp = new Timestamp(0);
+    java.util.Date date = new java.util.Date(0);
+
+    assertTrue(date.equals(timestamp));
+    assertFalse(timestamp.equals(date));
+  }
 }
diff --git a/luni/src/test/java/libcore/javax/crypto/CipherTest.java b/luni/src/test/java/libcore/javax/crypto/CipherTest.java
index 29112fb..cd070ab 100644
--- a/luni/src/test/java/libcore/javax/crypto/CipherTest.java
+++ b/luni/src/test/java/libcore/javax/crypto/CipherTest.java
@@ -847,6 +847,24 @@
         }
     }
 
+    public void testCipher_getInstance_DoesNotSupportKeyClass_Success() throws Exception {
+        Provider mockProvider = new MockProvider("MockProvider") {
+            public void setup() {
+                put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName());
+                put("Cipher.FOO SupportedKeyClasses", "None");
+            }
+        };
+
+        Security.addProvider(mockProvider);
+        try {
+            Cipher c = Cipher.getInstance("FOO", mockProvider);
+            c.init(Cipher.ENCRYPT_MODE, new MockKey());
+            assertEquals(mockProvider, c.getProvider());
+        } finally {
+            Security.removeProvider(mockProvider.getName());
+        }
+    }
+
     public void testCipher_getInstance_SuppliedProviderNotRegistered_MultipartTransform_Success()
             throws Exception {
         Provider mockProvider = new MockProvider("MockProvider") {
diff --git a/luni/src/test/java/libcore/javax/crypto/KeyAgreementTest.java b/luni/src/test/java/libcore/javax/crypto/KeyAgreementTest.java
new file mode 100644
index 0000000..ba03f75
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/crypto/KeyAgreementTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 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.javax.crypto;
+
+import java.security.Provider;
+import java.security.Security;
+
+import javax.crypto.KeyAgreement;
+
+import junit.framework.TestCase;
+
+public class KeyAgreementTest extends TestCase {
+    private static abstract class MockProvider extends Provider {
+        public MockProvider(String name) {
+            super(name, 1.0, "Mock provider used for testing");
+            setup();
+        }
+
+        public abstract void setup();
+    }
+
+    public void testKeyAgreement_getInstance_SuppliedProviderNotRegistered_Success()
+            throws Exception {
+        Provider mockProvider = new MockProvider("MockProvider") {
+            public void setup() {
+                put("KeyAgreement.FOO", MockKeyAgreementSpi.AllKeyTypes.class.getName());
+            }
+        };
+
+        {
+            KeyAgreement c = KeyAgreement.getInstance("FOO", mockProvider);
+            c.init(new MockKey());
+            assertEquals(mockProvider, c.getProvider());
+        }
+    }
+
+    public void testKeyAgreement_getInstance_DoesNotSupportKeyClass_Success()
+            throws Exception {
+        Provider mockProvider = new MockProvider("MockProvider") {
+            public void setup() {
+                put("KeyAgreement.FOO", MockKeyAgreementSpi.AllKeyTypes.class.getName());
+                put("KeyAgreement.FOO SupportedKeyClasses", "none");
+
+            }
+        };
+
+        Security.addProvider(mockProvider);
+        try {
+            KeyAgreement c = KeyAgreement.getInstance("FOO", mockProvider);
+            c.init(new MockKey());
+            assertEquals(mockProvider, c.getProvider());
+        } finally {
+            Security.removeProvider(mockProvider.getName());
+        }
+    }
+}
diff --git a/luni/src/test/java/libcore/javax/crypto/MockKeyAgreementSpi.java b/luni/src/test/java/libcore/javax/crypto/MockKeyAgreementSpi.java
new file mode 100644
index 0000000..574dbeb
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/crypto/MockKeyAgreementSpi.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 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.javax.crypto;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import javax.crypto.KeyAgreementSpi;
+import javax.crypto.SecretKey;
+import javax.crypto.ShortBufferException;
+
+/**
+ * Mock KeyAgreementSpi used by {@link KeyAgreementTest}.
+ */
+public class MockKeyAgreementSpi extends KeyAgreementSpi {
+    public static class SpecificKeyTypes extends MockKeyAgreementSpi {
+        @Override
+        public void checkKeyType(Key key) throws InvalidKeyException {
+            if (!(key instanceof MockKey)) {
+                throw new InvalidKeyException("Must be MockKey!");
+            }
+        }
+    }
+
+    public static class SpecificKeyTypes2 extends MockKeyAgreementSpi {
+        @Override
+        public void checkKeyType(Key key) throws InvalidKeyException {
+            System.err.println("Checking key of type " + key.getClass().getName());
+            if (!(key instanceof MockKey2)) {
+                throw new InvalidKeyException("Must be MockKey2!");
+            }
+        }
+    }
+
+    public static class AllKeyTypes extends MockKeyAgreementSpi {
+    }
+
+    public void checkKeyType(Key key) throws InvalidKeyException {
+    }
+
+    @Override
+    protected Key engineDoPhase(Key key, boolean lastPhase) throws InvalidKeyException,
+            IllegalStateException {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    protected byte[] engineGenerateSecret() throws IllegalStateException {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    protected int engineGenerateSecret(byte[] sharedSecret, int offset)
+            throws IllegalStateException, ShortBufferException {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    protected SecretKey engineGenerateSecret(String algorithm) throws IllegalStateException,
+            NoSuchAlgorithmException, InvalidKeyException {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    protected void engineInit(Key key, SecureRandom random) throws InvalidKeyException {
+        checkKeyType(key);
+    }
+
+    @Override
+    protected void engineInit(Key key, AlgorithmParameterSpec params, SecureRandom random)
+            throws InvalidKeyException, InvalidAlgorithmParameterException {
+        checkKeyType(key);
+    }
+}
diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java
index ddd0695..9b7dc18 100644
--- a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java
+++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java
@@ -884,6 +884,24 @@
         public abstract void setup();
     }
 
+    public void testMac_getInstance_DoesNotSupportKeyClass_Success() throws Exception {
+        Provider mockProvider = new MockProvider("MockProvider") {
+            public void setup() {
+                put("Mac.FOO", MockMacSpi.AllKeyTypes.class.getName());
+                put("Mac.FOO SupportedKeyClasses", "None");
+            }
+        };
+
+        Security.addProvider(mockProvider);
+        try {
+            Mac s = Mac.getInstance("FOO", mockProvider);
+            s.init(new MockKey());
+            assertEquals(mockProvider, s.getProvider());
+        } finally {
+            Security.removeProvider(mockProvider.getName());
+        }
+    }
+
     public void testMac_getInstance_SuppliedProviderNotRegistered_Success() throws Exception {
         Provider mockProvider = new MockProvider("MockProvider") {
             public void setup() {
diff --git a/support/src/test/java/libcore/java/security/StandardNames.java b/support/src/test/java/libcore/java/security/StandardNames.java
index 5f5bafd..a55b47a 100644
--- a/support/src/test/java/libcore/java/security/StandardNames.java
+++ b/support/src/test/java/libcore/java/security/StandardNames.java
@@ -801,7 +801,7 @@
         addBoth(   "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA");
         addBoth(   "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA");
 
-        // Android does not have Keberos support
+        // Android does not have Kerberos support
         addRi(     "TLS_KRB5_WITH_RC4_128_SHA");
         addRi(     "TLS_KRB5_WITH_RC4_128_MD5");
         addRi(     "TLS_KRB5_WITH_3DES_EDE_CBC_SHA");