Merge "Late binding: add tests for init-time rejection"
diff --git a/libart/src/main/java/java/lang/Class.java b/libart/src/main/java/java/lang/Class.java
index 5736efb..60052b8 100644
--- a/libart/src/main/java/java/lang/Class.java
+++ b/libart/src/main/java/java/lang/Class.java
@@ -583,7 +583,7 @@
      *            {@code (Class[]) null} is equivalent to the empty array.
      * @return the method described by {@code name} and {@code parameterTypes}.
      * @throws NoSuchMethodException
-     *             if the requested constructor cannot be found.
+     *             if the requested method cannot be found.
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
      * @see #getMethod(String, Class[])
diff --git a/luni/src/main/java/android/system/OsConstants.java b/luni/src/main/java/android/system/OsConstants.java
index b3ad5b6..f0d77de 100644
--- a/luni/src/main/java/android/system/OsConstants.java
+++ b/luni/src/main/java/android/system/OsConstants.java
@@ -350,6 +350,7 @@
     public static final int O_RDONLY = placeholder();
     public static final int O_RDWR = placeholder();
     public static final int O_SYNC = placeholder();
+    /** @hide */ public static final int O_DSYNC = placeholder();
     public static final int O_TRUNC = placeholder();
     public static final int O_WRONLY = placeholder();
     public static final int POLLERR = placeholder();
diff --git a/luni/src/main/java/java/io/RandomAccessFile.java b/luni/src/main/java/java/io/RandomAccessFile.java
index 0e4fa4f..42c30c4 100644
--- a/luni/src/main/java/java/io/RandomAccessFile.java
+++ b/luni/src/main/java/java/io/RandomAccessFile.java
@@ -44,8 +44,6 @@
      */
     private FileDescriptor fd;
 
-    private boolean syncMetadata = false;
-
     // The unique file channel associated with this FileInputStream (lazily
     // initialized).
     private FileChannel channel;
@@ -104,11 +102,11 @@
         } else if (mode.equals("rw") || mode.equals("rws") || mode.equals("rwd")) {
             flags = O_RDWR | O_CREAT;
             if (mode.equals("rws")) {
-                // Sync file and metadata with every write
-                syncMetadata = true;
-            } else if (mode.equals("rwd")) {
-                // Sync file, but not necessarily metadata
+                // Sync data and metadata with every write
                 flags |= O_SYNC;
+            } else if (mode.equals("rwd")) {
+                // Sync data, but not necessarily metadata
+                flags |= O_DSYNC;
             }
         } else {
             throw new IllegalArgumentException("Invalid mode: " + mode);
@@ -116,14 +114,6 @@
         this.mode = flags;
         this.fd = IoBridge.open(file.getPath(), flags);
 
-        // if we are in "rws" mode, attempt to sync file+metadata
-        if (syncMetadata) {
-            try {
-                fd.sync();
-            } catch (IOException e) {
-                // Ignored
-            }
-        }
         guard.open("close");
     }
 
@@ -635,10 +625,6 @@
             seek(newLength);
         }
 
-        // if we are in "rws" mode, attempt to sync file+metadata
-        if (syncMetadata) {
-            fd.sync();
-        }
     }
 
     /**
@@ -689,10 +675,6 @@
      */
     public void write(byte[] buffer, int byteOffset, int byteCount) throws IOException {
         IoBridge.write(fd, buffer, byteOffset, byteCount);
-        // if we are in "rws" mode, attempt to sync file+metadata
-        if (syncMetadata) {
-            fd.sync();
-        }
     }
 
     /**
diff --git a/luni/src/main/java/java/security/Signature.java b/luni/src/main/java/java/security/Signature.java
index b11abaa..7a21a46 100644
--- a/luni/src/main/java/java/security/Signature.java
+++ b/luni/src/main/java/java/security/Signature.java
@@ -687,16 +687,32 @@
         }
 
         @Override
+        protected int engineSign(byte[] outbuf, int offset, int len) throws SignatureException {
+            return getSpi().engineSign(outbuf, offset, len);
+        }
+
+        @Override
         protected void engineUpdate(byte arg0) throws SignatureException {
             getSpi().engineUpdate(arg0);
         }
 
         @Override
+        protected void engineUpdate(ByteBuffer input) {
+            getSpi().engineUpdate(input);
+        }
+
+        @Override
         protected boolean engineVerify(byte[] arg0) throws SignatureException {
             return getSpi().engineVerify(arg0);
         }
 
         @Override
+        protected boolean engineVerify(byte[] sigBytes, int offset, int length)
+                throws SignatureException {
+            return getSpi().engineVerify(sigBytes, offset, length);
+        }
+
+        @Override
         protected void engineUpdate(byte[] arg0, int arg1, int arg2) throws SignatureException {
             getSpi().engineUpdate(arg0, arg1, arg2);
         }
@@ -707,6 +723,12 @@
         }
 
         @Override
+        protected void engineInitSign(PrivateKey arg0, SecureRandom arg1)
+                throws InvalidKeyException {
+            getSpi(arg0).engineInitSign(arg0, arg1);
+        }
+
+        @Override
         protected void engineInitVerify(PublicKey arg0) throws InvalidKeyException {
             getSpi(arg0).engineInitVerify(arg0);
         }
@@ -717,6 +739,11 @@
         }
 
         @Override
+        protected AlgorithmParameters engineGetParameters() {
+            return getSpi().engineGetParameters();
+        }
+
+        @Override
         protected void engineSetParameter(String arg0, Object arg1)
                 throws InvalidParameterException {
             getSpi().engineSetParameter(arg0, arg1);
diff --git a/luni/src/main/java/java/text/Normalizer.java b/luni/src/main/java/java/text/Normalizer.java
index 2e6647e..5355014 100644
--- a/luni/src/main/java/java/text/Normalizer.java
+++ b/luni/src/main/java/java/text/Normalizer.java
@@ -16,8 +16,6 @@
 
 package java.text;
 
-import libcore.icu.NativeNormalizer;
-
 /**
  * Provides normalization functions according to
  * <a href="http://www.unicode.org/unicode/reports/tr15/tr15-23.html">Unicode Standard Annex #15:
@@ -36,22 +34,32 @@
         /**
          * Normalization Form D - Canonical Decomposition.
          */
-        NFD,
+        NFD(com.ibm.icu.text.Normalizer.NFD),
 
         /**
          * Normalization Form C - Canonical Decomposition, followed by Canonical Composition.
          */
-        NFC,
+        NFC(com.ibm.icu.text.Normalizer.NFC),
 
         /**
          * Normalization Form KD - Compatibility Decomposition.
          */
-        NFKD,
+        NFKD(com.ibm.icu.text.Normalizer.NFKD),
 
         /**
          * Normalization Form KC - Compatibility Decomposition, followed by Canonical Composition.
          */
-        NFKC;
+        NFKC(com.ibm.icu.text.Normalizer.NFKC);
+
+        private final com.ibm.icu.text.Normalizer.Mode icuForm;
+
+        Form(com.ibm.icu.text.Normalizer.Mode icuForm) {
+            this.icuForm = icuForm;
+        }
+
+        com.ibm.icu.text.Normalizer.Mode getIcuForm() {
+            return icuForm;
+        }
     }
 
     /**
@@ -63,7 +71,7 @@
      * @return true if normalized according to <code>form</code>
      */
     public static boolean isNormalized(CharSequence src, Form form) {
-        return NativeNormalizer.isNormalized(src, form);
+        return com.ibm.icu.text.Normalizer.isNormalized(src.toString(), form.getIcuForm(), 0);
     }
 
     /**
@@ -75,7 +83,7 @@
      * @return string normalized according to <code>form</code>
      */
     public static String normalize(CharSequence src, Form form) {
-        return NativeNormalizer.normalize(src, form);
+        return com.ibm.icu.text.Normalizer.normalize(src.toString(), form.getIcuForm());
     }
 
     private Normalizer() {}
diff --git a/luni/src/main/java/libcore/icu/NativeNormalizer.java b/luni/src/main/java/libcore/icu/NativeNormalizer.java
deleted file mode 100644
index a5d8da2..0000000
--- a/luni/src/main/java/libcore/icu/NativeNormalizer.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2010 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.icu;
-
-import java.text.Normalizer.Form;
-
-public final class NativeNormalizer {
-    public static boolean isNormalized(CharSequence src, Form form) {
-        return isNormalizedImpl(src.toString(), toUNormalizationMode(form));
-    }
-
-    public static String normalize(CharSequence src, Form form) {
-        return normalizeImpl(src.toString(), toUNormalizationMode(form));
-    }
-
-    private static int toUNormalizationMode(Form form) {
-        // Translates Java enum constants to ICU int constants.
-        // See UNormalizationMode in "unicode/unorm.h". Stable API since ICU 2.0.
-        switch (form) {
-        case NFC: return 4;
-        case NFD: return 2;
-        case NFKC: return 5;
-        case NFKD: return 3;
-        }
-        throw new AssertionError("unknown Normalizer.Form " + form);
-    }
-
-    private static native String normalizeImpl(String src, int form);
-
-    private static native boolean isNormalizedImpl(String src, int form);
-
-    private NativeNormalizer() {}
-}
diff --git a/luni/src/main/java/libcore/icu/NativePluralRules.java b/luni/src/main/java/libcore/icu/NativePluralRules.java
deleted file mode 100644
index f9fe74b..0000000
--- a/luni/src/main/java/libcore/icu/NativePluralRules.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2010 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.icu;
-
-import java.util.Locale;
-
-/**
- * Provides access to ICU's
- * <a href="http://icu-project.org/apiref/icu4c/classPluralRules.html">PluralRules</a> class.
- * This is not necessary for Java API, but is used by frameworks/base's resources system to
- * ease localization of strings to languages with complex grammatical rules regarding number.
- */
-public final class NativePluralRules {
-    public static final int ZERO  = 0;
-    public static final int ONE   = 1;
-    public static final int TWO   = 2;
-    public static final int FEW   = 3;
-    public static final int MANY  = 4;
-    public static final int OTHER = 5;
-
-    private final long address;
-
-    private NativePluralRules(long address) {
-        this.address = address;
-    }
-
-    @Override protected void finalize() throws Throwable {
-        try {
-            finalizeImpl(address);
-        } finally {
-            super.finalize();
-        }
-    }
-
-    public static NativePluralRules forLocale(Locale locale) {
-        return new NativePluralRules(forLocaleImpl(locale.toString()));
-    }
-
-    /**
-     * Returns the constant defined in this class corresponding
-     * to the first rule that matches the given value.
-     */
-    public int quantityForInt(int value) {
-        // Pre-L compatibility. http://b/18429565.
-        if (value < 0) {
-            return OTHER;
-        }
-        return quantityForIntImpl(address, value);
-    }
-
-    private static native void finalizeImpl(long address);
-    private static native long forLocaleImpl(String localeName);
-    private static native int quantityForIntImpl(long address, int value);
-}
diff --git a/luni/src/main/native/Register.cpp b/luni/src/main/native/Register.cpp
index 787a149..d0230ee 100644
--- a/luni/src/main/native/Register.cpp
+++ b/luni/src/main/native/Register.cpp
@@ -61,8 +61,6 @@
     REGISTER(register_libcore_icu_NativeConverter);
     REGISTER(register_libcore_icu_NativeDecimalFormat);
     REGISTER(register_libcore_icu_NativeIDN);
-    REGISTER(register_libcore_icu_NativeNormalizer);
-    REGISTER(register_libcore_icu_NativePluralRules);
     REGISTER(register_libcore_icu_TimeZoneNames);
     REGISTER(register_libcore_icu_Transliterator);
     REGISTER(register_libcore_io_AsynchronousCloseMonitor);
diff --git a/luni/src/main/native/android_system_OsConstants.cpp b/luni/src/main/native/android_system_OsConstants.cpp
index 3cc9b06..c064130 100644
--- a/luni/src/main/native/android_system_OsConstants.cpp
+++ b/luni/src/main/native/android_system_OsConstants.cpp
@@ -386,6 +386,7 @@
     initConstant(env, c, "O_RDONLY", O_RDONLY);
     initConstant(env, c, "O_RDWR", O_RDWR);
     initConstant(env, c, "O_SYNC", O_SYNC);
+    initConstant(env, c, "O_DSYNC", O_DSYNC);
     initConstant(env, c, "O_TRUNC", O_TRUNC);
     initConstant(env, c, "O_WRONLY", O_WRONLY);
     initConstant(env, c, "POLLERR", POLLERR);
diff --git a/luni/src/main/native/libcore_icu_NativeNormalizer.cpp b/luni/src/main/native/libcore_icu_NativeNormalizer.cpp
deleted file mode 100644
index 2d5e282..0000000
--- a/luni/src/main/native/libcore_icu_NativeNormalizer.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#define LOG_TAG "NativeNormalizer"
-
-#include "IcuUtilities.h"
-#include "JNIHelp.h"
-#include "JniConstants.h"
-#include "JniException.h"
-#include "ScopedJavaUnicodeString.h"
-#include "unicode/normlzr.h"
-
-static jstring NativeNormalizer_normalizeImpl(JNIEnv* env, jclass, jstring s, jint intMode) {
-  ScopedJavaUnicodeString src(env, s);
-  if (!src.valid()) {
-    return NULL;
-  }
-  UNormalizationMode mode = static_cast<UNormalizationMode>(intMode);
-  UErrorCode status = U_ZERO_ERROR;
-  icu::UnicodeString dst;
-  icu::Normalizer::normalize(src.unicodeString(), mode, 0, dst, status);
-  maybeThrowIcuException(env, "Normalizer::normalize", status);
-  return dst.isBogus() ? NULL : env->NewString(dst.getBuffer(), dst.length());
-}
-
-static jboolean NativeNormalizer_isNormalizedImpl(JNIEnv* env, jclass, jstring s, jint intMode) {
-  ScopedJavaUnicodeString src(env, s);
-  if (!src.valid()) {
-    return JNI_FALSE;
-  }
-  UNormalizationMode mode = static_cast<UNormalizationMode>(intMode);
-  UErrorCode status = U_ZERO_ERROR;
-  UBool result = icu::Normalizer::isNormalized(src.unicodeString(), mode, status);
-  maybeThrowIcuException(env, "Normalizer::isNormalized", status);
-  return result;
-}
-
-static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(NativeNormalizer, normalizeImpl, "(Ljava/lang/String;I)Ljava/lang/String;"),
-  NATIVE_METHOD(NativeNormalizer, isNormalizedImpl, "(Ljava/lang/String;I)Z"),
-};
-void register_libcore_icu_NativeNormalizer(JNIEnv* env) {
-  jniRegisterNativeMethods(env, "libcore/icu/NativeNormalizer", gMethods, NELEM(gMethods));
-}
diff --git a/luni/src/main/native/libcore_icu_NativePluralRules.cpp b/luni/src/main/native/libcore_icu_NativePluralRules.cpp
deleted file mode 100644
index f278485..0000000
--- a/luni/src/main/native/libcore_icu_NativePluralRules.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#define LOG_TAG "NativePluralRules"
-
-#include "IcuUtilities.h"
-#include "JNIHelp.h"
-#include "JniConstants.h"
-#include "JniException.h"
-#include "ScopedUtfChars.h"
-#include "unicode/plurrule.h"
-
-#include <string>
-
-static icu::PluralRules* toPluralRules(jlong address) {
-    return reinterpret_cast<icu::PluralRules*>(static_cast<uintptr_t>(address));
-}
-
-static void NativePluralRules_finalizeImpl(JNIEnv*, jclass, jlong address) {
-    delete toPluralRules(address);
-}
-
-static jlong NativePluralRules_forLocaleImpl(JNIEnv* env, jclass, jstring javaLocaleName) {
-    // The icu4c PluralRules returns a "other: n" default rule for the deprecated locales Java uses.
-    // Work around this by translating back to the current language codes.
-    std::string localeName(ScopedUtfChars(env, javaLocaleName).c_str());
-    if (localeName[0] == 'i' && localeName[1] == 'w') {
-        localeName[0] = 'h';
-        localeName[1] = 'e';
-    } else if (localeName[0] == 'i' && localeName[1] == 'n') {
-        localeName[0] = 'i';
-        localeName[1] = 'd';
-    } else if (localeName[0] == 'j' && localeName[1] == 'i') {
-        localeName[0] = 'y';
-        localeName[1] = 'i';
-    }
-
-    icu::Locale locale = icu::Locale::createFromName(localeName.c_str());
-    UErrorCode status = U_ZERO_ERROR;
-    icu::PluralRules* result = icu::PluralRules::forLocale(locale, status);
-    maybeThrowIcuException(env, "PluralRules::forLocale", status);
-    return reinterpret_cast<uintptr_t>(result);
-}
-
-static jint NativePluralRules_quantityForIntImpl(JNIEnv*, jclass, jlong address, jint value) {
-    icu::UnicodeString keyword = toPluralRules(address)->select(value);
-    if (keyword == "zero") {
-        return 0;
-    } else if (keyword == "one") {
-        return 1;
-    } else if (keyword == "two") {
-        return 2;
-    } else if (keyword == "few") {
-        return 3;
-    } else if (keyword == "many") {
-        return 4;
-    } else {
-        return 5;
-    }
-}
-
-static JNINativeMethod gMethods[] = {
-    NATIVE_METHOD(NativePluralRules, finalizeImpl, "(J)V"),
-    NATIVE_METHOD(NativePluralRules, forLocaleImpl, "(Ljava/lang/String;)J"),
-    NATIVE_METHOD(NativePluralRules, quantityForIntImpl, "(JI)I"),
-};
-void register_libcore_icu_NativePluralRules(JNIEnv* env) {
-    jniRegisterNativeMethods(env, "libcore/icu/NativePluralRules", gMethods, NELEM(gMethods));
-}
diff --git a/luni/src/main/native/sub.mk b/luni/src/main/native/sub.mk
index 78ec37a..1906185 100644
--- a/luni/src/main/native/sub.mk
+++ b/luni/src/main/native/sub.mk
@@ -41,8 +41,6 @@
     libcore_icu_NativeConverter.cpp \
     libcore_icu_NativeDecimalFormat.cpp \
     libcore_icu_NativeIDN.cpp \
-    libcore_icu_NativeNormalizer.cpp \
-    libcore_icu_NativePluralRules.cpp \
     libcore_icu_TimeZoneNames.cpp \
     libcore_icu_Transliterator.cpp \
     libcore_io_AsynchronousCloseMonitor.cpp \
diff --git a/luni/src/test/java/libcore/icu/NativePluralRulesTest.java b/luni/src/test/java/libcore/icu/NativePluralRulesTest.java
deleted file mode 100644
index 76179b4..0000000
--- a/luni/src/test/java/libcore/icu/NativePluralRulesTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2009 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.icu;
-
-import java.util.Locale;
-
-public class NativePluralRulesTest extends junit.framework.TestCase {
-    public void testNegatives() throws Exception {
-        // icu4c's behavior changed, but we prefer to preserve compatibility.
-        NativePluralRules en_US = NativePluralRules.forLocale(new Locale("en", "US"));
-        assertEquals(NativePluralRules.OTHER, en_US.quantityForInt(2));
-        assertEquals(NativePluralRules.ONE, en_US.quantityForInt(1));
-        assertEquals(NativePluralRules.OTHER, en_US.quantityForInt(0));
-        assertEquals(NativePluralRules.OTHER, en_US.quantityForInt(-1));
-        assertEquals(NativePluralRules.OTHER, en_US.quantityForInt(-2));
-
-        NativePluralRules ar = NativePluralRules.forLocale(new Locale("ar"));
-        assertEquals(NativePluralRules.ZERO, ar.quantityForInt(0));
-        assertEquals(NativePluralRules.OTHER, ar.quantityForInt(-1)); // Not ONE.
-        assertEquals(NativePluralRules.OTHER, ar.quantityForInt(-2)); // Not TWO.
-        assertEquals(NativePluralRules.OTHER, ar.quantityForInt(-3)); // Not FEW.
-        assertEquals(NativePluralRules.OTHER, ar.quantityForInt(-11)); // Not MANY.
-        assertEquals(NativePluralRules.OTHER, ar.quantityForInt(-100));
-    }
-
-    public void testEnglish() throws Exception {
-        NativePluralRules npr = NativePluralRules.forLocale(new Locale("en", "US"));
-        assertEquals(NativePluralRules.OTHER, npr.quantityForInt(0));
-        assertEquals(NativePluralRules.ONE, npr.quantityForInt(1));
-        assertEquals(NativePluralRules.OTHER, npr.quantityForInt(2));
-    }
-
-    public void testCzech() throws Exception {
-        NativePluralRules npr = NativePluralRules.forLocale(new Locale("cs", "CZ"));
-        assertEquals(NativePluralRules.OTHER, npr.quantityForInt(0));
-        assertEquals(NativePluralRules.ONE, npr.quantityForInt(1));
-        assertEquals(NativePluralRules.FEW, npr.quantityForInt(2));
-        assertEquals(NativePluralRules.FEW, npr.quantityForInt(3));
-        assertEquals(NativePluralRules.FEW, npr.quantityForInt(4));
-        assertEquals(NativePluralRules.OTHER, npr.quantityForInt(5));
-    }
-
-    public void testArabic() throws Exception {
-        NativePluralRules npr = NativePluralRules.forLocale(new Locale("ar"));
-        assertEquals(NativePluralRules.ZERO, npr.quantityForInt(0));
-        assertEquals(NativePluralRules.ONE, npr.quantityForInt(1));
-        assertEquals(NativePluralRules.TWO, npr.quantityForInt(2));
-        for (int i = 3; i <= 10; ++i) {
-            assertEquals(NativePluralRules.FEW, npr.quantityForInt(i));
-        }
-        assertEquals(NativePluralRules.MANY, npr.quantityForInt(11));
-        assertEquals(NativePluralRules.MANY, npr.quantityForInt(99));
-        assertEquals(NativePluralRules.OTHER, npr.quantityForInt(100));
-        assertEquals(NativePluralRules.OTHER, npr.quantityForInt(101));
-        assertEquals(NativePluralRules.OTHER, npr.quantityForInt(102));
-        assertEquals(NativePluralRules.FEW, npr.quantityForInt(103));
-        assertEquals(NativePluralRules.MANY, npr.quantityForInt(111));
-    }
-
-    public void testHebrew() throws Exception {
-        // java.util.Locale will translate "he" to the deprecated "iw".
-        NativePluralRules he = NativePluralRules.forLocale(new Locale("he"));
-        assertEquals(NativePluralRules.ONE, he.quantityForInt(1));
-        assertEquals(NativePluralRules.TWO, he.quantityForInt(2));
-        assertEquals(NativePluralRules.OTHER, he.quantityForInt(3));
-        assertEquals(NativePluralRules.OTHER, he.quantityForInt(10));
-    }
-}
-
diff --git a/luni/src/test/java/libcore/java/security/SignatureTest.java b/luni/src/test/java/libcore/java/security/SignatureTest.java
index f6e3a06..79a75c8 100644
--- a/luni/src/test/java/libcore/java/security/SignatureTest.java
+++ b/luni/src/test/java/libcore/java/security/SignatureTest.java
@@ -16,7 +16,9 @@
 
 package libcore.java.security;
 
+import java.lang.reflect.Method;
 import java.math.BigInteger;
+import java.security.AlgorithmParameters;
 import java.security.InvalidKeyException;
 import java.security.InvalidParameterException;
 import java.security.KeyFactory;
@@ -29,6 +31,7 @@
 import java.security.Security;
 import java.security.Signature;
 import java.security.SignatureException;
+import java.security.SignatureSpi;
 import java.security.spec.DSAPrivateKeySpec;
 import java.security.spec.DSAPublicKeySpec;
 import java.security.spec.ECFieldFp;
@@ -41,8 +44,11 @@
 import java.security.spec.RSAPrivateKeySpec;
 import java.security.spec.RSAPublicKeySpec;
 import java.security.spec.X509EncodedKeySpec;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.Callable;
@@ -1738,4 +1744,106 @@
         result = ecdsaVerify.verify(SIGNATURE);
         assertEquals(false, result);
     }
+
+    /**
+     * When an instance of a Signature is obtained, it's actually wrapped in an
+     * implementation that makes sure the correct SPI is selected and then calls
+     * through to the underlying SPI. We need to make sure that all methods on
+     * the delegate are wrapped and don't call directly into
+     * {@link SignatureSpi}.
+     */
+    public void testSignatureDelegateOverridesAllMethods() throws Exception {
+        Signature sig = Signature.getInstance("SHA1withRSA");
+
+        /*
+         * Make sure we're dealing with a delegate and not an actual instance of
+         * Signature.
+         */
+        Class<?> sigClass = sig.getClass();
+        assertFalse(sigClass.equals(SignatureSpi.class));
+        assertFalse(sigClass.equals(Signature.class));
+
+        List<String> methodsNotOverridden = new ArrayList<String>();
+
+        for (Method spiMethod : SignatureSpi.class.getDeclaredMethods()) {
+            try {
+                sigClass.getDeclaredMethod(spiMethod.getName(), spiMethod.getParameterTypes());
+            } catch (NoSuchMethodException e) {
+                methodsNotOverridden.add(spiMethod.toString());
+            }
+        }
+
+        assertEquals(Collections.EMPTY_LIST, methodsNotOverridden);
+    }
+
+    public void testGetParameters_IsCalled() throws Exception {
+        Signature sig = Signature.getInstance(FakeProviderForGetParametersTest.ALGORITHM,
+                new FakeProviderForGetParametersTest());
+
+        boolean[] getParametersCalled = new boolean[1];
+        sig.setParameter(FakeProviderForGetParametersTest.CALLBACK_PARAM_NAME, getParametersCalled);
+
+        assertFalse(getParametersCalled[0]);
+        sig.getParameters();
+        assertTrue(getParametersCalled[0]);
+    }
+
+    private static class FakeProviderForGetParametersTest extends Provider {
+        public static final String ALGORITHM = "FAKEFORGETPARAMETERS";
+        public static final String CALLBACK_PARAM_NAME = "callback";
+
+        protected FakeProviderForGetParametersTest() {
+            super("FakeProviderForGetParametersTest", 1.0, "For testing only");
+            put("Signature." + ALGORITHM, FakeSignatureWithGetParameters.class.getName());
+        }
+
+        public static class FakeSignatureWithGetParameters extends SignatureSpi {
+            private boolean[] callback;
+
+            @Override
+            protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
+            }
+
+            @Override
+            protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
+            }
+
+            @Override
+            protected void engineUpdate(byte b) throws SignatureException {
+            }
+
+            @Override
+            protected void engineUpdate(byte[] b, int off, int len) throws SignatureException {
+            }
+
+            @Override
+            protected byte[] engineSign() throws SignatureException {
+                return null;
+            }
+
+            @Override
+            protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
+                return false;
+            }
+
+            @Override
+            protected void engineSetParameter(String param, Object value)
+                    throws InvalidParameterException {
+                if (CALLBACK_PARAM_NAME.equals(param)) {
+                    callback = (boolean[]) value;
+                }
+            }
+
+            @Override
+            protected Object engineGetParameter(String param) throws InvalidParameterException {
+                return null;
+            }
+
+            @Override
+            protected AlgorithmParameters engineGetParameters() {
+                callback[0] = true;
+                return null;
+            }
+        }
+    }
 }