diff -ru CVS/classpath/java/text/DecimalFormat.java updated/classpath/java/text/DecimalFormat.java
--- CVS/classpath/java/text/DecimalFormat.java	2010-06-03 23:13:09.000000000 +0400
+++ updated/classpath/java/text/DecimalFormat.java	2010-11-04 14:33:37.156562000 +0300
@@ -1,5 +1,6 @@
 /* DecimalFormat.java -- Formats and parses numbers
-   Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005  Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2010
+   Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -132,7 +133,7 @@
 
   /**
    * This is an internal parameter used to keep track of the number
-   * of digits the form the exponent, when exponential notation is used.
+   * of digits that form the exponent, when exponential notation is used.
    * It is used with <code>exponentRound</code>
    */
   private byte minExponentDigits;
@@ -177,7 +178,7 @@
   private boolean hasFractionalPattern;
 
   /** Stores a list of attributes for use by formatToCharacterIterator. */
-  private ArrayList attributes = new ArrayList();
+  private final ArrayList attributes = new ArrayList();
 
   /**
    * Constructs a <code>DecimalFormat</code> which uses the default
@@ -584,20 +585,20 @@
    */
   public Number parse(String str, ParsePosition pos)
   {
+    // starting parsing position
+    int start = pos.getIndex();
+
     // a special values before anything else
     // NaN
-    if (str.contains(this.symbols.getNaN()))
-      return Double.valueOf(Double.NaN);
-
-    // this will be our final number
-    CPStringBuilder number = new CPStringBuilder();
+    if (str.startsWith(symbols.getNaN(), start))
+      {
+        pos.setIndex(start + symbols.getNaN().length()); // adjust pos
+        return Double.valueOf(Double.NaN);
+      }
 
     // special character
     char minus = symbols.getMinusSign();
 
-    // starting parsing position
-    int start = pos.getIndex();
-
     // validate the string, it have to be in the
     // same form as the format string or parsing will fail
     String _negativePrefix = (this.negativePrefix.compareTo("") == 0
@@ -606,38 +607,29 @@
 
     // we check both prefixes, because one might be empty.
     // We want to pick the longest prefix that matches.
-    int positiveLen = positivePrefix.length();
-    int negativeLen = _negativePrefix.length();
-
-    boolean isNegative = str.startsWith(_negativePrefix);
-    boolean isPositive = str.startsWith(positivePrefix);
-
-    if (isPositive && isNegative)
+    boolean isNegative = str.startsWith(_negativePrefix, start);
+    if (str.startsWith(positivePrefix, start))
       {
-        // By checking this way, we preserve ambiguity in the case
-        // where the negative format differs only in suffix.
-        if (negativeLen > positiveLen)
-          {
-            start += _negativePrefix.length();
-            isNegative = true;
-          }
-        else
+        int positiveLen = positivePrefix.length();
+        if (isNegative)
           {
-            start += positivePrefix.length();
-            isPositive = true;
+            // By checking this way, we preserve ambiguity in the case
+            // where the negative format differs only in suffix.
+            int negativeLen = _negativePrefix.length();
             if (negativeLen < positiveLen)
-              isNegative = false;
+              {
+                isNegative = false;
+                start += positiveLen;
+              }
+            else
+              start += negativeLen;
           }
+        else
+          start += positiveLen;
       }
     else if (isNegative)
       {
         start += _negativePrefix.length();
-        isPositive = false;
-      }
-    else if (isPositive)
-      {
-        start += positivePrefix.length();
-        isNegative = false;
       }
     else
       {
@@ -645,16 +637,35 @@
         return null;
       }
 
+    // 2nd special case: infinity
+    if (str.startsWith(symbols.getInfinity(), start))
+      {
+        pos.setIndex(start + symbols.getInfinity().length());
+
+        // FIXME: ouch, this is really ugly and lazy code...
+        if (this.parseBigDecimal)
+          {
+            if (isNegative)
+              return BigDecimal.valueOf(Double.NEGATIVE_INFINITY);
+            return BigDecimal.valueOf(Double.POSITIVE_INFINITY);
+          }
+
+        if (isNegative)
+          return Double.valueOf(Double.NEGATIVE_INFINITY);
+        return Double.valueOf(Double.POSITIVE_INFINITY);
+      }
+
     // other special characters used by the parser
     char decimalSeparator = symbols.getDecimalSeparator();
     char zero = symbols.getZeroDigit();
     char exponent = symbols.getExponential();
 
     // stop parsing position in the string
-    int stop = start + this.maximumIntegerDigits + maximumFractionDigits + 2;
-
+    int stop = start + maximumIntegerDigits;
+    if (maximumFractionDigits > 0)
+      stop += maximumFractionDigits + 1;
     if (useExponentialNotation)
-      stop += minExponentDigits + 1;
+      stop += (minExponentDigits > 0 ? minExponentDigits : 1) + 2;
 
     boolean inExponent = false;
 
@@ -663,74 +674,51 @@
     if (len < stop) stop = len;
     char groupingSeparator = symbols.getGroupingSeparator();
 
-    int i = start;
-    while (i < stop)
+    // this will be our final number
+    CPStringBuilder number = new CPStringBuilder();
+
+    int i;
+    for (i = start; i < stop; i++)
       {
         char ch = str.charAt(i);
-        i++;
-
         if (ch >= zero && ch <= (zero + 9))
           {
-            number.append(ch);
+            number.append((char)(ch - (zero - '0')));
           }
         else if (this.parseIntegerOnly)
           {
-            i--;
             break;
           }
         else if (ch == decimalSeparator)
           {
             number.append('.');
           }
-        else if (ch == exponent)
+        else if (ch == exponent && !inExponent && useExponentialNotation)
           {
-            number.append(ch);
-            inExponent = !inExponent;
+            number.append('e');
+            inExponent = true;
           }
-        else if ((ch == '+' || ch == '-' || ch == minus))
+        else if (ch == '+' || ch == '-' || ch == minus)
           {
             if (inExponent)
-              number.append(ch);
+              {
+                if (ch != '+')
+                  number.append('-');
+              }
             else
               {
-                i--;
                 break;
               }
           }
         else
           {
             if (!groupingUsed || ch != groupingSeparator)
-              {
-                i--;
-                break;
-              }
-          }
-      }
-
-    // 2nd special case: infinity
-    // XXX: need to be tested
-    if (str.contains(symbols.getInfinity()))
-      {
-        int inf = str.indexOf(symbols.getInfinity());
-        pos.setIndex(inf);
-
-        // FIXME: ouch, this is really ugly and lazy code...
-        if (this.parseBigDecimal)
-          {
-            if (isNegative)
-              return BigDecimal.valueOf(Double.NEGATIVE_INFINITY);
-
-            return BigDecimal.valueOf(Double.POSITIVE_INFINITY);
+              break;
           }
-
-        if (isNegative)
-          return Double.valueOf(Double.NEGATIVE_INFINITY);
-
-        return Double.valueOf(Double.POSITIVE_INFINITY);
       }
 
     // no number...
-    if (i == start || number.length() == 0)
+    if (number.length() == 0)
       {
         pos.setErrorIndex(i);
         return null;
@@ -738,25 +726,21 @@
 
     // now we have to check the suffix, done here after number parsing
     // or the index will not be updated correctly...
-    boolean hasNegativeSuffix = str.endsWith(this.negativeSuffix);
-    boolean hasPositiveSuffix = str.endsWith(this.positiveSuffix);
-    boolean positiveEqualsNegative = negativeSuffix.equals(positiveSuffix);
-
-    positiveLen = positiveSuffix.length();
-    negativeLen = negativeSuffix.length();
-
+    int positiveLen = positiveSuffix.length();
+    int negativeLen = negativeSuffix.length();
+    boolean hasNegativeSuffix = str.regionMatches(i, negativeSuffix, 0,
+                                                  negativeLen);
     if (isNegative && !hasNegativeSuffix)
       {
         pos.setErrorIndex(i);
         return null;
       }
-    else if (hasNegativeSuffix &&
-             !positiveEqualsNegative &&
-             (negativeLen > positiveLen))
+    else if (hasNegativeSuffix && negativeLen > positiveLen
+             && !negativeSuffix.equals(positiveSuffix))
       {
         isNegative = true;
       }
-    else if (!hasPositiveSuffix)
+    else if (!str.regionMatches(i, positiveSuffix, 0, positiveLen))
       {
         pos.setErrorIndex(i);
         return null;
@@ -764,7 +748,7 @@
 
     if (isNegative) number.insert(0, '-');
 
-    pos.setIndex(i);
+    pos.setIndex(i + (isNegative ? negativeLen : positiveLen));
 
     // now we handle the return type
     BigDecimal bigDecimal = new BigDecimal(number.toString());
@@ -1012,7 +996,7 @@
    * @return <code>true</code> if the strings are both <code>null</code> or
    * equals.
    */
-  private boolean equals(String s1, String s2)
+  private static boolean equals(String s1, String s2)
   {
     if (s1 == null || s2 == null)
       return s1 == s2;
@@ -1026,7 +1010,7 @@
    * This helper function creates a string consisting of all the
    * characters which can appear in a pattern and must be quoted.
    */
-  private String patternChars (DecimalFormatSymbols syms)
+  private static String patternChars (DecimalFormatSymbols syms)
   {
     CPStringBuilder buf = new CPStringBuilder ();
 
@@ -1053,7 +1037,7 @@
    * @param patChars
    * @return A StringBuffer with special characters quoted.
    */
-  private CPStringBuilder quoteFix(String text, String patChars)
+  private static CPStringBuilder quoteFix(String text, String patChars)
   {
     CPStringBuilder buf = new CPStringBuilder();
 
diff -ru CVS/classpath/java/text/SimpleDateFormat.java updated/classpath/java/text/SimpleDateFormat.java
--- CVS/classpath/java/text/SimpleDateFormat.java	2010-06-03 23:13:10.000000000 +0400
+++ updated/classpath/java/text/SimpleDateFormat.java	2010-11-04 14:33:46.959645500 +0300
@@ -1,6 +1,6 @@
 /* SimpleDateFormat.java -- A class for parsing/formating simple
    date constructs
-   Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005
+   Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2010
    Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
@@ -74,13 +74,13 @@
    * ID, size, and character used are stored for each sequence
    * of pattern characters.
    */
-  private class CompiledField
+  private static final class CompiledField
   {
     /**
      * The ID of the field within the local pattern characters.
      * Package private for use in out class.
      */
-    int field;
+    final int field;
 
     /**
      * The size of the character sequence.
@@ -91,7 +91,7 @@
     /**
      * The character used.
      */
-    private char character;
+    private final char character;
 
     /**
      * Constructs a compiled field using the
@@ -102,7 +102,7 @@
      * @param s the size of the field.
      * @param c the character used.
      */
-    public CompiledField(int f, int s, char c)
+    CompiledField(int f, int s, char c)
     {
       field = f;
       size = s;
@@ -113,7 +113,7 @@
      * Retrieves the ID of the field relative to
      * the local pattern characters.
      */
-    public int getField()
+    int getField()
     {
       return field;
     }
@@ -121,7 +121,7 @@
     /**
      * Retrieves the size of the character sequence.
      */
-    public int getSize()
+    int getSize()
     {
       return size;
     }
@@ -129,7 +129,7 @@
     /**
      * Retrieves the character used in the sequence.
      */
-    public char getCharacter()
+    char getCharacter()
     {
       return character;
     }
@@ -560,7 +560,7 @@
    * @return a version of the pattern using the characters in
    *         <code>newChars</code>.
    */
-  private String translateLocalizedPattern(String pattern,
+  private static String translateLocalizedPattern(String pattern,
                                            String oldChars, String newChars)
   {
     int len = pattern.length();
@@ -865,7 +865,8 @@
                                        buf.getAttributes());
   }
 
-  private void withLeadingZeros(int value, int length, FormatBuffer buffer)
+  private static void withLeadingZeros(int value, int length,
+                                       FormatBuffer buffer)
   {
     String valStr = String.valueOf(value);
     for (length -= valStr.length(); length > 0; length--)
@@ -873,7 +874,7 @@
     buffer.append(valStr);
   }
 
-  private boolean expect(String source, ParsePosition pos, char ch)
+  private static boolean expect(String source, ParsePosition pos, char ch)
   {
     int x = pos.getIndex();
     boolean r = x < source.length() && source.charAt(x) == ch;
@@ -1111,21 +1112,25 @@
                 numberFormat.setMinimumIntegerDigits(fmt_count);
                 if (maybe2DigitYear)
                   index = pos.getIndex();
-                Number n = null;
-                if (limit_digits)
+                Number n;
+                if (limit_digits
+                    && dateStr.length() > pos.getIndex() + fmt_count)
                   {
                     // numberFormat.setMaximumIntegerDigits(fmt_count) may
                     // not work as expected. So we explicitly use substring
                     // of dateStr.
-                    int origPos = pos.getIndex();
-                    pos.setIndex(0);
-                    n = numberFormat.parse(dateStr.substring(origPos, origPos + fmt_count), pos);
-                    pos.setIndex(origPos + pos.getIndex());
+                    n = numberFormat.parse(dateStr.substring(0,
+                                            pos.getIndex() + fmt_count), pos);
                   }
                 else
                   n = numberFormat.parse(dateStr, pos);
-                if (pos == null || ! (n instanceof Long))
-                  return null;
+
+                if (!(n instanceof Long))
+                  {
+                    if (n != null) // set error index if not yet
+                      pos.setErrorIndex(pos.getIndex());
+                    return null;
+                  }
                 value = n.intValue() + offset;
               }
             else if (set1 != null)
@@ -1136,8 +1141,8 @@
                 for (i = offset; i < set1.length; ++i)
                   {
                     if (set1[i] != null)
-                      if (dateStr.toUpperCase().startsWith(set1[i].toUpperCase(),
-                                                           index))
+                      if (dateStr.regionMatches(true, index, set1[i], 0,
+                                                set1[i].length()))
                         {
                           found = true;
                           pos.setIndex(index + set1[i].length());
@@ -1149,8 +1154,8 @@
                     for (i = offset; i < set2.length; ++i)
                       {
                         if (set2[i] != null)
-                          if (dateStr.toUpperCase().startsWith(set2[i].toUpperCase(),
-                                                               index))
+                          if (dateStr.regionMatches(true, index, set2[i], 0,
+                                                set2[i].length()))
                             {
                               found = true;
                               pos.setIndex(index + set2[i].length());
@@ -1223,7 +1228,7 @@
    * <code>String</code> representation.
    * </p>
    * <p>
-   * The supplied <code>String</code> must be a three
+   * The supplied <code>String</code> must start with a three
    * or four digit signed number, with an optional 'GMT'
    * prefix.  The first one or two digits represents the hours,
    * while the last two represent the minutes.  The
@@ -1254,7 +1259,7 @@
    * @return the parsed offset, or null if parsing
    *         failed.
    */
-  private Integer computeOffset(String zoneString, ParsePosition pos)
+  private static Integer computeOffset(String zoneString, ParsePosition pos)
   {
     Pattern pattern =
       Pattern.compile("(GMT)?([+-])([012])?([0-9]):?([0-9]{2})");
@@ -1277,8 +1282,9 @@
       {
         int sign = matcher.group(2).equals("+") ? 1 : -1;
         int hour = Integer.parseInt(matcher.group(4));
-        if (!matcher.group(3).equals(""))
-          hour += (Integer.parseInt(matcher.group(3)) * 10);
+        String hourLeading = matcher.group(3);
+        if (hourLeading != null && hourLeading.length() > 0)
+          hour += Integer.parseInt(hourLeading) * 10;
         int minutes = Integer.parseInt(matcher.group(5));
 
         if (hour > 23)
