Merging releases/1.5 into trunk

svn merge -r3391:3505 https://google-web-toolkit.googlecode.com/svn/releases/1.5 .



git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@3506 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/GWTShell.java b/dev/core/src/com/google/gwt/dev/GWTShell.java
index 20d9a2d..663a4e8 100644
--- a/dev/core/src/com/google/gwt/dev/GWTShell.java
+++ b/dev/core/src/com/google/gwt/dev/GWTShell.java
@@ -151,8 +151,7 @@
         try {
           port = Integer.parseInt(value);
         } catch (NumberFormatException e) {
-          String msg = "A port must be an integer or \"auto\"";
-          getTopLogger().log(TreeLogger.ERROR, msg, null);
+          System.err.println("A port must be an integer or \"auto\"");
           return false;
         }
       }
diff --git a/dev/core/src/com/google/gwt/dev/cfg/DefaultPropertyProvider.java b/dev/core/src/com/google/gwt/dev/cfg/DefaultPropertyProvider.java
index c8274c5..b6f0e77 100644
--- a/dev/core/src/com/google/gwt/dev/cfg/DefaultPropertyProvider.java
+++ b/dev/core/src/com/google/gwt/dev/cfg/DefaultPropertyProvider.java
@@ -41,7 +41,7 @@
   public DefaultPropertyProvider(ModuleDef module, Property property) {
     super(module, property);
     String src = "function () {";
-    src += "return _gwt_getMetaProperty(\"";
+    src += "return __gwt_getMetaProperty(\"";
     src += property.getName();
     src += "\"); }";
     setBody(parseFunction(src));
diff --git a/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java b/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java
index 07d3d8c..f66bce6 100644
--- a/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java
+++ b/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java
@@ -26,7 +26,6 @@
 
 import java.io.File;
 import java.io.Reader;
-import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.HashSet;
@@ -210,7 +209,7 @@
             && (!(externalForm.startsWith("zip:file")))
             && (!(externalForm.startsWith("http://")))
             && (!(externalForm.startsWith("ftp://")))) {
-          File gwtXmlFile = new File(new URI(externalForm));
+          File gwtXmlFile = new File(moduleURL.toURI());
           moduleDef.addGwtXmlFile(gwtXmlFile);
         }
       } catch (URISyntaxException e) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JVisitor.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JVisitor.java
index 3929349..4d9bd7c 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JVisitor.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JVisitor.java
@@ -63,12 +63,13 @@
 
   protected static InternalCompilerException translateException(JNode node,
       Throwable e) {
+    if (e instanceof OutOfMemoryError) {
+      // Always rethrow OOMs (might have no memory to load ICE class anyway).
+      throw (OutOfMemoryError) e;
+    }
     InternalCompilerException ice;
     if (e instanceof InternalCompilerException) {
       ice = (InternalCompilerException) e;
-    } else if (e instanceof OutOfMemoryError) {
-      // Just rethrow, it's not our problem.
-      throw (OutOfMemoryError) e;
     } else {
       ice = new InternalCompilerException("Unexpected error during visit.", e);
     }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/AutoboxUtils.java b/dev/core/src/com/google/gwt/dev/jjs/impl/AutoboxUtils.java
index 4a2a06a..185dbad 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/AutoboxUtils.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/AutoboxUtils.java
@@ -16,6 +16,7 @@
 package com.google.gwt.dev.jjs.impl;
 
 import com.google.gwt.dev.jjs.InternalCompilerException;
+import com.google.gwt.dev.jjs.ast.JCastOperation;
 import com.google.gwt.dev.jjs.ast.JClassType;
 import com.google.gwt.dev.jjs.ast.JExpression;
 import com.google.gwt.dev.jjs.ast.JMethod;
@@ -48,10 +49,21 @@
     computeUnboxMethods();
   }
 
+  /**
+   * Box the expression <code>toBox</code> into an instance of
+   * <code>wrapperType</code>. If <code>toBox</code> is not already of the
+   * primitive corresponding to <code>wrapperType</code>, then a cast may be
+   * necessary.
+   */
   public JExpression box(JExpression toBox, JClassType wrapperType) {
     return box(toBox, primitiveTypeForBoxClass(wrapperType), wrapperType);
   }
 
+  /**
+   * Box the expression <code>toBox</code> into the wrapper type corresponding
+   * to <code>primitiveType</code>. If <code>toBox</code> is not already of
+   * type <code>primitiveType</code>, then a cast may be necessary.
+   */
   public JExpression box(JExpression toBox, JPrimitiveType primitiveType) {
     // Find the wrapper type for this primitive type.
     String wrapperTypeName = primitiveType.getWrapperTypeName();
@@ -66,8 +78,9 @@
   }
 
   /**
-   * Return the box class for a given primitive.  Note that this can return <code>null</code>
-   * if the source program does not actually need the requested box type.
+   * Return the box class for a given primitive. Note that this can return
+   * <code>null</code> if the source program does not actually need the
+   * requested box type.
    */
   public JClassType boxClassForPrimitive(JPrimitiveType prim) {
     return (JClassType) program.getFromTypeMap(prim.getWrapperTypeName());
@@ -89,6 +102,12 @@
 
   private JExpression box(JExpression toBox, JPrimitiveType primitiveType,
       JClassType wrapperType) {
+    // Add a cast to toBox if need be
+    if (toBox.getType() != primitiveType) {
+      toBox = new JCastOperation(program, toBox.getSourceInfo(), primitiveType,
+          toBox);
+    }
+
     // Find the correct valueOf() method.
     JMethod valueOfMethod = null;
     for (JMethod method : wrapperType.methods) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java b/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
index b6fb379..1c641a4 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
@@ -127,6 +127,10 @@
 
     private static InternalCompilerException translateException(
         AbstractMethodDeclaration amd, Throwable e) {
+      if (e instanceof OutOfMemoryError) {
+        // Always rethrow OOMs (might have no memory to load ICE class anyway).
+        throw (OutOfMemoryError) e;
+      }
       InternalCompilerException ice;
       if (e instanceof InternalCompilerException) {
         ice = (InternalCompilerException) e;
@@ -602,6 +606,9 @@
 
         typeDecls.add(typeDeclaration);
         return true;
+      } catch (OutOfMemoryError e) {
+        // Always rethrow OOMs (might have no memory to load ICE class anyway).
+        throw e;
       } catch (InternalCompilerException ice) {
         ice.addNode(type);
         throw ice;
@@ -747,6 +754,10 @@
 
     private InternalCompilerException translateException(Statement stmt,
         Throwable e) {
+      if (e instanceof OutOfMemoryError) {
+        // Always rethrow OOMs (might have no memory to load ICE class anyway).
+        throw (OutOfMemoryError) e;
+      }
       InternalCompilerException ice;
       if (e instanceof InternalCompilerException) {
         ice = (InternalCompilerException) e;
@@ -779,6 +790,10 @@
 
     private static InternalCompilerException translateException(
         TypeDeclaration typeDecl, Throwable e) {
+      if (e instanceof OutOfMemoryError) {
+        // Always rethrow OOMs (might have no memory to load ICE class anyway).
+        throw (OutOfMemoryError) e;
+      }
       InternalCompilerException ice;
       if (e instanceof InternalCompilerException) {
         ice = (InternalCompilerException) e;
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
index b47447d..4f9a305 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
@@ -220,6 +220,10 @@
 
     private static InternalCompilerException translateException(JNode node,
         Throwable e) {
+      if (e instanceof OutOfMemoryError) {
+        // Always rethrow OOMs (might have no memory to load ICE class anyway).
+        throw (OutOfMemoryError) e;
+      }
       InternalCompilerException ice;
       if (e instanceof InternalCompilerException) {
         ice = (InternalCompilerException) e;
@@ -453,29 +457,10 @@
       // Check if we need to box the resulting expression.
       if (x != null) {
         if ((x.implicitConversion & TypeIds.BOXING) != 0) {
-          /*
-           * Beware! Passing in "primitiveTypeToBox" seems unnecessary, but it
-           * isn't. You cannot determine the true type to box directly by
-           * calling result.getType() in all cases because sometimes, such as
-           * when the expression is originally a int literal prefixed with a
-           * narrowing cast, the processExpression() calls returns JIntLiterals
-           * even when the actual type should be byte or short. So, unless you
-           * remember what the original expression type was, you'd incorrectly
-           * box a byte as an Integer.
-           */
-          JType primitiveTypeToBox = (JType) typeMap.get(x.resolvedType);
-
-          if (!(primitiveTypeToBox instanceof JPrimitiveType)) {
-            throw new InternalCompilerException(result,
-                "Attempt to box a non-primitive type: "
-                    + primitiveTypeToBox.getName(), null);
-          }
-
-          result = autoboxUtils.box(result,
-              ((JPrimitiveType) primitiveTypeToBox));
+          result = autoboxUtils.box(result, implicitConversionTargetType(x));
         } else if ((x.implicitConversion & TypeIds.UNBOXING) != 0) {
           // This code can actually leave an unbox operation in
-          // an lvalue position, for example ++x.intValue().
+          // an lvalue position, for example ++(x.intValue()).
           // Such trees are cleaned up in FixAssignmentToUnbox.
           JType typeToUnbox = (JType) typeMap.get(x.resolvedType);
           if (!(typeToUnbox instanceof JClassType)) {
@@ -1612,6 +1597,11 @@
       // May need to box or unbox the element assignment.
       if (x.elementVariableImplicitWidening != -1) {
         if ((x.elementVariableImplicitWidening & TypeIds.BOXING) != 0) {
+          /*
+           * Boxing is necessary. In this special case of autoboxing, the boxed
+           * expression cannot be a constant, so the box type must be exactly
+           * that associated with the expression.
+           */
           elementDecl.initializer = autoboxUtils.box(elementDecl.initializer,
               ((JPrimitiveType) elementDecl.initializer.getType()));
         } else if ((x.elementVariableImplicitWidening & TypeIds.UNBOXING) != 0) {
@@ -2178,6 +2168,43 @@
       statements.add(new JReturnStatement(program, info, returnValue));
     }
 
+    /*
+     * Determine the destination type for an implicit conversion of the given
+     * expression. Beware that when autoboxing, the type of the expression is
+     * not necessarily the same as the type of the box to be created. The JDT
+     * figures out what the necessary conversion is, depending on the context
+     * the expression appears in, and stores it in <code>x.implicitConversion</code>,
+     * so extract it from there.
+     */
+    private JPrimitiveType implicitConversionTargetType(Expression x)
+        throws InternalCompilerException {
+      /*
+       * This algorithm for finding the target type is copied from
+       * org.eclipse.jdt.internal.compiler.codegen.CodeStream.generateReturnBytecode() .
+       */
+      switch ((x.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4) {
+        case TypeIds.T_boolean:
+          return program.getTypePrimitiveBoolean();
+        case TypeIds.T_byte:
+          return program.getTypePrimitiveByte();
+        case TypeIds.T_char:
+          return program.getTypePrimitiveChar();
+        case TypeIds.T_double:
+          return program.getTypePrimitiveDouble();
+        case TypeIds.T_float:
+          return program.getTypePrimitiveFloat();
+        case TypeIds.T_int:
+          return program.getTypePrimitiveInt();
+        case TypeIds.T_long:
+          return program.getTypePrimitiveLong();
+        case TypeIds.T_short:
+          return program.getTypePrimitiveShort();
+        default:
+          throw new InternalCompilerException(
+              "Could not determine the desired box type");
+      }
+    }
+
     private SourceInfo makeSourceInfo(Statement x) {
       int startLine = Util.getLineNumber(x.sourceStart,
           currentSeparatorPositions, 0, currentSeparatorPositions.length - 1);
@@ -2285,6 +2312,10 @@
 
     private InternalCompilerException translateException(Object node,
         Throwable e) {
+      if (e instanceof OutOfMemoryError) {
+        // Always rethrow OOMs (might have no memory to load ICE class anyway).
+        throw (OutOfMemoryError) e;
+      }
       InternalCompilerException ice;
       if (e instanceof InternalCompilerException) {
         ice = (InternalCompilerException) e;
diff --git a/dev/core/src/com/google/gwt/dev/js/JsToStringGenerationVisitor.java b/dev/core/src/com/google/gwt/dev/js/JsToStringGenerationVisitor.java
index 70f7b31..13fb936 100644
--- a/dev/core/src/com/google/gwt/dev/js/JsToStringGenerationVisitor.java
+++ b/dev/core/src/com/google/gwt/dev/js/JsToStringGenerationVisitor.java
@@ -1092,10 +1092,28 @@
     p.print(' ');
   }
 
+  /**
+   * Decide whether, if <code>op</code> is printed followed by
+   * <code>arg</code>, there needs to be a space between the operator and
+   * expression.
+   * 
+   * @return <code>true</code> if a space needs to be printed
+   */
   private boolean _spaceCalc(JsOperator op, JsExpression arg) {
     if (op.isKeyword()) {
       return true;
     }
+    if (arg instanceof JsBinaryOperation) {
+      JsBinaryOperation binary = (JsBinaryOperation) arg;
+      /*
+       * If the binary operation has a higher precedence than op, then it won't
+       * be parenthesized, so check the first argument of the binary operation.
+       */
+      if (binary.getOperator().getPrecedence() > op.getPrecedence()) {
+        return _spaceCalc(op, binary.getArg1());
+      }
+      return false;
+    }
     if (arg instanceof JsPrefixOperation) {
       JsOperator op2 = ((JsPrefixOperation) arg).getOperator();
       return (op == JsBinaryOperator.SUB || op == JsUnaryOperator.NEG)
diff --git a/dev/core/src/com/google/gwt/dev/js/ast/JsRootScope.java b/dev/core/src/com/google/gwt/dev/js/ast/JsRootScope.java
index 2f1a8e0..95ce00a 100644
--- a/dev/core/src/com/google/gwt/dev/js/ast/JsRootScope.java
+++ b/dev/core/src/com/google/gwt/dev/js/ast/JsRootScope.java
@@ -77,6 +77,7 @@
         // Common browser-defined identifiers not defined in ECMAScript
         "window", "document", "event", "location", "history", "external",
         "Debug", "Enumerator", "Global", "Image", "ActiveXObject", "VBArray",
+        "Components",
 
         // Functions commonly defined on Object
         "toString", "getClass",
diff --git a/dev/core/src/com/google/gwt/dev/js/ast/JsVisitor.java b/dev/core/src/com/google/gwt/dev/js/ast/JsVisitor.java
index d0ea60b..ffaf3dd 100644
--- a/dev/core/src/com/google/gwt/dev/js/ast/JsVisitor.java
+++ b/dev/core/src/com/google/gwt/dev/js/ast/JsVisitor.java
@@ -434,6 +434,10 @@
 
   private <T extends JsVisitable<T>> InternalCompilerException translateException(
       T node, Throwable e) {
+    if (e instanceof OutOfMemoryError) {
+      // Always rethrow OOMs (might have no memory to load ICE class anyway).
+      throw (OutOfMemoryError) e;
+    }
     InternalCompilerException ice;
     if (e instanceof InternalCompilerException) {
       ice = (InternalCompilerException) e;
diff --git a/dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java b/dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java
index 8f19fcd..814f9ac 100644
--- a/dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java
+++ b/dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java
@@ -24,7 +24,6 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLClassLoader;
@@ -117,10 +116,8 @@
 
   public static ClassPathEntry createEntryForUrl(TreeLogger logger, URL url)
       throws URISyntaxException, IOException {
-    String urlString = url.toString();
     if (url.getProtocol().equals("file")) {
-      URI uri = new URI(urlString);
-      File f = new File(uri);
+      File f = new File(url.toURI());
       String lowerCaseFileName = f.getName().toLowerCase();
       if (f.isDirectory()) {
         return new DirectoryClassPathEntry(f);
@@ -144,7 +141,7 @@
         return null;
       }
     } else {
-      logger.log(TreeLogger.WARN, "Unknown URL type for " + urlString, null);
+      logger.log(TreeLogger.WARN, "Unknown URL type for " + url, null);
       return null;
     }
   }
diff --git a/dev/core/src/com/google/gwt/dev/shell/tomcat/EmbeddedTomcatServer.java b/dev/core/src/com/google/gwt/dev/shell/tomcat/EmbeddedTomcatServer.java
index 8ee3cd6..022713c 100644
--- a/dev/core/src/com/google/gwt/dev/shell/tomcat/EmbeddedTomcatServer.java
+++ b/dev/core/src/com/google/gwt/dev/shell/tomcat/EmbeddedTomcatServer.java
@@ -44,6 +44,7 @@
 import java.net.ServerSocket;
 import java.net.URISyntaxException;
 import java.net.URL;
+import java.net.URLConnection;
 import java.util.Collections;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -277,13 +278,18 @@
       if (srcLastModified < dstLastModified) {
         // Don't copy over it.
         //
-        logger.log(TreeLogger.TRACE, "Source is older than existing: "
+        logger.log(TreeLogger.SPAM, "Source is older than existing: "
             + dest.getAbsolutePath(), null);
         return;
       } else if (srcLastModified == dstLastModified) {
         // Exact same time; quietly don't overwrite.
         //
         return;
+      } else if (dest.exists()) {
+        // Warn about the overwrite
+        logger.log(TreeLogger.WARN, "Overwriting existing file '"
+            + dest.getAbsolutePath() + "' with '" + resource.getLocation()
+            + "', which has a newer timestamp");
       }
 
       // Make dest directories as required.
diff --git a/dev/core/test/com/google/gwt/dev/js/JsToStringGenerationVisitorAccuracyTest.java b/dev/core/test/com/google/gwt/dev/js/JsToStringGenerationVisitorAccuracyTest.java
index e1bbd8a..66ba017 100644
--- a/dev/core/test/com/google/gwt/dev/js/JsToStringGenerationVisitorAccuracyTest.java
+++ b/dev/core/test/com/google/gwt/dev/js/JsToStringGenerationVisitorAccuracyTest.java
@@ -47,6 +47,18 @@
     doTest("var x = [a, (b, c), d]");
   }
 
+  public void testBinaryBinaryUnary() throws Exception {
+    // there needs to be a space between the subtraction and negation
+    doTest("var x = a - (-b / c)");
+    doTest("var x = a - (-b * c)");
+    doTest("var x = a - (-b % c)");
+  }
+
+  public void testBinaryConditionalUnary() throws Exception {
+    // the subtraction operator has to be separated from the negation
+    doTest("var x = a - (-b ? c : d)");
+  }
+
   public void testComplexConstruction() throws Exception {
     doTest("(new (new (a(({a : 'b', c : 'd'}),[1,2,3,x,y,z]))())())()");
   }
@@ -69,6 +81,14 @@
     doTest("(x--)-(-(--y))");
   }
 
+  public void testEmptyStatements() throws Exception {
+    doTest("function f() {if (x);}");
+    doTest("function f() {while (x);}");
+    doTest("function f() {label:;}");
+    doTest("function f() {for (i=0;i<n;i++);}");
+    doTest("function f() {for (var x in s);}");
+  }
+
   public void testFunctionDeclarationInvocation() throws Exception {
     doTest("(function () {})()");
   }
@@ -114,14 +134,6 @@
     doTest("var x = -(-(--y))");
   }
 
-  public void testEmptyStatements() throws Exception {
-    doTest("function f() {if (x);}");
-    doTest("function f() {while (x);}");
-    doTest("function f() {label:;}");
-    doTest("function f() {for (i=0;i<n;i++);}");
-    doTest("function f() {for (var x in s);}");
-  }
-
   private void doTest(String js) throws Exception {
     List<JsStatement> expected = parser.parse(new JsProgram().getScope(),
         new StringReader(js), 0);
diff --git a/eclipse/reference/code-museum/DefaultMuseum.launch b/eclipse/reference/code-museum/DefaultMuseum.launch
index 3c0cabf..063c7eb 100644
--- a/eclipse/reference/code-museum/DefaultMuseum.launch
+++ b/eclipse/reference/code-museum/DefaultMuseum.launch
@@ -20,5 +20,5 @@
 <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.GWTShell"/>
 <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-out www com.google.gwt.museum.DefaultMuseum/DefaultMuseum.html"/>
 <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="code-museum"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dgwt.devjar=&quot;/usr/local/jlabanca/gwt_all/latest/trunk/build/staging/gwt-linux-0.0.0/gwt-user.jar&quot;"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dgwt.devjar=&quot;/usr/local/google/jlabanca/gwt_all/gwt15/releases/1.5/build/staging/gwt-linux-0.0.0/gwt-user.jar&quot;"/>
 </launchConfiguration>
diff --git a/reference/code-museum/src/com/google/gwt/museum/SingleIssue.gwt.xml b/reference/code-museum/src/com/google/gwt/museum/SingleIssue.gwt.xml
index 758fd87..dc1f1f3 100644
--- a/reference/code-museum/src/com/google/gwt/museum/SingleIssue.gwt.xml
+++ b/reference/code-museum/src/com/google/gwt/museum/SingleIssue.gwt.xml
@@ -5,8 +5,8 @@
     <inherits name="com.google.gwt.user.theme.standard.StandardResources"/>
     
     <!-- Specify the app entry point class.                   -->
-    <entry-point class='com.google.gwt.museum.client.defaultmuseum.Issue1488'/>
+    <entry-point class='com.google.gwt.museum.client.defaultmuseum.Issue2703'/>
     <source path="client/common"/>
-    <source path="client/defaultmuseum" includes="Issue1488.java"/>
+    <source path="client/defaultmuseum" includes="Issue2703.java"/>
     <source path="client/viewer"/>
 </module>
diff --git a/user/src/com/google/gwt/dom/client/Node.java b/user/src/com/google/gwt/dom/client/Node.java
index f501ef9..cf7c211 100644
--- a/user/src/com/google/gwt/dom/client/Node.java
+++ b/user/src/com/google/gwt/dom/client/Node.java
@@ -50,7 +50,7 @@
    * @param newChild The node to add
    * @return The node added
    */
-  public final native Node appendChild(Node newChild) /*-{
+  public final native <T extends Node> T appendChild(T newChild) /*-{
     return this.appendChild(newChild);
   }-*/;
 
diff --git a/user/src/com/google/gwt/user/client/ui/FlowPanel.java b/user/src/com/google/gwt/user/client/ui/FlowPanel.java
index 8d45192..601bac7 100644
--- a/user/src/com/google/gwt/user/client/ui/FlowPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/FlowPanel.java
@@ -41,7 +41,7 @@
    */
   @Override
   public void add(Widget w) {
-    super.add(w, getElement());
+    add(w, getElement());
   }
 
   /**
@@ -53,6 +53,6 @@
    *           range
    */
   public void insert(Widget w, int beforeIndex) {
-    super.insert(w, getElement(), beforeIndex, true);
+    insert(w, getElement(), beforeIndex, true);
   }
 }
diff --git a/user/src/com/google/gwt/user/client/ui/Tree.java b/user/src/com/google/gwt/user/client/ui/Tree.java
index 7d92b6d..6ca71a7 100644
--- a/user/src/com/google/gwt/user/client/ui/Tree.java
+++ b/user/src/com/google/gwt/user/client/ui/Tree.java
@@ -503,15 +503,17 @@
 
     switch (eventType) {
       case Event.ONKEYDOWN:
-      case Event.ONKEYUP:
-      case Event.ONKEYPRESS: {
-        if (keyboardListeners != null) {
-          keyboardListeners.fireKeyboardEvent(this, event);
-        }
+      case Event.ONKEYUP: {
         if (isArrowKey(DOM.eventGetKeyCode(event))) {
           DOM.eventCancelBubble(event, true);
           DOM.eventPreventDefault(event);
         }
+      }
+      // Intentional fall through
+      case Event.ONKEYPRESS: {
+        if (keyboardListeners != null) {
+          keyboardListeners.fireKeyboardEvent(this, event);
+        }
         break;
       }
     }
diff --git a/user/src/com/google/gwt/user/client/ui/impl/RichTextAreaImplIE6.java b/user/src/com/google/gwt/user/client/ui/impl/RichTextAreaImplIE6.java
index 43cffb4..5f2b10c 100644
--- a/user/src/com/google/gwt/user/client/ui/impl/RichTextAreaImplIE6.java
+++ b/user/src/com/google/gwt/user/client/ui/impl/RichTextAreaImplIE6.java
@@ -40,7 +40,7 @@
       } 
       var elem = _this.@com.google.gwt.user.client.ui.impl.RichTextAreaImpl::elem;
       var doc = elem.contentWindow.document;
-      doc.write('<html><body CONTENTEDITABLE="true"></body></html>');
+      doc.contentEditable = true;
 
       // Send notification that the iframe has reached design mode.
       _this.@com.google.gwt.user.client.ui.impl.RichTextAreaImplStandard::onElementInitialized()();
diff --git a/user/super/com/google/gwt/emul/java/util/Collections.java b/user/super/com/google/gwt/emul/java/util/Collections.java
index 7ad66e8..50963d9 100644
--- a/user/super/com/google/gwt/emul/java/util/Collections.java
+++ b/user/super/com/google/gwt/emul/java/util/Collections.java
@@ -15,8 +15,6 @@
  */
 package java.util;
 
-import java.io.Serializable;
-
 /**
  * Utility methods that operate on collections. <a
  * href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collections.html">[Sun
@@ -104,10 +102,18 @@
       throw new UnsupportedOperationException();
     }
 
+    public boolean equals(Object o) {
+      return list.equals(o);
+    }
+
     public T get(int index) {
       return list.get(index);
     }
 
+    public int hashCode() {
+      return list.hashCode();
+    }
+
     public int indexOf(Object o) {
       return list.indexOf(o);
     }
@@ -781,8 +787,10 @@
     return new UnmodifiableCollection<T>(coll);
   }
 
-  public static <T> List<T> unmodifiableList(final List<? extends T> list) {
-    return new UnmodifiableList<T>(list);
+  public static <T> List<T> unmodifiableList(List<? extends T> list) {
+    return (list instanceof RandomAccess)
+        ? new UnmodifiableRandomAccessList<T>(list) : new UnmodifiableList<T>(
+            list);
   }
 
   public static <K, V> Map<K, V> unmodifiableMap(
@@ -790,7 +798,7 @@
     return new UnmodifiableMap<K, V>(map);
   }
 
-  public static <T> Set<T> unmodifiableSet(final Set<? extends T> set) {
+  public static <T> Set<T> unmodifiableSet(Set<? extends T> set) {
     return new UnmodifiableSet<T>(set);
   }
 
diff --git a/user/test/com/google/gwt/dev/jjs/test/AutoboxTest.java b/user/test/com/google/gwt/dev/jjs/test/AutoboxTest.java
index 6c481a3..2ca6119 100644
--- a/user/test/com/google/gwt/dev/jjs/test/AutoboxTest.java
+++ b/user/test/com/google/gwt/dev/jjs/test/AutoboxTest.java
@@ -99,6 +99,23 @@
   }
 
   /**
+   * JLS 5.2 has a special case for assignment of a constant to a variable of
+   * type Byte, Short, or Character. Such an assignment is allowed so long as
+   * the constant fits within the type's range. In such cases, the box type can
+   * be different from the type of the constant.
+   */
+  public void testBoxingDifferentType() {
+    Character c = 1;
+    assertEquals(Character.valueOf((char) 1), c);
+
+    Byte b = 2;
+    assertEquals(Byte.valueOf((byte) 2), b);
+
+    Short s = 3;
+    assertEquals(Short.valueOf((short) 3), s);
+  }
+
+  /**
    * Verify that .valueOf() methods return identical references for types within
    * certain ranges.
    */