Add's Java 6's DecimalFormat.setRoundingMode (et cetera).

Format and NumberFormat's bogusly-public constructors became protected with
Java 6. DecimalFormat gained more control over rounding behavior. There's a
slight mismatch with our ICU4C-based implementation in that ICU4C doesn't
support RoundingMode.UNNECESSARY, so I've had to fake that (but I doubt it's
used much, if at all).

I've pulled out the obviously Android-specific tests from the harmony
DecimalFormatTest.java, but I've only brought back the rounding mode changes
from the current harmony code to avoid the new tests' dependencies. I've also
added one new test of my own, to check that setMaximumFractionDigits affects
rounding as it should (since the harmony tests don't test this, and it's
somewhat subtle).

Bug: 2497395
Change-Id: Ifafc8bb051e078ead988073281f5c33f0aeb130a
diff --git a/libcore/icu/src/main/java/com/ibm/icu4jni/text/NativeDecimalFormat.java b/libcore/icu/src/main/java/com/ibm/icu4jni/text/NativeDecimalFormat.java
index d1da72f..d46c2ec 100644
--- a/libcore/icu/src/main/java/com/ibm/icu4jni/text/NativeDecimalFormat.java
+++ b/libcore/icu/src/main/java/com/ibm/icu4jni/text/NativeDecimalFormat.java
@@ -20,6 +20,7 @@
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.math.RoundingMode;
 import java.text.AttributedCharacterIterator;
 import java.text.AttributedString;
 import java.text.DecimalFormatSymbols;
@@ -570,6 +571,21 @@
         }
     }
 
+    public void setRoundingMode(RoundingMode roundingMode, double roundingIncrement) {
+        final int nativeRoundingMode;
+        switch (roundingMode) {
+        case CEILING: nativeRoundingMode = 0; break;
+        case FLOOR: nativeRoundingMode = 1; break;
+        case DOWN: nativeRoundingMode = 2; break;
+        case UP: nativeRoundingMode = 3; break;
+        case HALF_EVEN: nativeRoundingMode = 4; break;
+        case HALF_DOWN: nativeRoundingMode = 5; break;
+        case HALF_UP: nativeRoundingMode = 6; break;
+        default: throw new AssertionError();
+        }
+        setRoundingMode(addr, nativeRoundingMode, roundingIncrement);
+    }
+
     private static native void applyPatternImpl(int addr, boolean localized, String pattern);
     private static native int cloneDecimalFormatImpl(int addr);
     private static native void closeDecimalFormatImpl(int addr);
@@ -589,6 +605,7 @@
             String nan, char patternSeparator, char percent, char perMill, char zeroDigit);
     private static native void setSymbol(int addr, int symbol, String str);
     private static native void setAttribute(int addr, int symbol, int i);
+    private static native void setRoundingMode(int addr, int roundingMode, double roundingIncrement);
     private static native void setTextAttribute(int addr, int symbol, String str);
     private static native String toPatternImpl(int addr, boolean localized);
 }
diff --git a/libcore/icu/src/main/native/NativeDecimalFormat.cpp b/libcore/icu/src/main/native/NativeDecimalFormat.cpp
index 413ffdd..b62e5b1 100644
--- a/libcore/icu/src/main/native/NativeDecimalFormat.cpp
+++ b/libcore/icu/src/main/native/NativeDecimalFormat.cpp
@@ -103,10 +103,16 @@
     return static_cast<jint>(reinterpret_cast<uintptr_t>(fmt));
 }
 
-static void closeDecimalFormatImpl(JNIEnv *env, jclass clazz, jint addr) {
+static void closeDecimalFormatImpl(JNIEnv* env, jclass, jint addr) {
     delete toDecimalFormat(addr);
 }
 
+static void setRoundingMode(JNIEnv* env, jclass, jint addr, jint mode, jdouble increment) {
+    DecimalFormat* fmt = toDecimalFormat(addr);
+    fmt->setRoundingMode(static_cast<DecimalFormat::ERoundingMode>(mode));
+    fmt->setRoundingIncrement(increment);
+}
+
 static void setSymbol(JNIEnv* env, jclass, jint addr, jint symbol, jstring s) {
     const UChar* chars = env->GetStringChars(s, NULL);
     const int32_t charCount = env->GetStringLength(s);
@@ -593,6 +599,7 @@
     {"setAttribute", "(III)V", (void*) setAttribute},
     {"setDecimalFormatSymbols", "(ILjava/lang/String;CCCLjava/lang/String;Ljava/lang/String;CCLjava/lang/String;CCCC)V", (void*) setDecimalFormatSymbols},
     {"setSymbol", "(IILjava/lang/String;)V", (void*) setSymbol},
+    {"setRoundingMode", "(IID)V", (void*) setRoundingMode},
     {"setTextAttribute", "(IILjava/lang/String;)V", (void*) setTextAttribute},
     {"toPatternImpl", "(IZ)Ljava/lang/String;", (void*) toPatternImpl},
 };
diff --git a/libcore/luni/src/test/java/java/text/DecimalFormatTest.java b/libcore/luni/src/test/java/java/text/DecimalFormatTest.java
index 6b2eb3d..c3a2721 100644
--- a/libcore/luni/src/test/java/java/text/DecimalFormatTest.java
+++ b/libcore/luni/src/test/java/java/text/DecimalFormatTest.java
@@ -19,10 +19,21 @@
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
+import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.math.RoundingMode;
 import java.util.Locale;
 
 public class DecimalFormatTest extends junit.framework.TestCase {
+    public void test_setMaximumFractionDigitsAffectsRoundingMode() throws Exception {
+        DecimalFormat df = (DecimalFormat) DecimalFormat.getInstance(Locale.US);
+        df.setMaximumFractionDigits(0);
+        df.setRoundingMode(RoundingMode.HALF_UP);
+        assertEquals("-0", df.format(-0.2));
+        df.setMaximumFractionDigits(1);
+        assertEquals("-0.2", df.format(-0.2));
+    }
+    
     // Android fails this test, truncating to 127 digits.
     public void test_setMaximumIntegerDigits() throws Exception {
         NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
@@ -34,4 +45,92 @@
         assertEquals(309, numberFormat.format(123).length());
         assertEquals(309, numberFormat.format(BigInteger.valueOf(123)).length());
     }
+    
+    // Regression test for http://b/1897917: BigDecimal does not take into account multiplier.
+    public void testBigDecimalBug1897917() {
+        // For example. the BigDecimal 0.17 formatted in PercentInstance is 0% instead of 17%:
+        NumberFormat pf = NumberFormat.getPercentInstance();
+        assertEquals("17%", pf.format(BigDecimal.valueOf(0.17)));
+        
+        // Test long decimal formatted in PercentInstance with various fractions.
+        String longDec = "11.2345678901234567890123456789012345678901234567890";
+        BigDecimal bd = new BigDecimal(longDec);
+        assertBigDecimalWithFraction(bd, "1,123.46%", 2);
+        assertBigDecimalWithFraction(bd, "1,123.45678901%", 8);
+        assertBigDecimalWithFraction(bd, "1,123.4567890123%", 10);
+        assertBigDecimalWithFraction(bd, "1,123.45678901234567890123%", 20);
+        assertBigDecimalWithFraction(bd, "1,123.456789012345678901234567890123%", 30);
+        
+        // Test trailing zeros.
+        assertDecFmtWithMultiplierAndFraction("3333.33333333", 3, 4, "10,000");
+        assertDecFmtWithMultiplierAndFraction("3333.33333333", -3, 4, "-10,000");
+        assertDecFmtWithMultiplierAndFraction("0.00333333", 3, 4, "0.01");
+        assertDecFmtWithMultiplierAndFraction("3330000000000000000000000000000000", 3, 4,
+                "9,990,000,000,000,000,000,000,000,000,000,000");
+    }
+    
+    public void testBigDecimalTestBigIntWithMultiplier() {
+        // Big integer tests.
+        assertDecFmtWithMultiplierAndFraction("123456789012345", 10, 0,
+                "1,234,567,890,123,450");
+        assertDecFmtWithMultiplierAndFraction("12345678901234567890", 10, 0,
+                "123,456,789,012,345,678,900");
+        assertDecFmtWithMultiplierAndFraction("98765432109876543210987654321", 10, 0,
+                "987,654,321,098,765,432,109,876,543,210");
+        
+        assertDecFmtWithMultiplierAndFraction("123456789012345", -10, 0,
+                "-1,234,567,890,123,450");
+        assertDecFmtWithMultiplierAndFraction("12345678901234567890", -10, 0,
+                "-123,456,789,012,345,678,900");
+        assertDecFmtWithMultiplierAndFraction("98765432109876543210987654321", -10, 0,
+                "-987,654,321,098,765,432,109,876,543,210");
+    }
+    
+    public void testBigDecimalICUConsistency() {
+        DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
+        df.setMaximumFractionDigits(2);
+        df.setMultiplier(2);
+        assertEquals(df.format(BigDecimal.valueOf(0.16)),
+        df.format(BigDecimal.valueOf(0.16).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(0.0293)),
+        df.format(BigDecimal.valueOf(0.0293).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(0.006)),
+        df.format(BigDecimal.valueOf(0.006).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(0.00283)),
+        df.format(BigDecimal.valueOf(0.00283).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(1.60)),
+        df.format(BigDecimal.valueOf(1.60).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(15)),
+        df.format(BigDecimal.valueOf(15).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(170)),
+        df.format(BigDecimal.valueOf(170).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(234.56)),
+        df.format(BigDecimal.valueOf(234.56).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(0)),
+        df.format(BigDecimal.valueOf(0).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(-1)),
+        df.format(BigDecimal.valueOf(-1).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(-10000)),
+        df.format(BigDecimal.valueOf(-10000).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(-0.001)),
+        df.format(BigDecimal.valueOf(-0.001).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(1234567890.1234567)),
+        df.format(BigDecimal.valueOf(1234567890.1234567).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(1.234567E100)),
+        df.format(BigDecimal.valueOf(1.234567E100).doubleValue()));
+    }
+    
+    private void assertBigDecimalWithFraction(BigDecimal bd, String expectedResult, int fraction) {
+        NumberFormat pf = NumberFormat.getPercentInstance();
+        pf.setMaximumFractionDigits(fraction);
+        assertEquals(expectedResult, pf.format(bd));
+    }
+    
+    private void assertDecFmtWithMultiplierAndFraction(String value, int multiplier, int fraction, String expectedResult) {
+        DecimalFormat df = (DecimalFormat)NumberFormat.getInstance();
+        df.setMultiplier(multiplier);
+        df.setMaximumFractionDigits(fraction);
+        BigDecimal d = new BigDecimal(value);
+        assertEquals(expectedResult, df.format(d));
+    }
 }
diff --git a/libcore/text/src/main/java/java/text/DecimalFormat.java b/libcore/text/src/main/java/java/text/DecimalFormat.java
index 65d4d48..07047b2 100644
--- a/libcore/text/src/main/java/java/text/DecimalFormat.java
+++ b/libcore/text/src/main/java/java/text/DecimalFormat.java
@@ -27,6 +27,7 @@
 import java.io.ObjectStreamField;
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.math.RoundingMode;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.Currency;
@@ -553,6 +554,8 @@
 
     private transient NativeDecimalFormat dform;
 
+    private transient RoundingMode roundingMode = RoundingMode.HALF_EVEN;
+
     /**
      * Constructs a new {@code DecimalFormat} for formatting and parsing numbers
      * for the default locale.
@@ -709,6 +712,21 @@
 
     @Override
     public StringBuffer format(double value, StringBuffer buffer, FieldPosition position) {
+        // All float/double/Float/Double formatting ends up here...
+        if (roundingMode == RoundingMode.UNNECESSARY) {
+            // ICU4C doesn't support this rounding mode, so we have to fake it.
+            try {
+                setRoundingMode(RoundingMode.UP);
+                String upResult = format(value, new StringBuffer(), new FieldPosition(0)).toString();
+                setRoundingMode(RoundingMode.DOWN);
+                String downResult = format(value, new StringBuffer(), new FieldPosition(0)).toString();
+                if (!upResult.equals(downResult)) {
+                    throw new ArithmeticException("rounding mode UNNECESSARY but rounding required");
+                }
+            } finally {
+                setRoundingMode(RoundingMode.UNNECESSARY);
+            }
+        }
         return dform.format(value, buffer, position);
     }
 
@@ -1040,6 +1058,8 @@
     public void setMaximumFractionDigits(int value) {
         super.setMaximumFractionDigits(value);
         dform.setMaximumFractionDigits(getMaximumFractionDigits());
+        // Changing the maximum fraction digits needs to update ICU4C's rounding configuration.
+        setRoundingMode(roundingMode);
     }
 
     /**
@@ -1176,11 +1196,10 @@
             new ObjectStreamField("negSuffixPattern", String.class), //$NON-NLS-1$
             new ObjectStreamField("multiplier", int.class), //$NON-NLS-1$
             new ObjectStreamField("groupingSize", byte.class), //$NON-NLS-1$
-            // BEGIN android-added
             new ObjectStreamField("groupingUsed", boolean.class), //$NON-NLS-1$
-            // END android-added
             new ObjectStreamField("decimalSeparatorAlwaysShown", boolean.class), //$NON-NLS-1$
             new ObjectStreamField("parseBigDecimal", boolean.class), //$NON-NLS-1$
+            new ObjectStreamField("roundingMode", RoundingMode.class), //$NON-NLS-1$
             new ObjectStreamField("symbols", DecimalFormatSymbols.class), //$NON-NLS-1$
             new ObjectStreamField("useExponentialNotation", boolean.class), //$NON-NLS-1$
             new ObjectStreamField("minExponentDigits", byte.class), //$NON-NLS-1$
@@ -1220,6 +1239,7 @@
         fields.put("decimalSeparatorAlwaysShown", dform
                 .isDecimalSeparatorAlwaysShown());
         fields.put("parseBigDecimal", parseBigDecimal);
+        fields.put("roundingMode", roundingMode);
         fields.put("symbols", symbols);
         fields.put("useExponentialNotation", false);
         fields.put("minExponentDigits", (byte) 0);
@@ -1227,7 +1247,7 @@
         fields.put("minimumIntegerDigits", dform.getMinimumIntegerDigits());
         fields.put("maximumFractionDigits", dform.getMaximumFractionDigits());
         fields.put("minimumFractionDigits", dform.getMinimumFractionDigits());
-        fields.put("serialVersionOnStream", 3);
+        fields.put("serialVersionOnStream", 4);
         stream.writeFields();
     }
 
@@ -1243,9 +1263,7 @@
      *             if some class of serialized objects or fields cannot be found
      */
     @SuppressWarnings("nls")
-    private void readObject(ObjectInputStream stream) throws IOException,
-            ClassNotFoundException {
-
+    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
         // BEGIN android-changed
         ObjectInputStream.GetField fields = stream.readFields();
         this.symbols = (DecimalFormatSymbols) fields.get("symbols", null);
@@ -1260,6 +1278,8 @@
         dform.setGroupingUsed(fields.get("groupingUsed", true));
         dform.setDecimalSeparatorAlwaysShown(fields.get("decimalSeparatorAlwaysShown", false));
 
+        setRoundingMode((RoundingMode) fields.get("roundingMode", RoundingMode.HALF_EVEN));
+
         final int maximumIntegerDigits = fields.get("maximumIntegerDigits", 309);
         final int minimumIntegerDigits = fields.get("minimumIntegerDigits", 309);
         final int maximumFractionDigits = fields.get("maximumFractionDigits", 340);
@@ -1285,4 +1305,29 @@
         }
         // END android-changed
     }
+
+    /**
+     * Returns the {@code RoundingMode} used by this {@code NumberFormat}.
+     * @since 1.6
+     * @hide
+     */
+    public RoundingMode getRoundingMode() {
+        return roundingMode;
+    }
+
+    /**
+     * Sets the {@code RoundingMode} used by this {@code NumberFormat}.
+     * @since 1.6
+     * @hide
+     */
+    public void setRoundingMode(RoundingMode roundingMode) {
+        if (roundingMode == null) {
+            throw new NullPointerException();
+        }
+        this.roundingMode = roundingMode;
+        if (roundingMode != RoundingMode.UNNECESSARY) { // ICU4C doesn't support UNNECESSARY.
+            double roundingIncrement = 1.0 / Math.pow(10, Math.max(0, getMaximumFractionDigits()));
+            dform.setRoundingMode(roundingMode, roundingIncrement);
+        }
+    }
 }
diff --git a/libcore/text/src/main/java/java/text/Format.java b/libcore/text/src/main/java/java/text/Format.java
index 18b0490..ff62856 100644
--- a/libcore/text/src/main/java/java/text/Format.java
+++ b/libcore/text/src/main/java/java/text/Format.java
@@ -66,9 +66,9 @@
     private static final long serialVersionUID = -299282585814624189L;
 
     /**
-     * Constructs a new {@code Format} instance.
+     * Used by subclasses. This was public in Java 5.
      */
-    public Format() {
+    protected Format() {
     }
 
     /**
diff --git a/libcore/text/src/main/java/java/text/NumberFormat.java b/libcore/text/src/main/java/java/text/NumberFormat.java
index 0ad6ac4..2bf898d 100644
--- a/libcore/text/src/main/java/java/text/NumberFormat.java
+++ b/libcore/text/src/main/java/java/text/NumberFormat.java
@@ -27,6 +27,7 @@
 import java.io.ObjectOutputStream;
 import java.io.ObjectStreamField;
 import java.math.BigInteger;
+import java.math.RoundingMode;
 import java.util.Currency;
 import java.util.Locale;
 
@@ -164,9 +165,9 @@
             maximumFractionDigits = 3, minimumFractionDigits = 0;
 
     /**
-     * Constructs a new instance of {@code NumberFormat}.
+     * Used by subclasses. This was public in Java 5.
      */
-    public NumberFormat() {
+    protected NumberFormat() {
     }
 
     /**
@@ -896,4 +897,25 @@
         }
     }
 
+    /**
+     * Returns the {@code RoundingMode} used by this {@code NumberFormat}. The default
+     * implementation in {@code NumberFormat} throws {@code UnsupportedOperationException}.
+     * Subclasses for which a rounding mode is meaningful are expected to override this method.
+     * @since 1.6
+     * @hide
+     */
+    public RoundingMode getRoundingMode() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Sets the {@code RoundingMode} used by this {@code NumberFormat}. The default
+     * implementation in {@code NumberFormat} throws {@code UnsupportedOperationException}.
+     * Subclasses for which a rounding mode is meaningful are expected to override this method.
+     * @since 1.6
+     * @hide
+     */
+    public void setRoundingMode(RoundingMode roundingMode) {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java b/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java
index 92aaf71..d7f0eaa 100644
--- a/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java
+++ b/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java
@@ -35,6 +35,7 @@
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.math.RoundingMode;
 import java.text.AttributedCharacterIterator;
 import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
@@ -2563,119 +2564,321 @@
         DecimalFormat format = (DecimalFormat) DecimalFormat.getInstance();
         format.setDecimalFormatSymbols(null);
     }
-
-    private void assertBigDecimalWithFraction(
-            BigDecimal bd,
-            String expectedResult,
-            int fraction) {
-        NumberFormat pf = NumberFormat.getPercentInstance();
-        pf.setMaximumFractionDigits(fraction);
-        assertEquals(expectedResult, pf.format(bd));
-    }
-
-    private void assertDecFmtWithMultiplierAndFraction(
-            String value,
-            int multiplier,
-            int fraction,
-            String expectedResult) {
-
-        DecimalFormat df = (DecimalFormat)NumberFormat.getInstance();
-        df.setMultiplier(multiplier);
-        df.setMaximumFractionDigits(fraction);
-        BigDecimal d = new BigDecimal(value);
-        assertEquals(expectedResult, df.format(d));
-    }
-
-    @TestTargetNew(
-        level = TestLevel.ADDITIONAL,
-        notes = "Regression test for some existing bugs and crashes",
-        method = "format",
-        args = { String.class, Object[].class }
-    )
-    public void testBigDecimalBug1897917() {
-        // Bug1897917 : BigDecimal does not take into account multiplier.
-        // So the BigDecimal 0.17 formatted in PercentInstance is 0% instead of 17%.
-
-        NumberFormat pf = NumberFormat.getPercentInstance();
-
-        // Test bug 1897917 case.
-        assertEquals("17%", pf.format(BigDecimal.valueOf(0.17)));
-
-        // Test long decimal formatted in PercentInstance with various fractions.
-        String longDec = "11.2345678901234567890123456789012345678901234567890";
-        BigDecimal bd = new BigDecimal(longDec);
-        assertBigDecimalWithFraction(bd, "1,123.46%", 2);
-        assertBigDecimalWithFraction(bd, "1,123.45678901%", 8);
-        assertBigDecimalWithFraction(bd, "1,123.4567890123%", 10);
-        assertBigDecimalWithFraction(bd, "1,123.45678901234567890123%", 20);
-        assertBigDecimalWithFraction(bd, "1,123.456789012345678901234567890123%", 30);
-
-        // Test trailing zeros.
-        assertDecFmtWithMultiplierAndFraction("3333.33333333", 3, 4, "10,000");
-        assertDecFmtWithMultiplierAndFraction("3333.33333333", -3, 4, "-10,000");
-        assertDecFmtWithMultiplierAndFraction("0.00333333", 3, 4, "0.01");
-        assertDecFmtWithMultiplierAndFraction("3330000000000000000000000000000000", 3, 4,
-                                               "9,990,000,000,000,000,000,000,000,000,000,000");
-    }
-
-    @TestTargetNew(
-        level = TestLevel.ADDITIONAL,
-        notes = "Regression test for some existing bugs and crashes",
-        method = "format",
-        args = { String.class, Object[].class }
-    )
-    public void testBigDecimalTestBigIntWithMultiplier() {
-       // Big integer tests.
-       assertDecFmtWithMultiplierAndFraction("123456789012345", 10, 0, "1,234,567,890,123,450");
-       assertDecFmtWithMultiplierAndFraction("12345678901234567890", 10, 0,
-                                              "123,456,789,012,345,678,900");
-       assertDecFmtWithMultiplierAndFraction("98765432109876543210987654321", 10, 0,
-                                              "987,654,321,098,765,432,109,876,543,210");
-
-       assertDecFmtWithMultiplierAndFraction("123456789012345", -10, 0, "-1,234,567,890,123,450");
-       assertDecFmtWithMultiplierAndFraction("12345678901234567890", -10, 0,
-                                              "-123,456,789,012,345,678,900");
-       assertDecFmtWithMultiplierAndFraction("98765432109876543210987654321", -10, 0,
-                                              "-987,654,321,098,765,432,109,876,543,210");
-   }
-
-   @TestTargetNew(
-        level = TestLevel.ADDITIONAL,
-        notes = "Regression test for some existing bugs and crashes",
-        method = "format",
-        args = { String.class, Object[].class }
-   )
-   public void testBigDecimalICUConsistency() {
-       DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
-       df.setMaximumFractionDigits(2);
-       df.setMultiplier(2);
-       assertEquals(df.format(BigDecimal.valueOf(0.16)),
-                    df.format(BigDecimal.valueOf(0.16).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(0.0293)),
-                    df.format(BigDecimal.valueOf(0.0293).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(0.006)),
-                    df.format(BigDecimal.valueOf(0.006).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(0.00283)),
-                    df.format(BigDecimal.valueOf(0.00283).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(1.60)),
-                    df.format(BigDecimal.valueOf(1.60).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(15)),
-                    df.format(BigDecimal.valueOf(15).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(170)),
-                    df.format(BigDecimal.valueOf(170).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(234.56)),
-                    df.format(BigDecimal.valueOf(234.56).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(0)),
-                    df.format(BigDecimal.valueOf(0).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(-1)),
-                    df.format(BigDecimal.valueOf(-1).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(-10000)),
-                    df.format(BigDecimal.valueOf(-10000).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(-0.001)),
-                    df.format(BigDecimal.valueOf(-0.001).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(1234567890.1234567)),
-                    df.format(BigDecimal.valueOf(1234567890.1234567).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(1.234567E100)),
-                    df.format(BigDecimal.valueOf(1.234567E100).doubleValue()));
+    
+    // BEGIN android-added: brought back from the harmony java6 branch.
+    public void test_SetRoudingMode_Ljava_math_RoundingMode() {
+        DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.US);
+        // ignore the fraction part of a given value
+        decimalFormat.setMaximumFractionDigits(0);
+        
+        // set RoundingMode.HALF_DOWN of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.HALF_DOWN);
+        String result = decimalFormat.format(11.3);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11", result);
+        
+        result = decimalFormat.format(11.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11", result);
+        
+        result = decimalFormat.format(11.6);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "12", result);
+        
+        // set RoundingMode.CEILING of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.CEILING);
+        result = decimalFormat.format(11.3);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "12", result);
+        
+        result = decimalFormat.format(-11.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "-11", result);
+        
+        // set RoundingMode.DOWN of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.DOWN);
+        result = decimalFormat.format(11.3);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "11", result);
+        
+        result = decimalFormat.format(-11.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "-11", result);
+        
+        result = decimalFormat.format(0);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "0", result);
+        
+        // set RoundingMode.FLOOR of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.FLOOR);
+        result = decimalFormat.format(11.3);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "11", result);
+        
+        result = decimalFormat.format(-11.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "-12", result);
+        
+        result = decimalFormat.format(0);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "0", result);
+        
+        // set RoundingMode.HALF_EVEN of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.HALF_EVEN);
+        result = decimalFormat.format(5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "6", result);
+        
+        result = decimalFormat.format(-5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "-6", result);
+        
+        result = decimalFormat.format(0.2);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "0", result);
+        
+        // set RoundingMode.HALF_UP of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
+        result = decimalFormat.format(5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "6", result);
+        
+        result = decimalFormat.format(-5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "-6", result);
+        
+        result = decimalFormat.format(0.2);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "0", result);
+        
+        // BEGIN android-changed: we're RI-compatible.
+        // the following assertion will fail on RI implementation, since the
+        // implementation of ICU and RI are not identical.
+        result = decimalFormat.format(-0.2);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "-0", result);
+        // END android-changed
+        
+        // set RoundingMode.UP of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.UP);
+        result = decimalFormat.format(5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "6", result);
+        
+        result = decimalFormat.format(-5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "-6", result);
+        
+        result = decimalFormat.format(0.2);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "1", result);
+        
+        result = decimalFormat.format(-0.2);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "-1", result);
+        
+        // set RoundingMode.UNNECESSARY of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.UNNECESSARY);
+        
+        try {
+            // when rounding is needed but RoundingMode is set to RoundingMode.UNNECESSARY, throw ArithmeticException
+            result = decimalFormat.format(5.5);
+            fail("ArithmeticException expected: RoundingMode.UNNECESSARY");
+        } catch (ArithmeticException e) {
+            // expected
+        }
+        
+        result = decimalFormat.format(1.0);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "1", result);
+        
+        result = decimalFormat.format(-1.0);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "-1", result);
+        
+        try {
+            // when the given RoundingMode is null, throw NullPointerException
+            decimalFormat.setRoundingMode(null);
+            fail("NullPointerException expected");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        
+        // set MaxFractionDigits to 3, test different DecimalFormat format
+        // function with differnt RoundingMode
+        decimalFormat.setMaximumFractionDigits(3);
+        
+        // set RoundingMode.HALF_DOWN of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.HALF_DOWN);
+        result = decimalFormat.format(11.5653);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11.565", result);
+        
+        result = decimalFormat.format(11.5655);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11.565", result);
+        
+        result = decimalFormat.format(11.5656);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11.566", result);
+        
+        // set RoundingMode.CEILING of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.CEILING);
+        result = decimalFormat.format(11.5653);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "11.566", result);
+        
+        result = decimalFormat.format(-11.5653);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "-11.565", result);
+        
+        // set RoundingMode.DOWN of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.DOWN);
+        result = decimalFormat.format(11.5653);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "11.565", result);
+        
+        result = decimalFormat.format(-11.5653);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "-11.565", result);
+        
+        result = decimalFormat.format(0);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "0", result);
+        
+        // set RoundingMode.FLOOR of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.FLOOR);
+        result = decimalFormat.format(11.5653);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "11.565", result);
+        
+        result = decimalFormat.format(-11.5655);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "-11.566", result);
+        
+        result = decimalFormat.format(0);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "0", result);
+        
+        // set RoundingMode.HALF_EVEN of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.HALF_EVEN);
+        result = decimalFormat.format(11.5653);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "11.565", result);
+        
+        result = decimalFormat.format(-11.5655);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "-11.566", result);
+        
+        result = decimalFormat.format(11.5656);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "11.566", result);
+        
+        // set RoundingMode.HALF_UP of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
+        result = decimalFormat.format(11.5653);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "11.565", result);
+        
+        result = decimalFormat.format(-11.5655);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "-11.566", result);
+        
+        result = decimalFormat.format(11.5656);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "11.566", result);
+        
+        // set RoundingMode.UP of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.UP);
+        result = decimalFormat.format(11.5653);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "11.566", result);
+        
+        result = decimalFormat.format(-11.5655);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "-11.566", result);
+        
+        // set RoundingMode.UNNECESSARY of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.UNNECESSARY);
+        result = decimalFormat.format(-11.565);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "-11.565", result);
+        
+        result = decimalFormat.format(11.565);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "11.565", result);
+        
+        // when setting MaxFractionDigits to negative value -2, default it as
+        // zero, test different DecimalFormat format
+        // function with differnt RoundingMode
+        decimalFormat.setMaximumFractionDigits(-2);
+        
+        // set RoundingMode.HALF_DOWN of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.HALF_DOWN);
+        result = decimalFormat.format(11.3);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11", result);
+        
+        result = decimalFormat.format(11.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11", result);
+        
+        result = decimalFormat.format(11.6);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "12", result);
+        
+        // set RoundingMode.CEILING of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.CEILING);
+        result = decimalFormat.format(11.3);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "12", result);
+        
+        result = decimalFormat.format(-11.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "-11", result);
+        
+        // set RoundingMode.DOWN of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.DOWN);
+        result = decimalFormat.format(11.3);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "11", result);
+        
+        result = decimalFormat.format(-11.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "-11", result);
+        
+        result = decimalFormat.format(0);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "0", result);
+        
+        // set RoundingMode.FLOOR of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.FLOOR);
+        result = decimalFormat.format(11.3);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "11", result);
+        
+        result = decimalFormat.format(-11.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "-12", result);
+        
+        result = decimalFormat.format(0);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "0", result);
+        
+        // set RoundingMode.HALF_EVEN of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.HALF_EVEN);
+        result = decimalFormat.format(5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "6", result);
+        
+        result = decimalFormat.format(-5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "-6", result);
+        
+        result = decimalFormat.format(0.2);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "0", result);
+        
+        // set RoundingMode.HALF_UP of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
+        result = decimalFormat.format(5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "6", result);
+        
+        result = decimalFormat.format(-5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "-6", result);
+        
+        result = decimalFormat.format(0.2);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "0", result);
+        
+        result = decimalFormat.format(-0.2);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "-0", result);
+        
+        // set RoundingMode.UP of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.UP);
+        result = decimalFormat.format(5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "6", result);
+        
+        result = decimalFormat.format(-5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "-6", result);
+        
+        result = decimalFormat.format(0.2);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "1", result);
+        
+        result = decimalFormat.format(-0.2);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "-1", result);
+        
+        // set RoundingMode.UNNECESSARY of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.UNNECESSARY);
+        
+        result = decimalFormat.format(1.0);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "1", result);
+        
+        result = decimalFormat.format(-1.0);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "-1", result);
     }
 }