Add DOM.asOld(Element) to avoid NPEs

Calling cast() to convert a dom.Element into a user.Element can
introduce a NullPointerException when null elements are allowed.  To
remedy this and make the type safety slightly stronger, add a
DOM.asOld() helper method to cast from dom.Element to user.Element,
and replace as many calls to cast() with it as possible.

Rather than try to be clever and only convert cast()s where it would
actually make a difference, I adopted a strict rule of just converting
as many as possible.  In particular, this reverts all calls to cast()
that were introduced by d91ce52a.

Change-Id: I8c7a05be0c70d544006ae7f6356f7a05027fa1f3
diff --git a/user/src/com/google/gwt/user/client/DOM.java b/user/src/com/google/gwt/user/client/DOM.java
index db90071..61cff42 100644
--- a/user/src/com/google/gwt/user/client/DOM.java
+++ b/user/src/com/google/gwt/user/client/DOM.java
@@ -517,7 +517,7 @@
    * @return the element from which the mouse pointer was moved
    */
   public static com.google.gwt.user.client.Element eventGetFromElement(Event evt) {
-    return impl.eventGetFromElement(evt).cast();
+    return asOld(impl.eventGetFromElement(evt));
   }
 
   /**
@@ -638,7 +638,7 @@
    * @return the element to which the mouse pointer was moved
    */
   public static com.google.gwt.user.client.Element eventGetToElement(Event evt) {
-    return impl.eventGetToElement(evt).cast();
+    return asOld(impl.eventGetToElement(evt));
   }
 
   /**
@@ -761,7 +761,7 @@
    *         exists
    */
   public static com.google.gwt.user.client.Element getCaptureElement() {
-    return sCaptureElem.cast();
+    return asOld(sCaptureElem);
   }
 
   /**
@@ -772,7 +772,7 @@
    * @return the n-th child element
    */
   public static com.google.gwt.user.client.Element getChild(Element parent, int index) {
-    return impl.getChild(parent, index).cast();
+    return asOld(impl.getChild(parent, index));
   }
 
   /**
@@ -818,7 +818,7 @@
    * @return the associated element, or <code>null</code> if none is found
    */
   public static com.google.gwt.user.client.Element getElementById(String id) {
-    return Document.get().getElementById(id).cast();
+    return asOld(Document.get().getElementById(id));
   }
 
   /**
@@ -889,7 +889,7 @@
    * @return the child element
    */
   public static com.google.gwt.user.client.Element getFirstChild(Element elem) {
-    return elem.getFirstChildElement().cast();
+    return asOld(elem.getFirstChildElement());
   }
 
   /**
@@ -971,7 +971,7 @@
    * @return the parent element
    */
   public static com.google.gwt.user.client.Element getParent(Element elem) {
-    return elem.getParentElement().cast();
+    return asOld(elem.getParentElement());
   }
 
   /**
@@ -1466,4 +1466,16 @@
     // Pass the event to the listener.
     listener.onBrowserEvent(evt);
   }
+
+  /**
+   * Provided as a convenient way to upcast values statically typed as
+   * {@link Element} to {@link com.google.gwt.user.client.Element}.
+   * For easier upgrades in the future, it's recommended that this function
+   * only be called within a <code>return</code> statement.
+   * <p>
+   * Does <em>not</em> throw a {@link NullPointerException} if elem is null.
+   */
+  public static com.google.gwt.user.client.Element asOld(Element elem) {
+    return (com.google.gwt.user.client.Element) elem;
+  }
 }
diff --git a/user/src/com/google/gwt/user/client/Element.java b/user/src/com/google/gwt/user/client/Element.java
index de9b439..d39be8e 100644
--- a/user/src/com/google/gwt/user/client/Element.java
+++ b/user/src/com/google/gwt/user/client/Element.java
@@ -23,12 +23,14 @@
  * created from, and can be accessed in JavaScript code as expected. This is
  * typically done by calling methods in the
  * {@link com.google.gwt.user.client.DOM} class.
- *
+ * <p>
  * As of GWT 2.6, users should use {@link com.google.gwt.dom.client.Element}
  * instead.  As an exception, some methods still return a <code>Element</code>
  * object for backwards compatibility (though this will change in a future
  * release), so overriding them will require returning an <code>Element</code>
  * object too.
+ *
+ * @see DOM#asOld
  */
 @Deprecated
 public class Element extends com.google.gwt.dom.client.Element {
diff --git a/user/src/com/google/gwt/user/client/ui/CellPanel.java b/user/src/com/google/gwt/user/client/ui/CellPanel.java
index 572eac1..7ed5758 100644
--- a/user/src/com/google/gwt/user/client/ui/CellPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/CellPanel.java
@@ -202,17 +202,17 @@
   }
 
   protected com.google.gwt.user.client.Element getBody() {
-    return body.cast();
+    return DOM.asOld(body);
   }
 
   protected com.google.gwt.user.client.Element getTable() {
-    return table.cast();
+    return DOM.asOld(table);
   }
 
   @SuppressWarnings("deprecation")
   protected void setCellHorizontalAlignment(Element td,
       HorizontalAlignmentConstant align) {
-    setCellHorizontalAlignment(td.<com.google.gwt.user.client.Element>cast(), align);
+    setCellHorizontalAlignment(DOM.asOld(td), align);
   }
 
   /**
@@ -228,7 +228,7 @@
   @SuppressWarnings("deprecation")
   protected void setCellVerticalAlignment(Element td,
       VerticalAlignmentConstant align) {
-    setCellVerticalAlignment(td.<com.google.gwt.user.client.Element>cast(), align);
+    setCellVerticalAlignment(DOM.asOld(td), align);
   }
 
   /**
diff --git a/user/src/com/google/gwt/user/client/ui/CheckBox.java b/user/src/com/google/gwt/user/client/ui/CheckBox.java
index a4644be..2feafe1 100644
--- a/user/src/com/google/gwt/user/client/ui/CheckBox.java
+++ b/user/src/com/google/gwt/user/client/ui/CheckBox.java
@@ -529,7 +529,7 @@
    * @param elem the new input element
    */
   protected void replaceInputElement(Element elem) {
-    replaceInputElement(elem.<com.google.gwt.user.client.Element>cast());
+    replaceInputElement(DOM.asOld(elem));
   }
 
   /**
diff --git a/user/src/com/google/gwt/user/client/ui/ComplexPanel.java b/user/src/com/google/gwt/user/client/ui/ComplexPanel.java
index ccca704..6989c8e 100644
--- a/user/src/com/google/gwt/user/client/ui/ComplexPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/ComplexPanel.java
@@ -84,7 +84,7 @@
    * @param container the element within which the child will be contained
    */
   protected void add(Widget child, Element container) {
-    add(child, container.<com.google.gwt.user.client.Element>cast());
+    add(child, DOM.asOld(container));
   }
 
   /**
@@ -179,8 +179,7 @@
    */
   protected void insert(Widget child, Element container, int beforeIndex,
       boolean domInsert) {
-    insert(child, container.<com.google.gwt.user.client.Element>cast(), beforeIndex,
-        domInsert);
+    insert(child, DOM.asOld(container), beforeIndex, domInsert);
   }
 
   /**
diff --git a/user/src/com/google/gwt/user/client/ui/DecoratedPopupPanel.java b/user/src/com/google/gwt/user/client/ui/DecoratedPopupPanel.java
index b98584d..7d48ffa 100644
--- a/user/src/com/google/gwt/user/client/ui/DecoratedPopupPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/DecoratedPopupPanel.java
@@ -15,6 +15,8 @@
  */
 package com.google.gwt.user.client.ui;
 
+import com.google.gwt.user.client.DOM;
+
 import java.util.Iterator;
 
 /**
@@ -185,6 +187,6 @@
    * @return the Element at the given row and cell
    */
   protected com.google.gwt.user.client.Element getCellElement(int row, int cell) {
-    return decPanel.getCellElement(row, cell).cast();
+    return DOM.asOld(decPanel.getCellElement(row, cell));
   }
 }
diff --git a/user/src/com/google/gwt/user/client/ui/DecoratorPanel.java b/user/src/com/google/gwt/user/client/ui/DecoratorPanel.java
index 4d9b661..bc3df4e 100644
--- a/user/src/com/google/gwt/user/client/ui/DecoratorPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/DecoratorPanel.java
@@ -192,11 +192,11 @@
   protected com.google.gwt.user.client.Element getCellElement(int row, int cell) {
     Element tr = DOM.getChild(tbody, row);
     Element td = DOM.getChild(tr, cell);
-    return DOM.getFirstChild(td).cast();
+    return DOM.asOld(DOM.getFirstChild(td));
   }
 
   @Override
   protected com.google.gwt.user.client.Element getContainerElement() {
-    return containerElem.cast();
+    return DOM.asOld(containerElem);
   }
 }
diff --git a/user/src/com/google/gwt/user/client/ui/Grid.java b/user/src/com/google/gwt/user/client/ui/Grid.java
index 355ffa3..176a2c9 100644
--- a/user/src/com/google/gwt/user/client/ui/Grid.java
+++ b/user/src/com/google/gwt/user/client/ui/Grid.java
@@ -16,6 +16,7 @@
 package com.google.gwt.user.client.ui;
 
 import com.google.gwt.dom.client.Element;
+import com.google.gwt.user.client.DOM;
 
 /**
  * A rectangular grid that can contain text, html, or a child
@@ -271,7 +272,7 @@
     // Add a non-breaking space to the TD. This ensures that the cell is
     // displayed.
     td.setInnerHTML("&nbsp;");
-    return td.cast();
+    return DOM.asOld(td);
   }
 
   /**
diff --git a/user/src/com/google/gwt/user/client/ui/HTMLPanel.java b/user/src/com/google/gwt/user/client/ui/HTMLPanel.java
index c05044b..a4301e2 100644
--- a/user/src/com/google/gwt/user/client/ui/HTMLPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/HTMLPanel.java
@@ -19,6 +19,7 @@
 import com.google.gwt.dom.client.Document;
 import com.google.gwt.dom.client.Element;
 import com.google.gwt.safehtml.shared.SafeHtml;
+import com.google.gwt.user.client.DOM;
 
 import java.util.Iterator;
 import java.util.NoSuchElementException;
@@ -186,7 +187,7 @@
    * @param toReplace the element to be replaced by the widget
    */
   public final void addAndReplaceElement(Widget widget, Element toReplace) {
-    addAndReplaceElement(widget, toReplace.<com.google.gwt.user.client.Element>cast());
+    addAndReplaceElement(widget, DOM.asOld(toReplace));
   }
 
   /**
@@ -311,7 +312,7 @@
    */
   public com.google.gwt.user.client.Element getElementById(String id) {
     Element elem = isAttached() ? Document.get().getElementById(id) : attachToDomAndGetElement(id);
-    return elem.cast();
+    return DOM.asOld(elem);
   }
 
   /**
diff --git a/user/src/com/google/gwt/user/client/ui/HTMLTable.java b/user/src/com/google/gwt/user/client/ui/HTMLTable.java
index b418aaa..b77b2e8 100644
--- a/user/src/com/google/gwt/user/client/ui/HTMLTable.java
+++ b/user/src/com/google/gwt/user/client/ui/HTMLTable.java
@@ -143,7 +143,7 @@
      * @return the cell's element.
      */
     public com.google.gwt.user.client.Element getElement() {
-      return getCellFormatter().getElement(rowIndex, cellIndex).cast();
+      return DOM.asOld(getCellFormatter().getElement(rowIndex, cellIndex));
     }
 
     /**
@@ -183,7 +183,7 @@
      */
     public com.google.gwt.user.client.Element getElement(int row, int column) {
       checkCellBounds(row, column);
-      return getCellElement(bodyElem, row, column).cast();
+      return DOM.asOld(getCellElement(bodyElem, row, column));
     }
 
     /**
@@ -385,7 +385,7 @@
      */
     protected com.google.gwt.user.client.Element ensureElement(int row, int column) {
       prepareCell(row, column);
-      return getCellElement(bodyElem, row, column).cast();
+      return DOM.asOld(getCellElement(bodyElem, row, column));
     }
 
     /**
@@ -468,7 +468,7 @@
      * @return the col element
      */
     public com.google.gwt.user.client.Element getElement(int column) {
-      return ensureColumn(column).cast();
+      return DOM.asOld(ensureColumn(column));
     }
 
     /**
@@ -613,7 +613,7 @@
      */
     public com.google.gwt.user.client.Element getElement(int row) {
       checkRowBounds(row);
-      return getRow(bodyElem, row).cast();
+      return DOM.asOld(getRow(bodyElem, row));
     }
 
     /**
@@ -722,12 +722,12 @@
      */
     protected com.google.gwt.user.client.Element ensureElement(int row) {
       prepareRow(row);
-      return getRow(bodyElem, row).cast();
+      return DOM.asOld(getRow(bodyElem, row));
     }
 
     @SuppressWarnings("deprecation")
     protected com.google.gwt.user.client.Element getRow(Element tbody, int row) {
-      return getRow(tbody.<com.google.gwt.user.client.Element>cast(), row);
+      return getRow(DOM.asOld(tbody), row);
     }
 
     /**
@@ -736,7 +736,7 @@
     @Deprecated
     protected com.google.gwt.user.client.Element getRow(
         com.google.gwt.user.client.Element tbody, int row) {
-      return impl.getRows(tbody).get(row).cast();
+      return DOM.asOld(impl.getRows(tbody).get(row));
     }
 
     /**
@@ -1264,7 +1264,7 @@
    * @return the newly created TD
    */
   protected com.google.gwt.user.client.Element createCell() {
-    return DOM.createTD().cast();
+    return DOM.createTD();
   }
 
   /**
@@ -1273,7 +1273,7 @@
    * @return the TBODY element
    */
   protected com.google.gwt.user.client.Element getBodyElement() {
-    return bodyElem.cast();
+    return DOM.asOld(bodyElem);
   }
 
   /**
@@ -1285,7 +1285,7 @@
    */
   @SuppressWarnings("deprecation")
   protected int getDOMCellCount(Element tableBody, int row) {
-    return getDOMCellCount(tableBody.<com.google.gwt.user.client.Element>cast(), row);
+    return getDOMCellCount(DOM.asOld(tableBody), row);
   }
 
   /**
@@ -1318,7 +1318,7 @@
 
   @SuppressWarnings("deprecation")
   protected int getDOMRowCount(Element tbody) {
-    return getDOMRowCount(tbody.<com.google.gwt.user.client.Element>cast());
+    return getDOMRowCount(DOM.asOld(tbody));
   }
 
   /**
@@ -1346,7 +1346,7 @@
         Element tr = DOM.getParent(td);
         Element body = DOM.getParent(tr);
         if (body == bodyElem) {
-          return td.cast();
+          return DOM.asOld(td);
         }
       }
       // If we run into this table's body, we're out of options.
@@ -1414,7 +1414,7 @@
    */
   @SuppressWarnings("deprecation")
   protected boolean internalClearCell(Element td, boolean clearInnerHTML) {
-    return internalClearCell(td.<com.google.gwt.user.client.Element>cast(), clearInnerHTML);
+    return internalClearCell(DOM.asOld(td), clearInnerHTML);
   }
 
   /**
diff --git a/user/src/com/google/gwt/user/client/ui/RenderablePanel.java b/user/src/com/google/gwt/user/client/ui/RenderablePanel.java
index b5cc978..c59eef1 100644
--- a/user/src/com/google/gwt/user/client/ui/RenderablePanel.java
+++ b/user/src/com/google/gwt/user/client/ui/RenderablePanel.java
@@ -21,6 +21,7 @@
 import com.google.gwt.dom.client.Element;
 import com.google.gwt.safehtml.shared.SafeHtml;
 import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
+import com.google.gwt.user.client.DOM;
 
 /**
  * EXPERIMENTAL and subject to change. Do not use this in production code.
@@ -97,7 +98,7 @@
    * @param toReplace the element to be replaced by the widget
    */
   public final void addAndReplaceElement(Widget widget, Element toReplace) {
-    addAndReplaceElement(widget, toReplace.<com.google.gwt.user.client.Element>cast());
+    addAndReplaceElement(widget, DOM.asOld(toReplace));
   }
 
   /**
diff --git a/user/src/com/google/gwt/user/client/ui/ScrollPanel.java b/user/src/com/google/gwt/user/client/ui/ScrollPanel.java
index daf3186..bf7d72c 100644
--- a/user/src/com/google/gwt/user/client/ui/ScrollPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/ScrollPanel.java
@@ -23,6 +23,7 @@
 import com.google.gwt.event.dom.client.ScrollHandler;
 import com.google.gwt.event.shared.HandlerRegistration;
 import com.google.gwt.touch.client.TouchScroller;
+import com.google.gwt.user.client.DOM;
 import com.google.gwt.user.client.Event;
 
 /**
@@ -45,7 +46,7 @@
    */
   public ScrollPanel() {
     this.scrollableElem = getElement();
-    this.containerElem = Document.get().createDivElement().cast();
+    this.containerElem = Document.get().createDivElement();
     scrollableElem.appendChild(containerElem);
     initialize();
   }
@@ -298,7 +299,7 @@
 
   @Override
   protected com.google.gwt.user.client.Element getContainerElement() {
-    return containerElem.cast();
+    return DOM.asOld(containerElem);
   }
 
   /**
@@ -308,7 +309,7 @@
    * @return the scrollable element
    */
   protected com.google.gwt.user.client.Element getScrollableElement() {
-    return scrollableElem.cast();
+    return DOM.asOld(scrollableElem);
   }
 
   @Override
diff --git a/user/src/com/google/gwt/user/client/ui/UIObject.java b/user/src/com/google/gwt/user/client/ui/UIObject.java
index e04fca1..6f5f49e 100644
--- a/user/src/com/google/gwt/user/client/ui/UIObject.java
+++ b/user/src/com/google/gwt/user/client/ui/UIObject.java
@@ -556,7 +556,7 @@
    */
   public com.google.gwt.user.client.Element getElement() {
     assert (element != null) : MISSING_ELEMENT_ERROR;
-    return element.cast();
+    return DOM.asOld(element);
   }
 
   /**
@@ -899,7 +899,7 @@
    * @param elem the object's element
    */
   protected final void setElement(Element elem) {
-    setElement(elem.<com.google.gwt.user.client.Element>cast());
+    setElement(DOM.asOld(elem));
   }
 
   /**