import cl @56673
diff --git a/i18n/decimfmt.cpp b/i18n/decimfmt.cpp
index a472088..dd2e809 100644
--- a/i18n/decimfmt.cpp
+++ b/i18n/decimfmt.cpp
@@ -60,6 +60,9 @@
 #include <stdio.h>
 
 
+#define LOGI(...) printf("<I>"); printf(__VA_ARGS__); printf("</I>");
+
+
 U_NAMESPACE_BEGIN
 
 //#define FMT_DEBUG
@@ -1299,6 +1302,7 @@
     return result;
 }
 
+// BEGIN android-changed
 /**
  * Parses the given text as either a number or a currency amount.
  * @param text the string to parse
@@ -1315,9 +1319,47 @@
                           Formattable& result,
                           ParsePosition& parsePosition,
                           UBool parseCurrency) const {
+    bool resultAssigned;
+    int scale;
+    DigitList digits;
+    parse(text, resultAssigned, result, parsePosition, parseCurrency, digits, scale);
+
+    if(!resultAssigned) {
+        result.setDouble(digits.getDouble() / scale);
+    }
+
+}
+
+/**
+ * Parses the given text as either a number or a currency amount.
+ * @param text the string to parse
+ * @param resultAssigned indicates whether or not the param result is assigned
+ * @param result output parameter for the parsing result
+ *    ATTENTION: result is assigned ONLY for types long and int64
+ * @param parsePosition input-output position; on input, the
+ * position within text to match; must have 0 <= pos.getIndex() <
+ * text.length(); on output, the position after the last matched
+ * character. If the parse fails, the position in unchanged upon
+ * output.
+ * @param parseCurrency if true, a currency amount is parsed;
+ * otherwise a Number is parsed
+ * @param digits The DigitList that represents the result will be returned
+ * @param scale the scale with which the number in the DigitList
+ * has to be scaled
+ *    ATTENTION: list and scale are only returned when result was not assigned
+ */
+void DecimalFormat::parse(const UnicodeString& text,
+                          bool& resultAssigned,
+                          Formattable& result,
+                          ParsePosition& parsePosition,
+                          UBool parseCurrency,
+                          DigitList& digits,
+                          int& scale) const {
     int32_t backup;
     int32_t i = backup = parsePosition.getIndex();
 
+    resultAssigned = true;
+
     // Handle NaN as a special case:
     
     // Skip padding characters, if around prefix
@@ -1347,7 +1389,6 @@
     UBool status[fgStatusLength];
     UChar curbuf[4];
     UChar* currency = parseCurrency ? curbuf : NULL;
-    DigitList digits;
 
     if (!subparse(text, parsePosition, digits, status, currency)) {
         parsePosition.setIndex(backup);
@@ -1359,7 +1400,6 @@
         double inf = uprv_getInfinity();
         result.setDouble(digits.fIsPositive ? inf : -inf);
     }
-
     else {
         // Do as much of the multiplier conversion as possible without
         // losing accuracy.
@@ -1393,11 +1433,13 @@
             else {  // else handle the remainder
                 result.setDouble(((double)n) / mult);
             }
-        }
+        }/*
+        else if (digits.fitsIntoDouble()) {
+            result.setDouble(digits.getDouble() / mult);LOGI("fits into neither\n");
+        }*/
         else {
-            // Handle non-integral or very large values
-            // Dividing by one is okay and not that costly.
-            result.setDouble(digits.getDouble() / mult);
+            scale = mult;
+            resultAssigned = false;
         }
     }
 
@@ -1408,7 +1450,7 @@
         U_ASSERT(U_SUCCESS(ec)); // should always succeed
     }
 }
-
+// END android-changed
 
 /*
 This is an old implimentation that was preparing for 64-bit numbers in ICU.
diff --git a/i18n/digitlst.cpp b/i18n/digitlst.cpp
index 39e69fd..83f84ca 100644
--- a/i18n/digitlst.cpp
+++ b/i18n/digitlst.cpp
@@ -61,12 +61,19 @@
 
 U_NAMESPACE_BEGIN
 
+// BEGIN android-added
+// capacity of a dynamically allocated fDecimalDigits buffer
+int fBufferSize = 0;
+// END android-added
 
 // -------------------------------------
 // default constructor
 
 DigitList::DigitList()
 {
+    // BEGIN android-added
+    fDecimalDigits = fDecimalDigitsBuffer;
+    // END android-added
     fDigits = fDecimalDigits + 1;   // skip the decimal
     clear();
 }
@@ -75,13 +82,32 @@
 
 DigitList::~DigitList()
 {
+    // BEGIN android-added
+    if (fDecimalDigits != fDecimalDigitsBuffer) free(fDecimalDigits);
+    // END android-added
 }
 
+// BEGIN android-added
+// -------------------------------------
+// capacity constructor
+
+DigitList::DigitList(int capacity)
+{
+    fBufferSize = capacity;
+    fDecimalDigits = (char *) malloc(capacity);
+    fDigits = fDecimalDigits + 1;   // skip the decimal
+    clear();
+}
+// END android-added
+
 // -------------------------------------
 // copy constructor
 
 DigitList::DigitList(const DigitList &other)
 {
+    // BEGIN android-added
+    fDecimalDigits = fDecimalDigitsBuffer;
+    // END android-added
     fDigits = fDecimalDigits + 1;   // skip the decimal
     *this = other;
 }
@@ -98,6 +124,14 @@
         fCount = other.fCount;
         fIsPositive = other.fIsPositive;
         fRoundingMode = other.fRoundingMode;
+        // BEGIN android-added
+        if (other.fDecimalDigits != other.fDecimalDigitsBuffer)
+        {
+            fBufferSize = other.fBufferSize;
+            fDecimalDigits = (char *) malloc(fBufferSize);
+            fDigits = fDecimalDigits + 1;   // skip the decimal
+        }
+        // END android-added
         uprv_strncpy(fDigits, other.fDigits, fCount);
     }
     return *this;
diff --git a/i18n/digitlst.h b/i18n/digitlst.h
index e6266dd..eae501c 100644
--- a/i18n/digitlst.h
+++ b/i18n/digitlst.h
@@ -71,6 +71,14 @@
     DigitList();
     ~DigitList();
 
+    // BEGIN android-added
+    /* capacity constructor
+     * @param capacity The size of the digit list buffer
+     * @return the newly created object. 
+     */
+    DigitList(int capacity);
+    // END android-added
+
     /* copy constructor
      * @param DigitList The object to be copied.
      * @return the newly created object. 
@@ -227,8 +235,14 @@
 
 private:
 
+    // BEGIN android-changed
     /* One character before fDigits for the decimal*/
-    char        fDecimalDigits[MAX_DEC_DIGITS + 1];
+    char        *fDecimalDigits;
+
+    char        fDecimalDigitsBuffer[MAX_DEC_DIGITS + 1];
+
+    int fBufferSize;
+    // END android-changed
 
     /**
      * Round the representation to the given number of digits.
diff --git a/i18n/unicode/decimfmt.h b/i18n/unicode/decimfmt.h
index 9789043..92c96bf 100644
--- a/i18n/unicode/decimfmt.h
+++ b/i18n/unicode/decimfmt.h
@@ -907,6 +907,15 @@
      */
     UnicodeString& format(int64_t number,
                           UnicodeString& appendTo) const;
+
+    // BEGIN android-added
+    UnicodeString& subformat(UnicodeString& appendTo,
+                             FieldPosition& fieldPosition,
+                             AttrBuffer attrBuffer,
+                             DigitList& digits,
+                             UBool         isInteger) const;
+    // END android-changed
+
    /**
     * Parse the given string using this object's choices. The method
     * does string comparisons to try to find an optimal match.
@@ -943,6 +952,36 @@
                        Formattable& result, 
                        UErrorCode& status) const;
 
+    // BEGIN android-added
+    // A way to access parsing directly as workaround for missing
+    // BigNum parsing
+    /**
+     * Parses the given text as either a number or a currency amount.
+     * @param text the string to parse
+     * @param resultAssigned indicates whether or not the param result is assigned
+     * @param result output parameter for the result
+     *    ATTENTION: result is assigned ONLY for types long and int64
+     * @param parsePosition input-output position; on input, the
+     * position within text to match; must have 0 <= pos.getIndex() <
+     * text.length(); on output, the position after the last matched
+     * character. If the parse fails, the position in unchanged upon
+     * output.
+     * @param parseCurrency if true, a currency amount is parsed;
+     * otherwise a Number is parsed
+     * @param digits The DigitList that represents the result will be returned
+     * @param scale the scale with which the number in the DigitList 
+     * has to be scaled
+    *    ATTENTION: list and scale are only returned when result was not assigned
+     */
+    virtual void parse(const UnicodeString& text,
+                       bool& resultAssigned,
+                       Formattable& result,
+                       ParsePosition& parsePosition,
+                       UBool parseCurrency,
+                       DigitList& digits,
+                       int& scale) const;
+    // END android-added
+
     /**
      * Parses text from the given string as a currency amount.  Unlike
      * the parse() method, this method will attempt to parse a generic
@@ -1726,11 +1765,13 @@
                              DigitList& digits,
                              UBool         isInteger) const;
 
-    UnicodeString& subformat(UnicodeString& appendTo,
-                             FieldPosition& fieldPosition,
-                             AttrBuffer attrBuffer,
-                             DigitList& digits,
-                             UBool         isInteger) const;
+    // BEGIN android-removed
+    // UnicodeString& subformat(UnicodeString& appendTo,
+    //                          FieldPosition& fieldPosition,
+    //                          AttrBuffer attrBuffer,
+    //                          DigitList& digits,
+    //                          UBool         isInteger) const;
+    // END android-removed
 
     void parse(const UnicodeString& text,
                Formattable& result,