Performance improvements for ElementBuilder. Note that this change looks enormous, but most of the files contain trivial API changes.

The current version of ElementBuilder involves a lot of casting, which results in thousands of dynamic casts (runtime type checks) when building a large table.  This change removes most of the unnecessary casts.

All of the endXXX() methods now return void instead of a parameterized return value.  The parameterized return value must be cast, and rightfully so because its returning the type of the parent builder.  That results in a dynamic cast for every element in the structure.  In practice, it usually isn't necessary or practical to continue building after calling end().  I originally put in the return value figuring that some people might find it useful, but not at the expense of performance. Likewise, all of the startXXX() methods in DomBuilderImpl and HtmlBuilderImpl now return a builder directly instead of going through a generic start() method.  The generic start method had a parameterized return type, which forces a dynamic cast.

All arrays and Collections require a dynamic cast every time an element is added.  ElementBuilderImpl used two Lists to maintain the stack of builders and the stack of tagNames, and DomBuilderImpl used a List to maintain the Stack of Elements.  I created a simple linked list based stack called FastPeekStack that replaces both stacks in ElementBuilderImpl and does not require any dynamic casts.  I removed the stack completely in DomBuilderImpl and instead used calls to currentElement.getParentElement() to move back up the stack. Maps have the same problem, so I replaced the Maps used as caches in DomStylesBuilder and HtmlStylesBuilder with JavaScriptObjects, and I use native JSNI to manually put/get items on the map.

In many cases, there were unnecessary method calls that added to the total time. In all of the HtmlElementBuilder implementations, setting an attribute calls attribute(name,value), which escapes the name and value, even though the name is a constant and does not need to be escaped. The escape call requires five String.indexOf() checks. I added a package protected trustedAttribute(name, value) method that does not escape the name, but still escapes the value. In addition, the version of attribute that takes an integer value no longer converts the value to a string and escapes it.  We append the integer directly, as integers are safe html.

Finally, there are some bug fixes. ElementBuilderFactory#createCheckInput() is not ElementBuilderFactory#createCheckboxInput(), and it correctly sets the input type to "checkbox" instead of "check".

Review at http://gwt-code-reviews.appspot.com/1477801

Review by: rdcastro@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10450 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/javadoc/com/google/gwt/examples/dom/builder/ElementBuilderFactoryChainingExample.java b/user/javadoc/com/google/gwt/examples/dom/builder/ElementBuilderFactoryChainingExample.java
index 21936d6..625a846 100644
--- a/user/javadoc/com/google/gwt/examples/dom/builder/ElementBuilderFactoryChainingExample.java
+++ b/user/javadoc/com/google/gwt/examples/dom/builder/ElementBuilderFactoryChainingExample.java
@@ -52,8 +52,9 @@
      * must be the "parent" builder. endDiv() does not need the optional
      * argument because we are finished building the element.
      */
-    divBuilder.id("myId").title("This is a div").style().trustedBackgroundColor("red")
-        .<DivBuilder> endStyle().text("Hello World!").endDiv();
+    divBuilder.id("myId").title("This is a div");
+    divBuilder.style().trustedBackgroundColor("red").endStyle();
+    divBuilder.text("Hello World!").endDiv();
 
     // Get the element out of the builder.
     Element div = divBuilder.finish();
diff --git a/user/src/com/google/gwt/dom/builder/client/DomBuilderFactory.java b/user/src/com/google/gwt/dom/builder/client/DomBuilderFactory.java
index e242307..4c0c5f2 100644
--- a/user/src/com/google/gwt/dom/builder/client/DomBuilderFactory.java
+++ b/user/src/com/google/gwt/dom/builder/client/DomBuilderFactory.java
@@ -98,8 +98,8 @@
   }
 
   @Override
-  public InputBuilder createCheckInputBuilder() {
-    return impl().startCheckInput();
+  public InputBuilder createCheckboxInputBuilder() {
+    return impl().startCheckboxInput();
   }
 
   @Override
diff --git a/user/src/com/google/gwt/dom/builder/client/DomBuilderImpl.java b/user/src/com/google/gwt/dom/builder/client/DomBuilderImpl.java
index 916d6b4..280d9fb 100644
--- a/user/src/com/google/gwt/dom/builder/client/DomBuilderImpl.java
+++ b/user/src/com/google/gwt/dom/builder/client/DomBuilderImpl.java
@@ -29,9 +29,6 @@
 import com.google.gwt.dom.client.TableSectionElement;
 import com.google.gwt.safehtml.shared.SafeHtml;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * Implementation of methods in
  * {@link com.google.gwt.dom.builder.shared.ElementBuilderBase} used to render
@@ -94,51 +91,47 @@
   private DomUListBuilder uListBuilder;
   private DomVideoBuilder videoBuilder;
 
-  private Element root;
+  /**
+   * The root element of the DOM structure being built.
+   */
+  private Element rootElement;
 
   /**
-   * The element at the top of the stack.
-   * 
-   * With normal usage, the current element will be accessed repeatedly to add
-   * attributes and styles. We maintain the current element outside of the stack
-   * to avoid a list access on each operation.
+   * The element at the top of the stack. We use DOM manipulation to move up and
+   * down the stack.
    */
   private Element currentElement;
-  private final List<Element> stackElements = new ArrayList<Element>();
-
-  @Override
-  public ElementBuilderBase<?> end() {
-    ElementBuilderBase<?> builder = super.end();
-    popElement();
-    return builder;
-  }
 
   public DomAnchorBuilder startAnchor() {
     if (anchorBuilder == null) {
       anchorBuilder = new DomAnchorBuilder(this);
     }
-    return start(Document.get().createAnchorElement(), anchorBuilder);
+    start(Document.get().createAnchorElement(), anchorBuilder);
+    return anchorBuilder;
   }
 
   public DomAreaBuilder startArea() {
     if (areaBuilder == null) {
       areaBuilder = new DomAreaBuilder(this);
     }
-    return start(Document.get().createAreaElement(), areaBuilder);
+    start(Document.get().createAreaElement(), areaBuilder);
+    return areaBuilder;
   }
 
   public DomAudioBuilder startAudio() {
     if (audioBuilder == null) {
       audioBuilder = new DomAudioBuilder(this);
     }
-    return start(Document.get().createAudioElement(), audioBuilder);
+    start(Document.get().createAudioElement(), audioBuilder);
+    return audioBuilder;
   }
 
   public DomBaseBuilder startBase() {
     if (baseBuilder == null) {
       baseBuilder = new DomBaseBuilder(this);
     }
-    return start(Document.get().createBaseElement(), baseBuilder);
+    start(Document.get().createBaseElement(), baseBuilder);
+    return baseBuilder;
   }
 
   public DomQuoteBuilder startBlockQuote() {
@@ -149,14 +142,16 @@
     if (bodyBuilder == null) {
       bodyBuilder = new DomBodyBuilder(this);
     }
-    return start(Document.get().createElement("body"), bodyBuilder);
+    start(Document.get().createElement("body"), bodyBuilder);
+    return bodyBuilder;
   }
 
   public DomBRBuilder startBR() {
     if (brBuilder == null) {
       brBuilder = new DomBRBuilder(this);
     }
-    return start(Document.get().createBRElement(), brBuilder);
+    start(Document.get().createBRElement(), brBuilder);
+    return brBuilder;
   }
 
   public InputBuilder startButtonInput() {
@@ -167,10 +162,11 @@
     if (canvasBuilder == null) {
       canvasBuilder = new DomCanvasBuilder(this);
     }
-    return start(Document.get().createCanvasElement(), canvasBuilder);
+    start(Document.get().createCanvasElement(), canvasBuilder);
+    return canvasBuilder;
   }
 
-  public InputBuilder startCheckInput() {
+  public InputBuilder startCheckboxInput() {
     return startInput(Document.get().createCheckInputElement());
   }
 
@@ -183,21 +179,24 @@
   }
 
   public DomDivBuilder startDiv() {
-    return start(Document.get().createDivElement(), divBuilder);
+    start(Document.get().createDivElement(), divBuilder);
+    return divBuilder;
   }
 
   public DomDListBuilder startDList() {
     if (dListBuilder == null) {
       dListBuilder = new DomDListBuilder(this);
     }
-    return start(Document.get().createDLElement(), dListBuilder);
+    start(Document.get().createDLElement(), dListBuilder);
+    return dListBuilder;
   }
 
   public DomFieldSetBuilder startFieldSet() {
     if (fieldSetBuilder == null) {
       fieldSetBuilder = new DomFieldSetBuilder(this);
     }
-    return start(Document.get().createFieldSetElement(), fieldSetBuilder);
+    start(Document.get().createFieldSetElement(), fieldSetBuilder);
+    return fieldSetBuilder;
   }
 
   public InputBuilder startFileInput() {
@@ -208,21 +207,24 @@
     if (formBuilder == null) {
       formBuilder = new DomFormBuilder(this);
     }
-    return start(Document.get().createFormElement(), formBuilder);
+    start(Document.get().createFormElement(), formBuilder);
+    return formBuilder;
   }
 
   public DomFrameBuilder startFrame() {
     if (frameBuilder == null) {
       frameBuilder = new DomFrameBuilder(this);
     }
-    return start(Document.get().createFrameElement(), frameBuilder);
+    start(Document.get().createFrameElement(), frameBuilder);
+    return frameBuilder;
   }
 
   public DomFrameSetBuilder startFrameSet() {
     if (frameSetBuilder == null) {
       frameSetBuilder = new DomFrameSetBuilder(this);
     }
-    return start(Document.get().createFrameSetElement(), frameSetBuilder);
+    start(Document.get().createFrameSetElement(), frameSetBuilder);
+    return frameSetBuilder;
   }
 
   public DomHeadingBuilder startH1() {
@@ -253,7 +255,8 @@
     if (headBuilder == null) {
       headBuilder = new DomHeadBuilder(this);
     }
-    return start(Document.get().createHeadElement(), headBuilder);
+    start(Document.get().createHeadElement(), headBuilder);
+    return headBuilder;
   }
 
   public InputBuilder startHiddenInput() {
@@ -264,21 +267,24 @@
     if (hrBuilder == null) {
       hrBuilder = new DomHRBuilder(this);
     }
-    return start(Document.get().createHRElement(), hrBuilder);
+    start(Document.get().createHRElement(), hrBuilder);
+    return hrBuilder;
   }
 
   public DomIFrameBuilder startIFrame() {
     if (iFrameBuilder == null) {
       iFrameBuilder = new DomIFrameBuilder(this);
     }
-    return start(Document.get().createIFrameElement(), iFrameBuilder);
+    start(Document.get().createIFrameElement(), iFrameBuilder);
+    return iFrameBuilder;
   }
 
   public DomImageBuilder startImage() {
     if (imageBuilder == null) {
       imageBuilder = new DomImageBuilder(this);
     }
-    return start(Document.get().createImageElement(), imageBuilder);
+    start(Document.get().createImageElement(), imageBuilder);
+    return imageBuilder;
   }
 
   public InputBuilder startImageInput() {
@@ -289,78 +295,90 @@
    * Start an input using the specified InputElement.
    */
   public DomInputBuilder startInput(InputElement input) {
-    return start(input, inputBuilder);
+    start(input, inputBuilder);
+    return inputBuilder;
   }
 
   public DomLabelBuilder startLabel() {
     if (labelBuilder == null) {
       labelBuilder = new DomLabelBuilder(this);
     }
-    return start(Document.get().createLabelElement(), labelBuilder);
+    start(Document.get().createLabelElement(), labelBuilder);
+    return labelBuilder;
   }
 
   public DomLegendBuilder startLegend() {
     if (legendBuilder == null) {
       legendBuilder = new DomLegendBuilder(this);
     }
-    return start(Document.get().createLegendElement(), legendBuilder);
+    start(Document.get().createLegendElement(), legendBuilder);
+    return legendBuilder;
   }
 
   public DomLIBuilder startLI() {
-    return start(Document.get().createLIElement(), liBuilder);
+    start(Document.get().createLIElement(), liBuilder);
+    return liBuilder;
   }
 
   public DomLinkBuilder startLink() {
     if (linkBuilder == null) {
       linkBuilder = new DomLinkBuilder(this);
     }
-    return start(Document.get().createLinkElement(), linkBuilder);
+    start(Document.get().createLinkElement(), linkBuilder);
+    return linkBuilder;
   }
 
   public DomMapBuilder startMap() {
     if (mapBuilder == null) {
       mapBuilder = new DomMapBuilder(this);
     }
-    return start(Document.get().createMapElement(), mapBuilder);
+    start(Document.get().createMapElement(), mapBuilder);
+    return mapBuilder;
   }
 
   public DomMetaBuilder startMeta() {
     if (metaBuilder == null) {
       metaBuilder = new DomMetaBuilder(this);
     }
-    return start(Document.get().createMetaElement(), metaBuilder);
+    start(Document.get().createMetaElement(), metaBuilder);
+    return metaBuilder;
   }
 
   public DomOListBuilder startOList() {
     if (oListBuilder == null) {
       oListBuilder = new DomOListBuilder(this);
     }
-    return start(Document.get().createOLElement(), oListBuilder);
+    start(Document.get().createOLElement(), oListBuilder);
+    return oListBuilder;
   }
 
   public DomOptGroupBuilder startOptGroup() {
     if (optGroupBuilder == null) {
       optGroupBuilder = new DomOptGroupBuilder(this);
     }
-    return start(Document.get().createOptGroupElement(), optGroupBuilder);
+    start(Document.get().createOptGroupElement(), optGroupBuilder);
+    return optGroupBuilder;
   }
 
   public DomOptionBuilder startOption() {
-    return start(Document.get().createOptionElement(), optionBuilder);
+    start(Document.get().createOptionElement(), optionBuilder);
+    return optionBuilder;
   }
 
   public DomParagraphBuilder startParagraph() {
     if (paragraphBuilder == null) {
       paragraphBuilder = new DomParagraphBuilder(this);
     }
-    return start(Document.get().createPElement(), paragraphBuilder);
+    start(Document.get().createPElement(), paragraphBuilder);
+    return paragraphBuilder;
   }
 
   public DomParamBuilder startParam() {
     if (paramBuilder == null) {
       paramBuilder = new DomParamBuilder(this);
     }
-    return start(Document.get().createParamElement(), paramBuilder);
+    start(Document.get().createParamElement(), paramBuilder);
+    return paramBuilder;
   }
 
   public InputBuilder startPasswordInput() {
@@ -371,7 +389,8 @@
     if (preBuilder == null) {
       preBuilder = new DomPreBuilder(this);
     }
-    return start(Document.get().createPreElement(), preBuilder);
+    start(Document.get().createPreElement(), preBuilder);
+    return preBuilder;
   }
 
   public DomButtonBuilder startPushButton() {
@@ -398,32 +417,37 @@
     if (scriptBuilder == null) {
       scriptBuilder = new DomScriptBuilder(this);
     }
-    return start(Document.get().createScriptElement(), scriptBuilder);
+    start(Document.get().createScriptElement(), scriptBuilder);
+    return scriptBuilder;
   }
 
   public DomSelectBuilder startSelect() {
     if (selectBuilder == null) {
       selectBuilder = new DomSelectBuilder(this);
     }
-    return start(Document.get().createSelectElement(), selectBuilder);
+    start(Document.get().createSelectElement(), selectBuilder);
+    return selectBuilder;
   }
 
   public DomSourceBuilder startSource() {
     if (sourceBuilder == null) {
       sourceBuilder = new DomSourceBuilder(this);
     }
-    return start(Document.get().createSourceElement(), sourceBuilder);
+    start(Document.get().createSourceElement(), sourceBuilder);
+    return sourceBuilder;
   }
 
   public DomSpanBuilder startSpan() {
-    return start(Document.get().createSpanElement(), spanBuilder);
+    start(Document.get().createSpanElement(), spanBuilder);
+    return spanBuilder;
   }
 
   public DomStyleBuilder startStyle() {
     if (styleBuilder == null) {
       styleBuilder = new DomStyleBuilder(this);
     }
-    return start(Document.get().createStyleElement(), styleBuilder);
+    start(Document.get().createStyleElement(), styleBuilder);
+    return styleBuilder;
   }
 
   public DomButtonBuilder startSubmitButton() {
@@ -438,14 +462,16 @@
     if (tableBuilder == null) {
       tableBuilder = new DomTableBuilder(this);
     }
-    return start(Document.get().createTableElement(), tableBuilder);
+    start(Document.get().createTableElement(), tableBuilder);
+    return tableBuilder;
   }
 
   public DomTableCaptionBuilder startTableCaption() {
     if (tableCaptionBuilder == null) {
       tableCaptionBuilder = new DomTableCaptionBuilder(this);
     }
-    return start(Document.get().createCaptionElement(), tableCaptionBuilder);
+    start(Document.get().createCaptionElement(), tableCaptionBuilder);
+    return tableCaptionBuilder;
   }
 
   public DomTableSectionBuilder startTBody() {
@@ -453,14 +479,16 @@
   }
 
   public DomTableCellBuilder startTD() {
-    return start(Document.get().createTDElement(), tableCellBuilder);
+    start(Document.get().createTDElement(), tableCellBuilder);
+    return tableCellBuilder;
   }
 
   public DomTextAreaBuilder startTextArea() {
     if (textAreaBuilder == null) {
       textAreaBuilder = new DomTextAreaBuilder(this);
     }
-    return start(Document.get().createTextAreaElement(), textAreaBuilder);
+    start(Document.get().createTextAreaElement(), textAreaBuilder);
+    return textAreaBuilder;
   }
 
   public DomTableSectionBuilder startTFoot() {
@@ -468,7 +496,8 @@
   }
 
   public DomTableCellBuilder startTH() {
-    return start(Document.get().createTHElement(), tableCellBuilder);
+    start(Document.get().createTHElement(), tableCellBuilder);
+    return tableCellBuilder;
   }
 
   public DomTableSectionBuilder startTHead() {
@@ -476,21 +505,24 @@
   }
 
   public DomTableRowBuilder startTR() {
-    return start(Document.get().createTRElement(), tableRowBuilder);
+    start(Document.get().createTRElement(), tableRowBuilder);
+    return tableRowBuilder;
   }
 
   public DomUListBuilder startUList() {
     if (uListBuilder == null) {
       uListBuilder = new DomUListBuilder(this);
     }
-    return start(Document.get().createULElement(), uListBuilder);
+    start(Document.get().createULElement(), uListBuilder);
+    return uListBuilder;
   }
 
   public DomVideoBuilder startVideo() {
     if (videoBuilder == null) {
       videoBuilder = new DomVideoBuilder(this);
     }
-    return start(Document.get().createVideoElement(), videoBuilder);
+    start(Document.get().createVideoElement(), videoBuilder);
+    return videoBuilder;
   }
 
   @Override
@@ -505,7 +537,8 @@
      * IllegalArgumentException.
      */
     assertValidTagName(tagName);
-    return start(Document.get().createElement(tagName), elementBuilder);
+    start(Document.get().createElement(tagName), elementBuilder);
+    return elementBuilder;
   }
 
   @Override
@@ -520,17 +553,17 @@
 
   @Override
   protected void doEndStartTagImpl() {
-    // No-op.
+    popElement();
   }
 
   @Override
   protected void doEndTagImpl(String tagName) {
-    // No-op.
+    popElement();
   }
 
   @Override
   protected Element doFinishImpl() {
-    return root;
+    return rootElement;
   }
 
   @Override
@@ -590,20 +623,11 @@
     return startInput(Document.get().createTextInputElement());
   }
 
+  /**
+   * Pop to the previous element in the stack.
+   */
   private void popElement() {
-    Element toRet = getCurrentElement();
-    int itemCount = stackElements.size(); // Greater than or equal to one.
-    stackElements.remove(itemCount - 1);
-    if (itemCount == 1) {
-      currentElement = null;
-    } else {
-      currentElement = stackElements.get(itemCount - 2);
-    }
-  }
-
-  private void pushElement(Element e) {
-    stackElements.add(e);
-    currentElement = e;
+    currentElement = getCurrentElement().getParentElement();
   }
 
   /**
@@ -612,22 +636,20 @@
    * @param element the element to start
    * @param builder the builder used to builder the new element
    */
-  private <B extends ElementBuilderBase<?>> B start(Element element, B builder) {
+  private void start(Element element, ElementBuilderBase<?> builder) {
     onStart(element.getTagName(), builder);
 
     // Set the root element.
-    if (root == null) {
+    if (rootElement == null) {
       // This is the new root element.
-      root = element;
+      rootElement = element;
     } else {
       // Appending to the current element.
       getCurrentElement().appendChild(element);
     }
 
     // Add the element to the stack.
-    pushElement(element);
-
-    return builder;
+    currentElement = element;
   }
 
   /**
@@ -637,7 +659,8 @@
     if (buttonBuilder == null) {
       buttonBuilder = new DomButtonBuilder(this);
     }
-    return start(button, buttonBuilder);
+    start(button, buttonBuilder);
+    return buttonBuilder;
   }
 
   /**
@@ -647,7 +670,8 @@
     if (headingBuilder == null) {
       headingBuilder = new DomHeadingBuilder(this);
     }
-    return start(Document.get().createHElement(level), headingBuilder);
+    start(Document.get().createHElement(level), headingBuilder);
+    return headingBuilder;
   }
 
   /**
@@ -657,7 +681,8 @@
     if (quoteBuilder == null) {
       quoteBuilder = new DomQuoteBuilder(this);
     }
-    return start(quote, quoteBuilder);
+    start(quote, quoteBuilder);
+    return quoteBuilder;
   }
 
   /**
@@ -667,7 +692,8 @@
     if (tableColBuilder == null) {
       tableColBuilder = new DomTableColBuilder(this);
     }
-    return start(element, tableColBuilder);
+    start(element, tableColBuilder);
+    return tableColBuilder;
   }
 
   /**
@@ -677,6 +703,7 @@
     if (tableSectionBuilder == null) {
       tableSectionBuilder = new DomTableSectionBuilder(this);
     }
-    return start(section, tableSectionBuilder);
+    start(section, tableSectionBuilder);
+    return tableSectionBuilder;
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/client/DomElementBuilderBase.java b/user/src/com/google/gwt/dom/builder/client/DomElementBuilderBase.java
index 6978f7e..94e03e6 100644
--- a/user/src/com/google/gwt/dom/builder/client/DomElementBuilderBase.java
+++ b/user/src/com/google/gwt/dom/builder/client/DomElementBuilderBase.java
@@ -105,6 +105,12 @@
   }
 
   @Override
+  public R attribute(String name, int value) {
+    assertCanAddAttribute().setAttribute(name, String.valueOf(value));
+    return getReturnBuilder();
+  }
+
+  @Override
   public R attribute(String name, String value) {
     assertCanAddAttribute().setAttribute(name, value);
     return getReturnBuilder();
@@ -186,8 +192,8 @@
   }
 
   @Override
-  public InputBuilder startCheckInput() {
-    return delegate.startCheckInput();
+  public InputBuilder startCheckboxInput() {
+    return delegate.startCheckboxInput();
   }
 
   @Override
diff --git a/user/src/com/google/gwt/dom/builder/client/DomStylesBuilder.java b/user/src/com/google/gwt/dom/builder/client/DomStylesBuilder.java
index 8a24120..b8d01e3 100644
--- a/user/src/com/google/gwt/dom/builder/client/DomStylesBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/client/DomStylesBuilder.java
@@ -15,7 +15,7 @@
  */
 package com.google.gwt.dom.builder.client;
 
-import com.google.gwt.dom.builder.shared.ElementBuilderBase;
+import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.dom.builder.shared.StylesBuilder;
 import com.google.gwt.dom.client.Style.BorderStyle;
 import com.google.gwt.dom.client.Style.Cursor;
@@ -35,9 +35,6 @@
 import com.google.gwt.regexp.shared.RegExp;
 import com.google.gwt.safehtml.shared.SafeUri;
 
-import java.util.HashMap;
-import java.util.Map;
-
 /**
  * Builds the style object.
  */
@@ -49,8 +46,11 @@
    * The set of style property names is limited, and common ones are reused
    * frequently, so caching saves us from converting every style property name
    * from hyphenated to camelCase form.
+   * 
+   * Use a {@link JavaScriptObject} to avoid the dynamic casts associated with
+   * the emulated version of {@link java.util.Map}.
    */
-  private static Map<String, String> hyphenatedMap;
+  private static JavaScriptObject hyphenatedMap;
 
   /**
    * Regex to match a word in a hyphenated phrase. A word starts with an a
@@ -70,7 +70,7 @@
   static String toCamelCaseForm(String name) {
     // Static initializers.
     if (hyphenatedMap == null) {
-      hyphenatedMap = new HashMap<String, String>();
+      hyphenatedMap = JavaScriptObject.createObject();
       maybeHyphenatedWord = RegExp.compile("([-]?)([a-z])([a-z0-9]*)", "g");
     }
 
@@ -80,7 +80,7 @@
     }
 
     // Check for the name in the cache.
-    String camelCase = hyphenatedMap.get(name);
+    String camelCase = getCamelCaseName(hyphenatedMap, name);
 
     // Convert the name to camelCase format if not in the cache.
     if (camelCase == null) {
@@ -108,12 +108,32 @@
           }
         }
       }
-      hyphenatedMap.put(name, camelCase);
+      putCamelCaseName(hyphenatedMap, name, camelCase);
     }
 
     return camelCase;
   }
 
+  /**
+   * Get the camelCase form of a style name to a map.
+   * 
+   * @param name the user specified style name
+   * @return the camelCase name, or null if not set
+   */
+  private static native String getCamelCaseName(JavaScriptObject map, String name) /*-{
+    return map[name] || null;
+  }-*/;
+
+  /**
+   * Save the camelCase form of a style name to a map.
+   * 
+   * @param name the user specified style name
+   * @param camelCase the camelCase name
+   */
+  private static native void putCamelCaseName(JavaScriptObject map, String name, String camelCase) /*-{
+    map[name] = camelCase;
+  }-*/;
+
   private final DomBuilderImpl delegate;
 
   /**
@@ -161,10 +181,9 @@
     return this;
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endStyle() {
-    return (B) delegate.endStyle();
+  public void endStyle() {
+    delegate.endStyle();
   }
 
   @Override
diff --git a/user/src/com/google/gwt/dom/builder/shared/AbstractElementBuilderBase.java b/user/src/com/google/gwt/dom/builder/shared/AbstractElementBuilderBase.java
index d212f8f..ff2b658 100644
--- a/user/src/com/google/gwt/dom/builder/shared/AbstractElementBuilderBase.java
+++ b/user/src/com/google/gwt/dom/builder/shared/AbstractElementBuilderBase.java
@@ -84,370 +84,310 @@
 
   private final ElementBuilderImpl delegate;
   private final boolean isEndTagForbidden;
+  private final R returnBuilder;
 
+  @SuppressWarnings("unchecked")
   protected AbstractElementBuilderBase(ElementBuilderImpl delegate, boolean isEndTagForbidden) {
     this.delegate = delegate;
     this.isEndTagForbidden = isEndTagForbidden;
+
+    // Cache the return builder to avoid repeated cast checks.
+    this.returnBuilder = (R) this;
   }
 
   @Override
-  public R attribute(String name, int value) {
-    return attribute(name, String.valueOf(value));
+  public void end() {
+    delegate.end();
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B end() {
-    // An explicit cast is required to satisfy some javac compilers.
-    return (B) delegate.end();
+  public void end(String tagName) {
+    delegate.end(tagName);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B end(String tagName) {
-    return (B) delegate.end(tagName);
+  public void endAnchor() {
+    end(AnchorElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endAnchor() {
-    return (B) end(AnchorElement.TAG);
+  public void endArea() {
+    end(AreaElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endArea() {
-    return (B) end(AreaElement.TAG);
+  public void endAudio() {
+    end(AudioElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endAudio() {
-    return (B) end(AudioElement.TAG);
+  public void endBase() {
+    end(BaseElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endBase() {
-    return (B) end(BaseElement.TAG);
+  public void endBlockQuote() {
+    end(QuoteElement.TAG_BLOCKQUOTE);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endBlockQuote() {
-    return (B) end(QuoteElement.TAG_BLOCKQUOTE);
+  public void endBody() {
+    end(BodyElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endBody() {
-    return (B) end(BodyElement.TAG);
+  public void endBR() {
+    end(BRElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endBR() {
-    return (B) end(BRElement.TAG);
+  public void endButton() {
+    end(ButtonElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endButton() {
-    return (B) end(ButtonElement.TAG);
+  public void endCanvas() {
+    end(CanvasElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endCanvas() {
-    return (B) end(CanvasElement.TAG);
+  public void endCol() {
+    end(TableColElement.TAG_COL);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endCol() {
-    return (B) end(TableColElement.TAG_COL);
+  public void endColGroup() {
+    end(TableColElement.TAG_COLGROUP);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endColGroup() {
-    return (B) end(TableColElement.TAG_COLGROUP);
+  public void endDiv() {
+    end(DivElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endDiv() {
-    return (B) end(DivElement.TAG);
+  public void endDList() {
+    end(DListElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endDList() {
-    return (B) end(DListElement.TAG);
+  public void endFieldSet() {
+    end(FieldSetElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endFieldSet() {
-    return (B) end(FieldSetElement.TAG);
+  public void endForm() {
+    end(FormElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endForm() {
-    return (B) end(FormElement.TAG);
+  public void endFrame() {
+    end(FrameElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endFrame() {
-    return (B) end(FrameElement.TAG);
+  public void endFrameSet() {
+    end(FrameSetElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endFrameSet() {
-    return (B) end(FrameSetElement.TAG);
+  public void endH1() {
+    end(HeadingElement.TAG_H1);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endH1() {
-    return (B) end(HeadingElement.TAG_H1);
+  public void endH2() {
+    end(HeadingElement.TAG_H2);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endH2() {
-    return (B) end(HeadingElement.TAG_H2);
+  public void endH3() {
+    end(HeadingElement.TAG_H3);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endH3() {
-    return (B) end(HeadingElement.TAG_H3);
+  public void endH4() {
+    end(HeadingElement.TAG_H4);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endH4() {
-    return (B) end(HeadingElement.TAG_H4);
+  public void endH5() {
+    end(HeadingElement.TAG_H5);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endH5() {
-    return (B) end(HeadingElement.TAG_H5);
+  public void endH6() {
+    end(HeadingElement.TAG_H6);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endH6() {
-    return (B) end(HeadingElement.TAG_H6);
+  public void endHead() {
+    end(HeadElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endHead() {
-    return (B) end(HeadElement.TAG);
+  public void endHR() {
+    end(HRElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endHR() {
-    return (B) end(HRElement.TAG);
+  public void endIFrame() {
+    end(IFrameElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endIFrame() {
-    return (B) end(IFrameElement.TAG);
+  public void endImage() {
+    end(ImageElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endImage() {
-    return (B) end(ImageElement.TAG);
+  public void endInput() {
+    end(InputElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endInput() {
-    return (B) end(InputElement.TAG);
+  public void endLabel() {
+    end(LabelElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endLabel() {
-    return (B) end(LabelElement.TAG);
+  public void endLegend() {
+    end(LegendElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endLegend() {
-    return (B) end(LegendElement.TAG);
+  public void endLI() {
+    end(LIElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endLI() {
-    return (B) end(LIElement.TAG);
+  public void endLink() {
+    end(LinkElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endLink() {
-    return (B) end(LinkElement.TAG);
+  public void endMap() {
+    end(MapElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endMap() {
-    return (B) end(MapElement.TAG);
+  public void endMeta() {
+    end(MetaElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endMeta() {
-    return (B) end(MetaElement.TAG);
+  public void endOList() {
+    end(OListElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endOList() {
-    return (B) end(OListElement.TAG);
+  public void endOptGroup() {
+    end(OptGroupElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endOptGroup() {
-    return (B) end(OptGroupElement.TAG);
+  public void endOption() {
+    end(OptionElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endOption() {
-    return (B) end(OptionElement.TAG);
+  public void endParagraph() {
+    end(ParagraphElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endParagraph() {
-    return (B) end(ParagraphElement.TAG);
+  public void endParam() {
+    end(ParamElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endParam() {
-    return (B) end(ParamElement.TAG);
+  public void endPre() {
+    end(PreElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endPre() {
-    return (B) end(PreElement.TAG);
+  public void endQuote() {
+    end(QuoteElement.TAG_Q);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endQuote() {
-    return (B) end(QuoteElement.TAG_Q);
+  public void endScript() {
+    end(ScriptElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endScript() {
-    return (B) end(ScriptElement.TAG);
+  public void endSelect() {
+    end(SelectElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endSelect() {
-    return (B) end(SelectElement.TAG);
+  public void endSource() {
+    end(SourceElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endSource() {
-    return (B) end(SourceElement.TAG);
+  public void endSpan() {
+    end(SpanElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endSpan() {
-    return (B) end(SpanElement.TAG);
+  public void endStyle() {
+    end(StyleElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endStyle() {
-    return (B) end(StyleElement.TAG);
+  public void endTable() {
+    end(TableElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endTable() {
-    return (B) end(TableElement.TAG);
+  public void endTableCaption() {
+    end(TableCaptionElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endTableCaption() {
-    return (B) end(TableCaptionElement.TAG);
+  public void endTBody() {
+    end(TableSectionElement.TAG_TBODY);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endTBody() {
-    return (B) end(TableSectionElement.TAG_TBODY);
+  public void endTD() {
+    end(TableCellElement.TAG_TD);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endTD() {
-    return (B) end(TableCellElement.TAG_TD);
+  public void endTextArea() {
+    end(TextAreaElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endTextArea() {
-    return (B) end(TextAreaElement.TAG);
+  public void endTFoot() {
+    end(TableSectionElement.TAG_TFOOT);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endTFoot() {
-    return (B) end(TableSectionElement.TAG_TFOOT);
+  public void endTH() {
+    end(TableCellElement.TAG_TH);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endTH() {
-    return (B) end(TableCellElement.TAG_TH);
+  public void endTHead() {
+    end(TableSectionElement.TAG_THEAD);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endTHead() {
-    return (B) end(TableSectionElement.TAG_THEAD);
+  public void endTR() {
+    end(TableRowElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endTR() {
-    return (B) end(TableRowElement.TAG);
+  public void endUList() {
+    end(UListElement.TAG);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endUList() {
-    return (B) end(UListElement.TAG);
-  }
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public <B extends ElementBuilderBase<?>> B endVideo() {
-    return (B) end(VideoElement.TAG);
+  public void endVideo() {
+    end(VideoElement.TAG);
   }
 
   @Override
@@ -487,8 +427,7 @@
    * 
    * @return the return builder
    */
-  @SuppressWarnings("unchecked")
   protected R getReturnBuilder() {
-    return (R) this;
+    return returnBuilder;
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/ElementBuilderBase.java b/user/src/com/google/gwt/dom/builder/shared/ElementBuilderBase.java
index 498159d..29e8966 100644
--- a/user/src/com/google/gwt/dom/builder/shared/ElementBuilderBase.java
+++ b/user/src/com/google/gwt/dom/builder/shared/ElementBuilderBase.java
@@ -69,793 +69,473 @@
 
   /**
    * End the current element without checking its type.
-   * 
-   * <p>
-   * By default, this method returns the {@link ElementBuilderBase} instance for
-   * the parent element, or null if this is the root element.
-   * </p>
-   * 
-   * <pre>
-   * DivBuilder div = ElementBuilderFactory.get().createDivBuilder();
-   * SelectBuilder select = div.startSelect();
-   * ElementBuilderBase&lt;?&gt; sameAs_div = select.end();
-   * </pre>
-   * 
-   * <p>
-   * You can cast the return type by parameterizing the return value. If the
-   * parameterized type does not match the builder type of this element's
-   * parent, a {@link ClassCastException} is thrown.
-   * </p>
-   * 
-   * <pre>
-   * DivBuilder div = ElementBuilderFactory.get().createDivBuilder();
-   * SelectBuilder select = div.startSelect();
-   * DivBuilder sameAs_div = select.&lt;DivBuilder&gt;end();
-   * </pre>
-   * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
-   * @throws ClassCastException if the return type does not match the builder
-   *           type of this element's parent
    */
-  <B extends ElementBuilderBase<?>> B end();
+  void end();
 
   /**
    * End the current element after checking that its tag is the specified
    * tagName.
    * 
    * @param tagName the expected tagName of the current element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
-   * @throws IllegalStateException if the current element does not match the
-   *           expected tagName
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B end(String tagName);
+  void end(String tagName);
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endAnchor();
+  void endAnchor();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endArea();
+  void endArea();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endAudio();
+  void endAudio();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endBase();
+  void endBase();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endBlockQuote();
+  void endBlockQuote();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endBody();
+  void endBody();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endBR();
+  void endBR();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endButton();
+  void endButton();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endCanvas();
+  void endCanvas();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endCol();
+  void endCol();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endColGroup();
+  void endColGroup();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endDiv();
+  void endDiv();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endDList();
+  void endDList();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endFieldSet();
+  void endFieldSet();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endForm();
+  void endForm();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endFrame();
+  void endFrame();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endFrameSet();
+  void endFrameSet();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endH1();
+  void endH1();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endH2();
+  void endH2();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endH3();
+  void endH3();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endH4();
+  void endH4();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endH5();
+  void endH5();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endH6();
+  void endH6();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endHead();
+  void endHead();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endHR();
+  void endHR();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endIFrame();
+  void endIFrame();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endImage();
+  void endImage();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endInput();
+  void endInput();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endLabel();
+  void endLabel();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endLegend();
+  void endLegend();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endLI();
+  void endLI();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endLink();
+  void endLink();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endMap();
+  void endMap();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endMeta();
+  void endMeta();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endOList();
+  void endOList();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endOptGroup();
+  void endOptGroup();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endOption();
+  void endOption();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endParagraph();
+  void endParagraph();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endParam();
+  void endParam();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endPre();
+  void endPre();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endQuote();
+  void endQuote();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endScript();
+  void endScript();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endSelect();
+  void endSelect();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endSource();
+  void endSource();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endSpan();
+  void endSpan();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endStyle();
+  void endStyle();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endTable();
+  void endTable();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endTableCaption();
+  void endTableCaption();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endTBody();
+  void endTBody();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endTD();
+  void endTD();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endTextArea();
+  void endTextArea();
+
+  /**
+   * End the current element. . *
+   * 
+   * @throws IllegalStateException if the current element has the wrong tag
+   * @see #end()
+   */
+  void endTFoot();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endTFoot();
+  void endTH();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endTH();
+  void endTHead();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endTHead();
+  void endTR();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endTR();
+  void endUList();
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
    * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  <B extends ElementBuilderBase<?>> B endUList();
-
-  /**
-   * End the current element.
-   * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
-   * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
-   * @see #end()
-   */
-  <B extends ElementBuilderBase<?>> B endVideo();
+  void endVideo();
 
   /**
    * Return the built DOM as an {@link Element}.
@@ -980,7 +660,7 @@
    * 
    * @return the builder for the new element
    */
-  InputBuilder startCheckInput();
+  InputBuilder startCheckboxInput();
 
   /**
    * Append a tablecol element.
diff --git a/user/src/com/google/gwt/dom/builder/shared/ElementBuilderFactory.java b/user/src/com/google/gwt/dom/builder/shared/ElementBuilderFactory.java
index 28d396b..31da8b1 100644
--- a/user/src/com/google/gwt/dom/builder/shared/ElementBuilderFactory.java
+++ b/user/src/com/google/gwt/dom/builder/shared/ElementBuilderFactory.java
@@ -135,7 +135,7 @@
 
   public abstract CanvasBuilder createCanvasBuilder();
 
-  public abstract InputBuilder createCheckInputBuilder();
+  public abstract InputBuilder createCheckboxInputBuilder();
 
   public abstract TableColBuilder createColBuilder();
 
diff --git a/user/src/com/google/gwt/dom/builder/shared/ElementBuilderImpl.java b/user/src/com/google/gwt/dom/builder/shared/ElementBuilderImpl.java
index e70fc7f..5591afa 100644
--- a/user/src/com/google/gwt/dom/builder/shared/ElementBuilderImpl.java
+++ b/user/src/com/google/gwt/dom/builder/shared/ElementBuilderImpl.java
@@ -20,9 +20,6 @@
 import com.google.gwt.regexp.shared.RegExp;
 import com.google.gwt.safehtml.shared.SafeHtml;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * Base implementation of {@link ElementBuilderBase} that handles state, but
  * nothing else.
@@ -41,6 +38,83 @@
 public abstract class ElementBuilderImpl {
 
   /**
+   * A node in the builder stack.
+   */
+  private static class StackNode {
+    private final ElementBuilderBase<?> builder;
+    private StackNode next;
+    private final String tagName;
+
+    public StackNode(String tagName, ElementBuilderBase<?> builder) {
+      this.builder = builder;
+      this.tagName = tagName;
+    }
+  }
+
+  /**
+   * A stack that allows quick access to its top element.
+   * 
+   * <p>
+   * FastPeekStack is implemented using a simple linked list of nodes to avoid
+   * the dynamic casts associated with the emulated version of
+   * {@link java.util.ArrayList}. When constructing a large DOM structure, such
+   * as a table, the dynamic casts in ArrayList can significantly degrade
+   * performance.
+   * </p>
+   */
+  private class FastPeekStack {
+
+    private static final String EMPTY_STACK_MESSAGE = "There are no elements on the stack.";
+
+    /**
+     * The top item in the stack.
+     */
+    private StackNode top;
+
+    public boolean isEmpty() {
+      return (top == null);
+    }
+
+    public StackNode peek() {
+      assertNotEmpty();
+      return top;
+    }
+
+    /**
+     * Pop the current {@link StackNode} and return it.
+     * 
+     * <p>
+     * The popped node will be recycled and should not be saved.
+     * </p>
+     * 
+     * @return the popped node
+     */
+    public StackNode pop() {
+      assertNotEmpty();
+      StackNode toRet = top;
+      top = top.next;
+      return toRet;
+    }
+
+    public void push(ElementBuilderBase<?> builder, String tagName) {
+      StackNode node = new StackNode(tagName, builder);
+      node.next = top;
+      top = node;
+    }
+
+    /**
+     * Assert that the stack is not empty.
+     * 
+     * @throws IllegalStateException if empty
+     */
+    private void assertNotEmpty() {
+      if (isEmpty()) {
+        throw new IllegalStateException(EMPTY_STACK_MESSAGE);
+      }
+    }
+  }
+
+  /**
    * A regex for matching valid HTML tags.
    */
   private static RegExp HTML_TAG_REGEX;
@@ -76,12 +150,7 @@
   /**
    * The stack of element builders.
    */
-  private final List<ElementBuilderBase<?>> stackBuilders = new ArrayList<ElementBuilderBase<?>>();
-
-  /**
-   * The stack of tag names.
-   */
-  private final List<String> stackTags = new ArrayList<String>();
+  private final FastPeekStack stack = new FastPeekStack();
 
   public ElementBuilderImpl() {
     if (HTML_TAG_REGEX == null) {
@@ -90,39 +159,11 @@
     }
   }
 
-  public ElementBuilderBase<?> end() {
-    // Get the top item (also verifies there is a top item).
-    String tagName = getCurrentTagName();
-
-    // Close the start tag.
-    maybeCloseStartTag();
-
-    /*
-     * End the tag. The tag name is safe because it comes from the stack, and
-     * tag names are checked before they are added to the stack.
-     */
-    if (getCurrentBuilder().isEndTagForbidden()) {
-      doEndStartTagImpl();
-    } else {
-      doEndTagImpl(tagName);
-    }
-
-    // Popup the item off the top of the stack.
-    isStartTagOpen = false; // Closed because this element was added.
-    isStyleClosed = true; // Too late to add styles.
-    stackTags.remove(stackTags.size() - 1);
-    stackBuilders.remove(stackBuilders.size() - 1);
-
-    /*
-     * If this element was added, then we did not add html or text to the
-     * parent.
-     */
-    isHtmlOrTextAdded = false;
-
-    return getCurrentBuilder();
+  public void end() {
+    endImpl(getCurrentTagName());
   }
 
-  public ElementBuilderBase<?> end(String tagName) {
+  public void end(String tagName) {
     // Verify the tag name matches the expected tag.
     String topItem = getCurrentTagName();
     if (!topItem.equalsIgnoreCase(tagName)) {
@@ -131,16 +172,15 @@
     }
 
     // End the element.
-    return end();
+    endImpl(topItem);
   }
 
-  public ElementBuilderBase<?> endStyle() {
+  public void endStyle() {
     if (!isStyleOpen) {
       throw new IllegalStateException(
           "Attempting to close a style attribute, but the style attribute isn't open");
     }
     maybeCloseStyleAttribute();
-    return getCurrentBuilder();
   }
 
   /**
@@ -173,13 +213,13 @@
   public void onStart(String tagName, ElementBuilderBase<?> builder) {
     if (isEmpty) {
       isEmpty = false;
-    } else if (stackTags.size() == 0) {
+    } else if (stack.isEmpty()) {
       // Check that we aren't creating another top level element.
       throw new IllegalStateException("You can only build one top level element.");
     } else {
       // Check that the element supports children.
-      assertEndTagNotForbidden(getCurrentTagName() + " does not support child elements.");
-      if (!builder.isChildElementSupported()) {
+      assertEndTagNotForbidden("child elements");
+      if (!getCurrentBuilder().isChildElementSupported()) {
         throw new UnsupportedOperationException(getCurrentTagName()
             + " does not support child elements.");
       }
@@ -194,8 +234,7 @@
     assertValidTagName(tagName);
 
     maybeCloseStartTag();
-    stackTags.add(tagName);
-    stackBuilders.add(builder);
+    stack.push(builder, tagName);
     isStartTagOpen = true;
     isStyleOpen = false;
     isStyleClosed = false;
@@ -223,7 +262,8 @@
    * @throw {@link IllegalStateException} if the start tag is closed
    */
   protected void assertCanAddAttributeImpl() {
-    assertStartTagOpen("Attributes cannot be added after appending HTML or adding a child element.");
+    assertStartTagOpen("Attributes cannot be added after appending HTML or adding a child "
+        + "element.");
     maybeCloseStyleAttribute();
   }
 
@@ -318,7 +358,7 @@
    * </p>
    */
   protected void endAllTags() {
-    while (!stackTags.isEmpty()) {
+    while (!stack.isEmpty()) {
       end();
     }
   }
@@ -329,19 +369,20 @@
    */
   protected void lockCurrentElement() {
     maybeCloseStartTag();
-    assertEndTagNotForbidden(getCurrentTagName() + " does not support html.");
+    assertEndTagNotForbidden("html");
     isHtmlOrTextAdded = true;
   }
 
   /**
    * Assert that the current builder does not forbid end tags.
    * 
-   * @param message the error message if not supported
+   * @param operation the operation that the user is attempting
    * @throw {@link UnsupportedOperationException} if not supported
    */
-  private void assertEndTagNotForbidden(String message) {
+  private void assertEndTagNotForbidden(String operation) {
     if (getCurrentBuilder().isEndTagForbidden()) {
-      throw new UnsupportedOperationException(message);
+      throw new UnsupportedOperationException(getCurrentTagName() + " does not support "
+          + operation);
     }
   }
 
@@ -358,13 +399,44 @@
   }
 
   /**
+   * End the current element without checking the tag name.
+   * 
+   * @param tagName the tag name to end
+   */
+  private void endImpl(String tagName) {
+    // Close the start tag.
+    maybeCloseStartTag();
+
+    /*
+     * End the tag. The tag name is safe because it comes from the stack, and
+     * tag names are checked before they are added to the stack.
+     */
+    if (getCurrentBuilder().isEndTagForbidden()) {
+      doEndStartTagImpl();
+    } else {
+      doEndTagImpl(tagName);
+    }
+
+    // Popup the item off the top of the stack.
+    isStartTagOpen = false; // Closed because this element was added.
+    isStyleClosed = true; // Too late to add styles.
+    stack.pop();
+
+    /*
+     * If this element was added, then we did not add html or text to the
+     * parent.
+     */
+    isHtmlOrTextAdded = false;
+  }
+
+  /**
    * Get the builder at the top of the stack.
    * 
-   * @return an {@link ElementBuilderBase}, or null if there are non left
+   * @return an {@link ElementBuilderBase}
+   * @throws IllegalStateException if there are no elements on the stack
    */
   private ElementBuilderBase<?> getCurrentBuilder() {
-    int stackSize = stackBuilders.size();
-    return (stackSize == 0) ? null : stackBuilders.get(stackSize - 1);
+    return stack.peek().builder;
   }
 
   /**
@@ -374,13 +446,7 @@
    * @throws IllegalStateException if there are no elements on the stack
    */
   private String getCurrentTagName() {
-    // Verify there is something on the stack.
-    int stackSize = stackTags.size();
-    if (stackSize == 0) {
-      throw new IllegalStateException("There are no elements on the stack.");
-    }
-
-    return stackTags.get(stackSize - 1);
+    return stack.peek().tagName;
   }
 
   /**
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlAnchorBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlAnchorBuilder.java
index edac389..bc5dc7b 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlAnchorBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlAnchorBuilder.java
@@ -27,36 +27,36 @@
 
   @Override
   public AnchorBuilder accessKey(String accessKey) {
-    return attribute("accessKey", accessKey);
+    return trustedAttribute("accessKey", accessKey);
   }
 
   @Override
   public AnchorBuilder href(String href) {
-    return attribute("href", href);
+    return trustedAttribute("href", href);
   }
 
   @Override
   public AnchorBuilder hreflang(String hreflang) {
-    return attribute("hreflang", hreflang);
+    return trustedAttribute("hreflang", hreflang);
   }
 
   @Override
   public AnchorBuilder name(String name) {
-    return attribute("name", name);
+    return trustedAttribute("name", name);
   }
 
   @Override
   public AnchorBuilder rel(String rel) {
-    return attribute("rel", rel);
+    return trustedAttribute("rel", rel);
   }
 
   @Override
   public AnchorBuilder target(String target) {
-    return attribute("target", target);
+    return trustedAttribute("target", target);
   }
 
   @Override
   public AnchorBuilder type(String type) {
-    return attribute("type", type);
+    return trustedAttribute("type", type);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlAreaBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlAreaBuilder.java
index 5188461..d821e28 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlAreaBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlAreaBuilder.java
@@ -26,31 +26,31 @@
 
   @Override
   public AreaBuilder accessKey(String accessKey) {
-    return attribute("accessKey", accessKey);
+    return trustedAttribute("accessKey", accessKey);
   }
 
   @Override
   public AreaBuilder alt(String alt) {
-    return attribute("alt", alt);
+    return trustedAttribute("alt", alt);
   }
 
   @Override
   public AreaBuilder coords(String coords) {
-    return attribute("coords", coords);
+    return trustedAttribute("coords", coords);
   }
 
   @Override
   public AreaBuilder href(String href) {
-    return attribute("href", href);
+    return trustedAttribute("href", href);
   }
 
   @Override
   public AreaBuilder shape(String shape) {
-    return attribute("shape", shape);
+    return trustedAttribute("shape", shape);
   }
 
   @Override
   public AreaBuilder target(String target) {
-    return attribute("target", target);
+    return trustedAttribute("target", target);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlBaseBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlBaseBuilder.java
index 46bb686..4e8beda 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlBaseBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlBaseBuilder.java
@@ -26,11 +26,11 @@
 
   @Override
   public BaseBuilder href(String href) {
-    return attribute("href", href);
+    return trustedAttribute("href", href);
   }
 
   @Override
   public BaseBuilder target(String target) {
-    return attribute("target", target);
+    return trustedAttribute("target", target);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlBuilderFactory.java b/user/src/com/google/gwt/dom/builder/shared/HtmlBuilderFactory.java
index 286dab7..6a74146 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlBuilderFactory.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlBuilderFactory.java
@@ -95,8 +95,8 @@
   }
 
   @Override
-  public InputBuilder createCheckInputBuilder() {
-    return impl().startCheckInput();
+  public InputBuilder createCheckboxInputBuilder() {
+    return impl().startCheckboxInput();
   }
 
   @Override
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlBuilderImpl.java b/user/src/com/google/gwt/dom/builder/shared/HtmlBuilderImpl.java
index d03317d..8488cc2 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlBuilderImpl.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlBuilderImpl.java
@@ -151,37 +151,44 @@
     return SafeHtmlUtils.fromTrustedString(sb.toString());
   }
 
+  public void attribute(String name, int value) {
+    trustedAttribute(escape(name), value);
+  }
+
   public void attribute(String name, String value) {
-    assertCanAddAttributeImpl();
-    sb.append(" ").append(escape(name)).append("=\"").append(escape(value)).append("\"");
+    trustedAttribute(escape(name), value);
   }
 
   public HtmlAnchorBuilder startAnchor() {
     if (anchorBuilder == null) {
       anchorBuilder = new HtmlAnchorBuilder(this);
     }
-    return trustedStart(AnchorElement.TAG, anchorBuilder);
+    trustedStart(AnchorElement.TAG, anchorBuilder);
+    return anchorBuilder;
   }
 
   public HtmlAreaBuilder startArea() {
     if (areaBuilder == null) {
       areaBuilder = new HtmlAreaBuilder(this);
     }
-    return trustedStart(AreaElement.TAG, areaBuilder);
+    trustedStart(AreaElement.TAG, areaBuilder);
+    return areaBuilder;
   }
 
   public HtmlAudioBuilder startAudio() {
     if (audioBuilder == null) {
       audioBuilder = new HtmlAudioBuilder(this);
     }
-    return trustedStart(AudioElement.TAG, audioBuilder);
+    trustedStart(AudioElement.TAG, audioBuilder);
+    return audioBuilder;
   }
 
   public HtmlBaseBuilder startBase() {
     if (baseBuilder == null) {
       baseBuilder = new HtmlBaseBuilder(this);
     }
-    return trustedStart(BaseElement.TAG, baseBuilder);
+    trustedStart(BaseElement.TAG, baseBuilder);
+    return baseBuilder;
   }
 
   public HtmlQuoteBuilder startBlockQuote() {
@@ -192,14 +199,16 @@
     if (bodyBuilder == null) {
       bodyBuilder = new HtmlBodyBuilder(this);
     }
-    return trustedStart(BodyElement.TAG, bodyBuilder);
+    trustedStart(BodyElement.TAG, bodyBuilder);
+    return bodyBuilder;
   }
 
   public HtmlBRBuilder startBR() {
     if (brBuilder == null) {
       brBuilder = new HtmlBRBuilder(this);
     }
-    return trustedStart(BRElement.TAG, brBuilder);
+    trustedStart(BRElement.TAG, brBuilder);
+    return brBuilder;
   }
 
   public InputBuilder startButtonInput() {
@@ -210,11 +219,12 @@
     if (canvasBuilder == null) {
       canvasBuilder = new HtmlCanvasBuilder(this);
     }
-    return trustedStart(CanvasElement.TAG, canvasBuilder);
+    trustedStart(CanvasElement.TAG, canvasBuilder);
+    return canvasBuilder;
   }
 
-  public InputBuilder startCheckInput() {
-    return startInput("check");
+  public InputBuilder startCheckboxInput() {
+    return startInput("checkbox");
   }
 
   public HtmlTableColBuilder startCol() {
@@ -226,21 +236,24 @@
   }
 
   public HtmlDivBuilder startDiv() {
-    return trustedStart(DivElement.TAG, divBuilder);
+    trustedStart(DivElement.TAG, divBuilder);
+    return divBuilder;
   }
 
   public HtmlDListBuilder startDList() {
     if (dListBuilder == null) {
       dListBuilder = new HtmlDListBuilder(this);
     }
-    return trustedStart(DListElement.TAG, dListBuilder);
+    trustedStart(DListElement.TAG, dListBuilder);
+    return dListBuilder;
   }
 
   public HtmlFieldSetBuilder startFieldSet() {
     if (fieldSetBuilder == null) {
       fieldSetBuilder = new HtmlFieldSetBuilder(this);
     }
-    return trustedStart(FieldSetElement.TAG, fieldSetBuilder);
+    trustedStart(FieldSetElement.TAG, fieldSetBuilder);
+    return fieldSetBuilder;
   }
 
   public InputBuilder startFileInput() {
@@ -251,21 +264,24 @@
     if (formBuilder == null) {
       formBuilder = new HtmlFormBuilder(this);
     }
-    return trustedStart(FormElement.TAG, formBuilder);
+    trustedStart(FormElement.TAG, formBuilder);
+    return formBuilder;
   }
 
   public HtmlFrameBuilder startFrame() {
     if (frameBuilder == null) {
       frameBuilder = new HtmlFrameBuilder(this);
     }
-    return trustedStart(FrameElement.TAG, frameBuilder);
+    trustedStart(FrameElement.TAG, frameBuilder);
+    return frameBuilder;
   }
 
   public HtmlFrameSetBuilder startFrameSet() {
     if (frameSetBuilder == null) {
       frameSetBuilder = new HtmlFrameSetBuilder(this);
     }
-    return trustedStart(FrameSetElement.TAG, frameSetBuilder);
+    trustedStart(FrameSetElement.TAG, frameSetBuilder);
+    return frameSetBuilder;
   }
 
   public HtmlHeadingBuilder startH1() {
@@ -296,7 +312,8 @@
     if (headBuilder == null) {
       headBuilder = new HtmlHeadBuilder(this);
     }
-    return trustedStart(HeadElement.TAG, headBuilder);
+    trustedStart(HeadElement.TAG, headBuilder);
+    return headBuilder;
   }
 
   public InputBuilder startHiddenInput() {
@@ -307,21 +324,24 @@
     if (hrBuilder == null) {
       hrBuilder = new HtmlHRBuilder(this);
     }
-    return trustedStart(HRElement.TAG, hrBuilder);
+    trustedStart(HRElement.TAG, hrBuilder);
+    return hrBuilder;
   }
 
   public HtmlIFrameBuilder startIFrame() {
     if (iFrameBuilder == null) {
       iFrameBuilder = new HtmlIFrameBuilder(this);
     }
-    return trustedStart(IFrameElement.TAG, iFrameBuilder);
+    trustedStart(IFrameElement.TAG, iFrameBuilder);
+    return iFrameBuilder;
   }
 
   public HtmlImageBuilder startImage() {
     if (imageBuilder == null) {
       imageBuilder = new HtmlImageBuilder(this);
     }
-    return trustedStart(ImageElement.TAG, imageBuilder);
+    trustedStart(ImageElement.TAG, imageBuilder);
+    return imageBuilder;
   }
 
   public InputBuilder startImageInput() {
@@ -332,71 +352,82 @@
     if (labelBuilder == null) {
       labelBuilder = new HtmlLabelBuilder(this);
     }
-    return trustedStart(LabelElement.TAG, labelBuilder);
+    trustedStart(LabelElement.TAG, labelBuilder);
+    return labelBuilder;
   }
 
   public HtmlLegendBuilder startLegend() {
     if (legendBuilder == null) {
       legendBuilder = new HtmlLegendBuilder(this);
     }
-    return trustedStart(LegendElement.TAG, legendBuilder);
+    trustedStart(LegendElement.TAG, legendBuilder);
+    return legendBuilder;
   }
 
   public HtmlLIBuilder startLI() {
-    return trustedStart(LIElement.TAG, liBuilder);
+    trustedStart(LIElement.TAG, liBuilder);
+    return liBuilder;
   }
 
   public HtmlLinkBuilder startLink() {
     if (linkBuilder == null) {
       linkBuilder = new HtmlLinkBuilder(this);
     }
-    return trustedStart(LinkElement.TAG, linkBuilder);
+    trustedStart(LinkElement.TAG, linkBuilder);
+    return linkBuilder;
   }
 
   public HtmlMapBuilder startMap() {
     if (mapBuilder == null) {
       mapBuilder = new HtmlMapBuilder(this);
     }
-    return trustedStart(MapElement.TAG, mapBuilder);
+    trustedStart(MapElement.TAG, mapBuilder);
+    return mapBuilder;
   }
 
   public HtmlMetaBuilder startMeta() {
     if (metaBuilder == null) {
       metaBuilder = new HtmlMetaBuilder(this);
     }
-    return trustedStart(MetaElement.TAG, metaBuilder);
+    trustedStart(MetaElement.TAG, metaBuilder);
+    return metaBuilder;
   }
 
   public HtmlOListBuilder startOList() {
     if (oListBuilder == null) {
       oListBuilder = new HtmlOListBuilder(this);
     }
-    return trustedStart(OListElement.TAG, oListBuilder);
+    trustedStart(OListElement.TAG, oListBuilder);
+    return oListBuilder;
   }
 
   public HtmlOptGroupBuilder startOptGroup() {
     if (optGroupBuilder == null) {
       optGroupBuilder = new HtmlOptGroupBuilder(this);
     }
-    return trustedStart(OptGroupElement.TAG, optGroupBuilder);
+    trustedStart(OptGroupElement.TAG, optGroupBuilder);
+    return optGroupBuilder;
   }
 
   public HtmlOptionBuilder startOption() {
-    return trustedStart(OptionElement.TAG, optionBuilder);
+    trustedStart(OptionElement.TAG, optionBuilder);
+    return optionBuilder;
   }
 
   public HtmlParagraphBuilder startParagraph() {
     if (paragraphBuilder == null) {
       paragraphBuilder = new HtmlParagraphBuilder(this);
     }
-    return trustedStart(ParagraphElement.TAG, paragraphBuilder);
+    trustedStart(ParagraphElement.TAG, paragraphBuilder);
+    return paragraphBuilder;
   }
 
   public HtmlParamBuilder startParam() {
     if (paramBuilder == null) {
       paramBuilder = new HtmlParamBuilder(this);
     }
-    return trustedStart(ParamElement.TAG, paramBuilder);
+    trustedStart(ParamElement.TAG, paramBuilder);
+    return paramBuilder;
   }
 
   public InputBuilder startPasswordInput() {
@@ -407,7 +438,8 @@
     if (preBuilder == null) {
       preBuilder = new HtmlPreBuilder(this);
     }
-    return trustedStart(PreElement.TAG, preBuilder);
+    trustedStart(PreElement.TAG, preBuilder);
+    return preBuilder;
   }
 
   public HtmlButtonBuilder startPushButton() {
@@ -436,32 +468,37 @@
     if (scriptBuilder == null) {
       scriptBuilder = new HtmlScriptBuilder(this);
     }
-    return trustedStart(ScriptElement.TAG, scriptBuilder);
+    trustedStart(ScriptElement.TAG, scriptBuilder);
+    return scriptBuilder;
   }
 
   public HtmlSelectBuilder startSelect() {
     if (selectBuilder == null) {
       selectBuilder = new HtmlSelectBuilder(this);
     }
-    return trustedStart(SelectElement.TAG, selectBuilder);
+    trustedStart(SelectElement.TAG, selectBuilder);
+    return selectBuilder;
   }
 
   public HtmlSourceBuilder startSource() {
     if (sourceBuilder == null) {
       sourceBuilder = new HtmlSourceBuilder(this);
     }
-    return trustedStart(SourceElement.TAG, sourceBuilder);
+    trustedStart(SourceElement.TAG, sourceBuilder);
+    return sourceBuilder;
   }
 
   public HtmlSpanBuilder startSpan() {
-    return trustedStart(SpanElement.TAG, spanBuilder);
+    trustedStart(SpanElement.TAG, spanBuilder);
+    return spanBuilder;
   }
 
   public HtmlStyleBuilder startStyle() {
     if (styleBuilder == null) {
       styleBuilder = new HtmlStyleBuilder(this);
     }
-    return trustedStart(StyleElement.TAG, styleBuilder);
+    trustedStart(StyleElement.TAG, styleBuilder);
+    return styleBuilder;
   }
 
   public HtmlButtonBuilder startSubmitButton() {
@@ -476,14 +513,16 @@
     if (tableBuilder == null) {
       tableBuilder = new HtmlTableBuilder(this);
     }
-    return trustedStart(TableElement.TAG, tableBuilder);
+    trustedStart(TableElement.TAG, tableBuilder);
+    return tableBuilder;
   }
 
   public HtmlTableCaptionBuilder startTableCaption() {
     if (tableCaptionBuilder == null) {
       tableCaptionBuilder = new HtmlTableCaptionBuilder(this);
     }
-    return trustedStart(TableCaptionElement.TAG, tableCaptionBuilder);
+    trustedStart(TableCaptionElement.TAG, tableCaptionBuilder);
+    return tableCaptionBuilder;
   }
 
   public HtmlTableSectionBuilder startTBody() {
@@ -491,14 +530,16 @@
   }
 
   public HtmlTableCellBuilder startTD() {
-    return trustedStart(TableCellElement.TAG_TD, tableCellBuilder);
+    trustedStart(TableCellElement.TAG_TD, tableCellBuilder);
+    return tableCellBuilder;
   }
 
   public HtmlTextAreaBuilder startTextArea() {
     if (textAreaBuilder == null) {
       textAreaBuilder = new HtmlTextAreaBuilder(this);
     }
-    return trustedStart(TextAreaElement.TAG, textAreaBuilder);
+    trustedStart(TextAreaElement.TAG, textAreaBuilder);
+    return textAreaBuilder;
   }
 
   public InputBuilder startTextInput() {
@@ -510,7 +551,8 @@
   }
 
   public HtmlTableCellBuilder startTH() {
-    return trustedStart(TableCellElement.TAG_TH, tableCellBuilder);
+    trustedStart(TableCellElement.TAG_TH, tableCellBuilder);
+    return tableCellBuilder;
   }
 
   public HtmlTableSectionBuilder startTHead() {
@@ -521,25 +563,29 @@
     if (titleBuilder == null) {
       titleBuilder = new HtmlTitleBuilder(this);
     }
-    return trustedStart(TitleElement.TAG, titleBuilder);
+    trustedStart(TitleElement.TAG, titleBuilder);
+    return titleBuilder;
   }
 
   public HtmlTableRowBuilder startTR() {
-    return trustedStart(TableRowElement.TAG, tableRowBuilder);
+    trustedStart(TableRowElement.TAG, tableRowBuilder);
+    return tableRowBuilder;
   }
 
   public HtmlUListBuilder startUList() {
     if (uListBuilder == null) {
       uListBuilder = new HtmlUListBuilder(this);
     }
-    return trustedStart(UListElement.TAG, uListBuilder);
+    trustedStart(UListElement.TAG, uListBuilder);
+    return uListBuilder;
   }
 
   public HtmlVideoBuilder startVideo() {
     if (videoBuilder == null) {
       videoBuilder = new HtmlVideoBuilder(this);
     }
-    return trustedStart(VideoElement.TAG, videoBuilder);
+    trustedStart(VideoElement.TAG, videoBuilder);
+    return videoBuilder;
   }
 
   @Override
@@ -553,8 +599,26 @@
     return style();
   }
 
+  /**
+   * Add a trusted attribute without escaping the name.
+   */
+  public void trustedAttribute(String name, int value) {
+    assertCanAddAttributeImpl();
+    sb.append(" ").append(name).append("=\"").append(value).append("\"");
+  }
+
+  /**
+   * Add a trusted attribute without escaping the name. The value is still
+   * escaped.
+   */
+  public void trustedAttribute(String name, String value) {
+    assertCanAddAttributeImpl();
+    sb.append(" ").append(name).append("=\"").append(escape(value)).append("\"");
+  }
+
   public HtmlElementBuilder trustedStart(String tagName) {
-    return trustedStart(tagName, elementBuilder);
+    trustedStart(tagName, elementBuilder);
+    return elementBuilder;
   }
 
   @Override
@@ -625,9 +689,9 @@
     if (buttonBuilder == null) {
       buttonBuilder = new HtmlButtonBuilder(this);
     }
-    HtmlButtonBuilder builder = trustedStart("button", buttonBuilder);
-    builder.attribute("type", type);
-    return builder;
+    trustedStart("button", buttonBuilder);
+    buttonBuilder.attribute("type", type);
+    return buttonBuilder;
   }
 
   /**
@@ -637,7 +701,8 @@
     if (headingBuilder == null) {
       headingBuilder = new HtmlHeadingBuilder(this);
     }
-    return trustedStart("h" + level, headingBuilder);
+    trustedStart("h" + level, headingBuilder);
+    return headingBuilder;
   }
 
   /**
@@ -656,7 +721,8 @@
     if (quoteBuilder == null) {
       quoteBuilder = new HtmlQuoteBuilder(this);
     }
-    return trustedStart(tagName, quoteBuilder);
+    trustedStart(tagName, quoteBuilder);
+    return quoteBuilder;
   }
 
   /**
@@ -666,7 +732,8 @@
     if (tableColBuilder == null) {
       tableColBuilder = new HtmlTableColBuilder(this);
     }
-    return trustedStart(tagName, tableColBuilder);
+    trustedStart(tagName, tableColBuilder);
+    return tableColBuilder;
   }
 
   /**
@@ -676,18 +743,16 @@
     if (tableSectionBuilder == null) {
       tableSectionBuilder = new HtmlTableSectionBuilder(this);
     }
-    return trustedStart(tagName, tableSectionBuilder);
+    trustedStart(tagName, tableSectionBuilder);
+    return tableSectionBuilder;
   }
 
   /**
    * Start a tag using the specified builder. The tagName is not checked or
    * escaped.
-   * 
-   * @return the builder
    */
-  private <B extends ElementBuilderBase<?>> B trustedStart(String tagName, B builder) {
+  private void trustedStart(String tagName, ElementBuilderBase<?> builder) {
     onStart(tagName, builder);
     sb.append("<").append(tagName);
-    return builder;
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlButtonBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlButtonBuilder.java
index 2fca42b..6d25b83 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlButtonBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlButtonBuilder.java
@@ -27,21 +27,21 @@
 
   @Override
   public ButtonBuilder accessKey(String accessKey) {
-    return attribute("accessKey", accessKey);
+    return trustedAttribute("accessKey", accessKey);
   }
 
   @Override
   public ButtonBuilder disabled() {
-    return attribute("disabled", "disabled");
+    return trustedAttribute("disabled", "disabled");
   }
 
   @Override
   public ButtonBuilder name(String name) {
-    return attribute("name", name);
+    return trustedAttribute("name", name);
   }
 
   @Override
   public ButtonBuilder value(String value) {
-    return attribute("value", value);
+    return trustedAttribute("value", value);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlCanvasBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlCanvasBuilder.java
index 2c3e75b..48f5a36 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlCanvasBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlCanvasBuilder.java
@@ -27,11 +27,11 @@
 
   @Override
   public CanvasBuilder height(int height) {
-    return attribute("height", height);
+    return trustedAttribute("height", height);
   }
 
   @Override
   public CanvasBuilder width(int width) {
-    return attribute("width", width);
+    return trustedAttribute("width", width);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlElementBuilderBase.java b/user/src/com/google/gwt/dom/builder/shared/HtmlElementBuilderBase.java
index 14151b9..82e0423 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlElementBuilderBase.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlElementBuilderBase.java
@@ -67,6 +67,12 @@
   }
 
   @Override
+  public R attribute(String name, int value) {
+    delegate.attribute(name, value);
+    return getReturnBuilder();
+  }
+
+  @Override
   public R attribute(String name, String value) {
     delegate.attribute(name, value);
     return getReturnBuilder();
@@ -74,43 +80,36 @@
 
   @Override
   public R className(String className) {
-    return attribute("class", className);
+    return trustedAttribute("class", className);
   }
 
   @Override
   public R dir(String dir) {
-    return attribute("dir", dir);
+    return trustedAttribute("dir", dir);
   }
 
   @Override
   public R draggable(String draggable) {
-    return attribute("draggable", draggable);
+    return trustedAttribute("draggable", draggable);
   }
 
   /**
    * End the current element.
    * 
-   * @param <B> the type of the parent element
-   * @return the {@link ElementBuilderBase} for the parent element, or null if
-   *         the current element does not have a parent
-   * @throws IllegalStateException if the current element has the wrong tag
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified class
    * @see #end()
    */
-  @SuppressWarnings("unchecked")
-  public <B extends ElementBuilderBase<?>> B endTitle() {
-    return (B) end(TitleElement.TAG);
+  public void endTitle() {
+    end(TitleElement.TAG);
   }
 
   @Override
   public R id(String id) {
-    return attribute("id", id);
+    return trustedAttribute("id", id);
   }
 
   @Override
   public R lang(String lang) {
-    return attribute("lang", lang);
+    return trustedAttribute("lang", lang);
   }
 
   @Override
@@ -159,8 +158,8 @@
   }
 
   @Override
-  public InputBuilder startCheckInput() {
-    return delegate.startCheckInput();
+  public InputBuilder startCheckboxInput() {
+    return delegate.startCheckboxInput();
   }
 
   @Override
@@ -464,16 +463,32 @@
 
   @Override
   public R tabIndex(int tabIndex) {
-    return attribute("tabIndex", tabIndex);
+    return trustedAttribute("tabIndex", tabIndex);
   }
 
   @Override
   public R title(String title) {
-    return attribute("title", title);
+    return trustedAttribute("title", title);
   }
 
   @Override
   public ElementBuilder trustedStart(String tagName) {
     return delegate.trustedStart(tagName);
   }
+
+  /**
+   * Add an attribute with a trusted name.
+   */
+  R trustedAttribute(String name, int value) {
+    delegate.trustedAttribute(name, value);
+    return getReturnBuilder();
+  }
+
+  /**
+   * Add an attribute with a trusted name. The name is still escaped.
+   */
+  R trustedAttribute(String name, String value) {
+    delegate.trustedAttribute(name, value);
+    return getReturnBuilder();
+  }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlFormBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlFormBuilder.java
index ca46b26..83b2bf5 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlFormBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlFormBuilder.java
@@ -26,31 +26,31 @@
 
   @Override
   public FormBuilder acceptCharset(String acceptCharset) {
-    return attribute("acceptCharset", acceptCharset);
+    return trustedAttribute("acceptCharset", acceptCharset);
   }
 
   @Override
   public FormBuilder action(String action) {
-    return attribute("action", action);
+    return trustedAttribute("action", action);
   }
 
   @Override
   public FormBuilder enctype(String enctype) {
-    return attribute("enctype", enctype);
+    return trustedAttribute("enctype", enctype);
   }
 
   @Override
   public FormBuilder method(String method) {
-    return attribute("method", method);
+    return trustedAttribute("method", method);
   }
 
   @Override
   public FormBuilder name(String name) {
-    return attribute("name", name);
+    return trustedAttribute("name", name);
   }
 
   @Override
   public FormBuilder target(String target) {
-    return attribute("target", target);
+    return trustedAttribute("target", target);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlFrameBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlFrameBuilder.java
index 7102582..b81a127 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlFrameBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlFrameBuilder.java
@@ -26,41 +26,41 @@
 
   @Override
   public FrameBuilder frameBorder(int frameBorder) {
-    return attribute("frameBorder", frameBorder);
+    return trustedAttribute("frameBorder", frameBorder);
   }
 
   @Override
   public FrameBuilder longDesc(String longDesc) {
-    return attribute("longDesc", longDesc);
+    return trustedAttribute("longDesc", longDesc);
   }
 
   @Override
   public FrameBuilder marginHeight(int marginHeight) {
-    return attribute("marginHeight", marginHeight);
+    return trustedAttribute("marginHeight", marginHeight);
   }
 
   @Override
   public FrameBuilder marginWidth(int marginWidth) {
-    return attribute("marginWidth", marginWidth);
+    return trustedAttribute("marginWidth", marginWidth);
   }
 
   @Override
   public FrameBuilder name(String name) {
-    return attribute("name", name);
+    return trustedAttribute("name", name);
   }
 
   @Override
   public FrameBuilder noResize() {
-    return attribute("noresize", "noresize");
+    return trustedAttribute("noresize", "noresize");
   }
 
   @Override
   public FrameBuilder scrolling(String scrolling) {
-    return attribute("scrolling", scrolling);
+    return trustedAttribute("scrolling", scrolling);
   }
 
   @Override
   public FrameBuilder src(String src) {
-    return attribute("src", src);
+    return trustedAttribute("src", src);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlFrameSetBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlFrameSetBuilder.java
index 9198ade..2232bac 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlFrameSetBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlFrameSetBuilder.java
@@ -29,7 +29,7 @@
 
   @Override
   public FrameSetBuilder cols(String cols) {
-    return attribute("cols", cols);
+    return trustedAttribute("cols", cols);
   }
 
   @Override
@@ -39,7 +39,7 @@
 
   @Override
   public FrameSetBuilder rows(String rows) {
-    return attribute("rows", rows);
+    return trustedAttribute("rows", rows);
   }
 
   @Override
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlIFrameBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlIFrameBuilder.java
index ee3c654..22e1823 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlIFrameBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlIFrameBuilder.java
@@ -29,7 +29,7 @@
 
   @Override
   public IFrameBuilder frameBorder(int frameBorder) {
-    return attribute("frameBorder", frameBorder);
+    return trustedAttribute("frameBorder", frameBorder);
   }
 
   @Override
@@ -44,32 +44,32 @@
 
   @Override
   public IFrameBuilder marginHeight(int marginHeight) {
-    return attribute("marginHeight", marginHeight);
+    return trustedAttribute("marginHeight", marginHeight);
   }
 
   @Override
   public IFrameBuilder marginWidth(int marginWidth) {
-    return attribute("marginWidth", marginWidth);
+    return trustedAttribute("marginWidth", marginWidth);
   }
 
   @Override
   public IFrameBuilder name(String name) {
-    return attribute("name", name);
+    return trustedAttribute("name", name);
   }
 
   @Override
   public IFrameBuilder noResize() {
-    return attribute("noresize", "noresize");
+    return trustedAttribute("noresize", "noresize");
   }
 
   @Override
   public IFrameBuilder scrolling(String scrolling) {
-    return attribute("scrolling", scrolling);
+    return trustedAttribute("scrolling", scrolling);
   }
 
   @Override
   public IFrameBuilder src(String src) {
-    return attribute("src", src);
+    return trustedAttribute("src", src);
   }
 
   @Override
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlImageBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlImageBuilder.java
index 715d9c0..056632e 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlImageBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlImageBuilder.java
@@ -26,26 +26,26 @@
 
   @Override
   public ImageBuilder alt(String alt) {
-    return attribute("alt", alt);
+    return trustedAttribute("alt", alt);
   }
 
   @Override
   public ImageBuilder height(int height) {
-    return attribute("height", height);
+    return trustedAttribute("height", height);
   }
 
   @Override
   public ImageBuilder isMap() {
-    return attribute("ismap", "ismap");
+    return trustedAttribute("ismap", "ismap");
   }
 
   @Override
   public ImageBuilder src(String src) {
-    return attribute("src", src);
+    return trustedAttribute("src", src);
   }
 
   @Override
   public ImageBuilder width(int width) {
-    return attribute("width", width);
+    return trustedAttribute("width", width);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlInputBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlInputBuilder.java
index 6d5d697..1058f5a 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlInputBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlInputBuilder.java
@@ -26,66 +26,66 @@
 
   @Override
   public InputBuilder accept(String accept) {
-    return attribute("accept", accept);
+    return trustedAttribute("accept", accept);
   }
 
   @Override
   public InputBuilder accessKey(String accessKey) {
-    return attribute("accessKey", accessKey);
+    return trustedAttribute("accessKey", accessKey);
   }
 
   @Override
   public InputBuilder alt(String alt) {
-    return attribute("alt", alt);
+    return trustedAttribute("alt", alt);
   }
 
   @Override
   public InputBuilder checked() {
-    return attribute("checked", "checked");
+    return trustedAttribute("checked", "checked");
   }
 
   @Override
   public InputBuilder defaultChecked() {
-    return attribute("defaultChecked", "defaultChecked");
+    return trustedAttribute("defaultChecked", "defaultChecked");
   }
 
   @Override
   public InputBuilder defaultValue(String defaultValue) {
-    return attribute("defaultValue", defaultValue);
+    return trustedAttribute("defaultValue", defaultValue);
   }
 
   @Override
   public InputBuilder disabled() {
-    return attribute("disabled", "disabled");
+    return trustedAttribute("disabled", "disabled");
   }
 
   @Override
   public InputBuilder maxLength(int maxLength) {
-    return attribute("maxlength", maxLength);
+    return trustedAttribute("maxlength", maxLength);
   }
 
   @Override
   public InputBuilder name(String name) {
-    return attribute("name", name);
+    return trustedAttribute("name", name);
   }
 
   @Override
   public InputBuilder readOnly() {
-    return attribute("readonly", "readonly");
+    return trustedAttribute("readonly", "readonly");
   }
 
   @Override
   public InputBuilder size(int size) {
-    return attribute("size", size);
+    return trustedAttribute("size", size);
   }
 
   @Override
   public InputBuilder src(String src) {
-    return attribute("src", src);
+    return trustedAttribute("src", src);
   }
 
   @Override
   public InputBuilder value(String value) {
-    return attribute("value", value);
+    return trustedAttribute("value", value);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlLabelBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlLabelBuilder.java
index 77801d8..50c8e59 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlLabelBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlLabelBuilder.java
@@ -26,11 +26,11 @@
 
   @Override
   public LabelBuilder accessKey(String accessKey) {
-    return attribute("accessKey", accessKey);
+    return trustedAttribute("accessKey", accessKey);
   }
 
   @Override
   public LabelBuilder htmlFor(String htmlFor) {
-    return attribute("htmlFor", htmlFor);
+    return trustedAttribute("for", htmlFor);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlLegendBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlLegendBuilder.java
index 7aecb64..0eac563 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlLegendBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlLegendBuilder.java
@@ -27,6 +27,6 @@
 
   @Override
   public LegendBuilder accessKey(String accessKey) {
-    return attribute("accessKey", accessKey);
+    return trustedAttribute("accessKey", accessKey);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlLinkBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlLinkBuilder.java
index ee298c3..79ff254 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlLinkBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlLinkBuilder.java
@@ -26,36 +26,36 @@
 
   @Override
   public LinkBuilder disabled() {
-    return attribute("disabled", "disabled");
+    return trustedAttribute("disabled", "disabled");
   }
 
   @Override
   public LinkBuilder href(String href) {
-    return attribute("href", href);
+    return trustedAttribute("href", href);
   }
 
   @Override
   public LinkBuilder hreflang(String hreflang) {
-    return attribute("hreflang", hreflang);
+    return trustedAttribute("hreflang", hreflang);
   }
 
   @Override
   public LinkBuilder media(String media) {
-    return attribute("media", media);
+    return trustedAttribute("media", media);
   }
 
   @Override
   public LinkBuilder rel(String rel) {
-    return attribute("rel", rel);
+    return trustedAttribute("rel", rel);
   }
 
   @Override
   public LinkBuilder target(String target) {
-    return attribute("target", target);
+    return trustedAttribute("target", target);
   }
 
   @Override
   public LinkBuilder type(String type) {
-    return attribute("type", type);
+    return trustedAttribute("type", type);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlMapBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlMapBuilder.java
index 67452e0..4adb9339 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlMapBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlMapBuilder.java
@@ -26,6 +26,6 @@
 
   @Override
   public MapBuilder name(String name) {
-    return attribute("name", name);
+    return trustedAttribute("name", name);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlMediaBuilderBase.java b/user/src/com/google/gwt/dom/builder/shared/HtmlMediaBuilderBase.java
index 39d0998..2951ef5 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlMediaBuilderBase.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlMediaBuilderBase.java
@@ -29,31 +29,31 @@
 
   @Override
   public R autoplay() {
-    return attribute("autoplay", "autoplay");
+    return trustedAttribute("autoplay", "autoplay");
   }
 
   @Override
   public R controls() {
-    return attribute("controls", "controls");
+    return trustedAttribute("controls", "controls");
   }
 
   @Override
   public R loop() {
-    return attribute("loop", "loop");
+    return trustedAttribute("loop", "loop");
   }
 
   @Override
   public R muted() {
-    return attribute("muted", "muted");
+    return trustedAttribute("muted", "muted");
   }
 
   @Override
   public R preload(String preload) {
-    return attribute("preload", preload);
+    return trustedAttribute("preload", preload);
   }
 
   @Override
   public R src(String url) {
-    return attribute("src", url);
+    return trustedAttribute("src", url);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlMetaBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlMetaBuilder.java
index daa1440..7a93ba5 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlMetaBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlMetaBuilder.java
@@ -26,16 +26,16 @@
 
   @Override
   public MetaBuilder content(String content) {
-    return attribute("content", content);
+    return trustedAttribute("content", content);
   }
 
   @Override
   public MetaBuilder httpEquiv(String httpEquiv) {
-    return attribute("httpEquiv", httpEquiv);
+    return trustedAttribute("httpEquiv", httpEquiv);
   }
 
   @Override
   public MetaBuilder name(String name) {
-    return attribute("name", name);
+    return trustedAttribute("name", name);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlOptGroupBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlOptGroupBuilder.java
index 45c4570..f761367 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlOptGroupBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlOptGroupBuilder.java
@@ -27,11 +27,11 @@
 
   @Override
   public OptGroupBuilder disabled() {
-    return attribute("disabled", "disabled");
+    return trustedAttribute("disabled", "disabled");
   }
 
   @Override
   public OptGroupBuilder label(String label) {
-    return attribute("label", label);
+    return trustedAttribute("label", label);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlOptionBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlOptionBuilder.java
index 53e379a..3d0d917 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlOptionBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlOptionBuilder.java
@@ -27,26 +27,26 @@
 
   @Override
   public OptionBuilder defaultSelected() {
-    return attribute("defaultSelected", "defaultSelected");
+    return trustedAttribute("defaultSelected", "defaultSelected");
   }
 
   @Override
   public OptionBuilder disabled() {
-    return attribute("disabled", "disabled");
+    return trustedAttribute("disabled", "disabled");
   }
 
   @Override
   public OptionBuilder label(String label) {
-    return attribute("label", label);
+    return trustedAttribute("label", label);
   }
 
   @Override
   public OptionBuilder selected() {
-    return attribute("selected", "selected");
+    return trustedAttribute("selected", "selected");
   }
 
   @Override
   public OptionBuilder value(String value) {
-    return attribute("value", value);
+    return trustedAttribute("value", value);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlParamBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlParamBuilder.java
index 01362ad..ed8ca76 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlParamBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlParamBuilder.java
@@ -26,11 +26,11 @@
 
   @Override
   public ParamBuilder name(String name) {
-    return attribute("name", name);
+    return trustedAttribute("name", name);
   }
 
   @Override
   public ParamBuilder value(String value) {
-    return attribute("value", value);
+    return trustedAttribute("value", value);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlQuoteBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlQuoteBuilder.java
index 2607465..1681a46 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlQuoteBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlQuoteBuilder.java
@@ -26,6 +26,6 @@
 
   @Override
   public QuoteBuilder cite(String cite) {
-    return attribute("cite", cite);
+    return trustedAttribute("cite", cite);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlScriptBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlScriptBuilder.java
index 60299a3..343b15d 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlScriptBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlScriptBuilder.java
@@ -29,7 +29,7 @@
 
   @Override
   public ScriptBuilder defer(String defer) {
-    return attribute("defer", defer);
+    return trustedAttribute("defer", defer);
   }
 
   @Override
@@ -44,11 +44,11 @@
 
   @Override
   public ScriptBuilder src(String src) {
-    return attribute("src", src);
+    return trustedAttribute("src", src);
   }
 
   @Override
   public ScriptBuilder type(String type) {
-    return attribute("type", type);
+    return trustedAttribute("type", type);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlSelectBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlSelectBuilder.java
index e9776df..a86cc21 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlSelectBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlSelectBuilder.java
@@ -27,36 +27,36 @@
 
   @Override
   public SelectBuilder disabled() {
-    return attribute("disabled", "disabled");
+    return trustedAttribute("disabled", "disabled");
   }
 
   @Override
   public SelectBuilder multiple() {
-    return attribute("multiple", "multiple");
+    return trustedAttribute("multiple", "multiple");
   }
 
   @Override
   public SelectBuilder name(String name) {
-    return attribute("name", name);
+    return trustedAttribute("name", name);
   }
 
   @Override
   public SelectBuilder selectedIndex(int index) {
-    return attribute("index", index);
+    return trustedAttribute("index", index);
   }
 
   @Override
   public SelectBuilder size(int size) {
-    return attribute("size", size);
+    return trustedAttribute("size", size);
   }
 
   @Override
   public SelectBuilder type(String type) {
-    return attribute("type", type);
+    return trustedAttribute("type", type);
   }
 
   @Override
   public SelectBuilder value(String value) {
-    return attribute("value", value);
+    return trustedAttribute("value", value);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlSourceBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlSourceBuilder.java
index f81c3e6..7cdd535 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlSourceBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlSourceBuilder.java
@@ -27,11 +27,11 @@
 
   @Override
   public SourceBuilder src(String url) {
-    return attribute("url", url);
+    return trustedAttribute("url", url);
   }
 
   @Override
   public SourceBuilder type(String type) {
-    return attribute("type", type);
+    return trustedAttribute("type", type);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlStyleBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlStyleBuilder.java
index 4d9e0a7..1bec387 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlStyleBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlStyleBuilder.java
@@ -34,7 +34,7 @@
 
   @Override
   public StyleBuilder disabled() {
-    return attribute("disabled", "disabled");
+    return trustedAttribute("disabled", "disabled");
   }
 
   @Override
@@ -49,7 +49,7 @@
 
   @Override
   public StyleBuilder media(String media) {
-    return attribute("media", media);
+    return trustedAttribute("media", media);
   }
 
   @Override
@@ -59,6 +59,6 @@
 
   @Override
   public StyleBuilder type(String type) {
-    return attribute("type", type);
+    return trustedAttribute("type", type);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlStylesBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlStylesBuilder.java
index 29b87e2..2af1e83 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlStylesBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlStylesBuilder.java
@@ -15,6 +15,8 @@
  */
 package com.google.gwt.dom.builder.shared;
 
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.dom.client.Style.BorderStyle;
 import com.google.gwt.dom.client.Style.Cursor;
 import com.google.gwt.dom.client.Style.Display;
@@ -43,13 +45,79 @@
 class HtmlStylesBuilder implements StylesBuilder {
 
   /**
+   * A very fast map implemented using a {@link JavaScriptObject} when running
+   * in production.
+   */
+  private static interface FastStringMap {
+    /**
+     * Get a value.
+     * 
+     * @return the value, or null if not in the map
+     */
+    String get(String key);
+
+    /**
+     * Set a value.
+     */
+    void put(String key, String value);
+  }
+
+  /**
+   * JRE implementation of {@link FastStringMap}.
+   */
+  private static class FastStringMapJre implements FastStringMap {
+
+    private final Map<String, String> map = new HashMap<String, String>();
+
+    @Override
+    public String get(String key) {
+      return map.get(key);
+    }
+
+    @Override
+    public void put(String key, String value) {
+      map.put(key, value);
+    }
+  }
+
+  /**
+   * Native implementation of {@link FastStringMap}.
+   * 
+   * The native implementation sets and retrieves properties on a
+   * {@link JavaScriptObject}, which avoids the dynamic casts associated with
+   * the emulated version of {@link java.util.Map}.
+   */
+  private static class FastStringMapClient implements FastStringMap {
+
+    private final JavaScriptObject map = JavaScriptObject.createObject();
+
+    @Override
+    public String get(String key) {
+      return getImpl(map, key);
+    }
+
+    @Override
+    public void put(String key, String value) {
+      putImpl(map, key, value);
+    }
+
+    private native String getImpl(JavaScriptObject map, String key) /*-{
+      return map[key] || null;
+    }-*/;
+
+    private native void putImpl(JavaScriptObject map, String key, String value) /*-{
+      map[key] = value;
+    }-*/;
+  }
+
+  /**
    * A map of camelCase style properties to their hyphenated equivalents.
    * 
    * The set of style property names is limited, and common ones are reused
    * frequently, so caching saves us from converting every style property name
    * from camelCase to hyphenated form.
    */
-  private static Map<String, String> camelCaseMap;
+  private static FastStringMap camelCaseMap;
 
   /**
    * Regex to match a word in a camelCase phrase. A word starts with an
@@ -77,7 +145,7 @@
   static String toHyphenatedForm(String name) {
     // Static initializers.
     if (camelCaseWord == null) {
-      camelCaseMap = new HashMap<String, String>();
+      camelCaseMap = GWT.isClient() ? new FastStringMapClient() : new FastStringMapJre();
       camelCaseWord = RegExp.compile("([A-Za-z])([^A-Z]*)", "g");
       caseWord = RegExp.compile("[A-Z]([^A-Z]*)");
     }
@@ -154,10 +222,9 @@
     return delegate.styleProperty(SafeStylesUtils.forDisplay(value));
   }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public <B extends ElementBuilderBase<?>> B endStyle() {
-    return (B) delegate.endStyle();
+  public void endStyle() {
+    delegate.endStyle();
   }
 
   @Override
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlTableBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlTableBuilder.java
index 0f6d02f..f28db41 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlTableBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlTableBuilder.java
@@ -28,22 +28,22 @@
 
   @Override
   public TableBuilder border(int border) {
-    return attribute("border", border);
+    return trustedAttribute("border", border);
   }
 
   @Override
   public TableBuilder cellPadding(int cellPadding) {
-    return attribute("cellPadding", cellPadding);
+    return trustedAttribute("cellPadding", cellPadding);
   }
 
   @Override
   public TableBuilder cellSpacing(int cellSpacing) {
-    return attribute("cellSpacing", cellSpacing);
+    return trustedAttribute("cellSpacing", cellSpacing);
   }
 
   @Override
   public TableBuilder frame(String frame) {
-    return attribute("frame", frame);
+    return trustedAttribute("frame", frame);
   }
 
   @Override
@@ -53,7 +53,7 @@
 
   @Override
   public TableBuilder rules(String rules) {
-    return attribute("rules", rules);
+    return trustedAttribute("rules", rules);
   }
 
   @Override
@@ -63,6 +63,6 @@
 
   @Override
   public TableBuilder width(String width) {
-    return attribute("width", width);
+    return trustedAttribute("width", width);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlTableCellBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlTableCellBuilder.java
index a3b912a..2347cb3 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlTableCellBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlTableCellBuilder.java
@@ -27,36 +27,36 @@
 
   @Override
   public TableCellBuilder align(String align) {
-    return attribute("align", align);
+    return trustedAttribute("align", align);
   }
 
   @Override
   public TableCellBuilder ch(String ch) {
-    return attribute("ch", ch);
+    return trustedAttribute("ch", ch);
   }
 
   @Override
   public TableCellBuilder chOff(String chOff) {
-    return attribute("chOff", chOff);
+    return trustedAttribute("chOff", chOff);
   }
 
   @Override
   public TableCellBuilder colSpan(int colSpan) {
-    return attribute("colSpan", colSpan);
+    return trustedAttribute("colSpan", colSpan);
   }
 
   @Override
   public TableCellBuilder headers(String headers) {
-    return attribute("headers", headers);
+    return trustedAttribute("headers", headers);
   }
 
   @Override
   public TableCellBuilder rowSpan(int rowSpan) {
-    return attribute("rowSpan", rowSpan);
+    return trustedAttribute("rowSpan", rowSpan);
   }
 
   @Override
   public TableCellBuilder vAlign(String vAlign) {
-    return attribute("vAlign", vAlign);
+    return trustedAttribute("vAlign", vAlign);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlTableColBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlTableColBuilder.java
index dd9135f..e396e27 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlTableColBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlTableColBuilder.java
@@ -27,31 +27,31 @@
 
   @Override
   public TableColBuilder align(String align) {
-    return attribute("align", align);
+    return trustedAttribute("align", align);
   }
 
   @Override
   public TableColBuilder ch(String ch) {
-    return attribute("ch", ch);
+    return trustedAttribute("ch", ch);
   }
 
   @Override
   public TableColBuilder chOff(String chOff) {
-    return attribute("chOff", chOff);
+    return trustedAttribute("chOff", chOff);
   }
 
   @Override
   public TableColBuilder span(int span) {
-    return attribute("span", span);
+    return trustedAttribute("span", span);
   }
 
   @Override
   public TableColBuilder vAlign(String vAlign) {
-    return attribute("vAlign", vAlign);
+    return trustedAttribute("vAlign", vAlign);
   }
 
   @Override
   public TableColBuilder width(String width) {
-    return attribute("width", width);
+    return trustedAttribute("width", width);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlTableRowBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlTableRowBuilder.java
index b271070..a1003c4 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlTableRowBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlTableRowBuilder.java
@@ -29,17 +29,17 @@
 
   @Override
   public TableRowBuilder align(String align) {
-    return attribute("align", align);
+    return trustedAttribute("align", align);
   }
 
   @Override
   public TableRowBuilder ch(String ch) {
-    return attribute("ch", ch);
+    return trustedAttribute("ch", ch);
   }
 
   @Override
   public TableRowBuilder chOff(String chOff) {
-    return attribute("chOff", chOff);
+    return trustedAttribute("chOff", chOff);
   }
 
   @Override
@@ -54,6 +54,6 @@
 
   @Override
   public TableRowBuilder vAlign(String vAlign) {
-    return attribute("vAlign", vAlign);
+    return trustedAttribute("vAlign", vAlign);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlTableSectionBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlTableSectionBuilder.java
index 252ff1e..da1a8b0 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlTableSectionBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlTableSectionBuilder.java
@@ -29,17 +29,17 @@
 
   @Override
   public TableSectionBuilder align(String align) {
-    return attribute("align", align);
+    return trustedAttribute("align", align);
   }
 
   @Override
   public TableSectionBuilder ch(String ch) {
-    return attribute("ch", ch);
+    return trustedAttribute("ch", ch);
   }
 
   @Override
   public TableSectionBuilder chOff(String chOff) {
-    return attribute("chOff", chOff);
+    return trustedAttribute("chOff", chOff);
   }
 
   @Override
@@ -54,6 +54,6 @@
 
   @Override
   public TableSectionBuilder vAlign(String vAlign) {
-    return attribute("vAlign", vAlign);
+    return trustedAttribute("vAlign", vAlign);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlTextAreaBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlTextAreaBuilder.java
index 03a8da5..1084bc8 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlTextAreaBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlTextAreaBuilder.java
@@ -29,22 +29,22 @@
 
   @Override
   public TextAreaBuilder accessKey(String accessKey) {
-    return attribute("accessKey", accessKey);
+    return trustedAttribute("accessKey", accessKey);
   }
 
   @Override
   public TextAreaBuilder cols(int cols) {
-    return attribute("cols", cols);
+    return trustedAttribute("cols", cols);
   }
 
   @Override
   public TextAreaBuilder defaultValue(String defaultValue) {
-    return attribute("defaultValue", defaultValue);
+    return trustedAttribute("defaultValue", defaultValue);
   }
 
   @Override
   public TextAreaBuilder disabled() {
-    return attribute("disabled", "disabled");
+    return trustedAttribute("disabled", "disabled");
   }
 
   @Override
@@ -59,21 +59,21 @@
 
   @Override
   public TextAreaBuilder name(String name) {
-    return attribute("name", name);
+    return trustedAttribute("name", name);
   }
 
   @Override
   public TextAreaBuilder readOnly() {
-    return attribute("readonly", "readonly");
+    return trustedAttribute("readonly", "readonly");
   }
 
   @Override
   public TextAreaBuilder rows(int rows) {
-    return attribute("rows", rows);
+    return trustedAttribute("rows", rows);
   }
 
   @Override
   public TextAreaBuilder value(String value) {
-    return attribute("value", value);
+    return trustedAttribute("value", value);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/HtmlVideoBuilder.java b/user/src/com/google/gwt/dom/builder/shared/HtmlVideoBuilder.java
index 8791c7b..391a6ec 100644
--- a/user/src/com/google/gwt/dom/builder/shared/HtmlVideoBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/HtmlVideoBuilder.java
@@ -26,16 +26,16 @@
 
   @Override
   public VideoBuilder height(int height) {
-    return attribute("height", height);
+    return trustedAttribute("height", height);
   }
 
   @Override
   public VideoBuilder poster(String url) {
-    return attribute("url", url);
+    return trustedAttribute("url", url);
   }
 
   @Override
   public VideoBuilder width(int width) {
-    return attribute("width", width);
+    return trustedAttribute("width", width);
   }
 }
diff --git a/user/src/com/google/gwt/dom/builder/shared/StylesBuilder.java b/user/src/com/google/gwt/dom/builder/shared/StylesBuilder.java
index 49b35ff..7562ae9 100644
--- a/user/src/com/google/gwt/dom/builder/shared/StylesBuilder.java
+++ b/user/src/com/google/gwt/dom/builder/shared/StylesBuilder.java
@@ -79,38 +79,9 @@
   /**
    * End the current style attribute.
    * 
-   * <p>
-   * By default, this method returns the {@link ElementBuilderBase} instance for
-   * the element that contains the style attribute.
-   * </p>
-   * 
-   * <pre>
-   * DivBuilder div = ElementBuilderFactory.get().createDivBuilder();
-   * StylesBuilder styles = div.style();
-   * styles.fontSize(12.0, Unit.PT);
-   * ElementBuilderBase&lt;?&gt; sameAs_div = styles.endStyle();
-   * </pre>
-   * 
-   * <p>
-   * You can cast the return type by parameterizing the return value. If the
-   * parameterized type does not match the builder type of the element that
-   * contains this style, a {@link ClassCastException} is thrown.
-   * </p>
-   * 
-   * <pre>
-   * DivBuilder div = ElementBuilderFactory.get().createDivBuilder();
-   * StylesBuilder styles = div.style();
-   * styles.fontSize(12.0, Unit.PT);
-   * DivBuilder sameAsDiv = styles.&lt;DivBuilder&gt; endStyle();
-   * </pre>
-   * 
-   * @param <B> the type of the element that contains the styles
-   * @return the {@link ElementBuilderBase} for the containing element
    * @throws IllegalStateException if the style attribute is already closed
-   * @throws ClassCastException if the parent builder does not match the
-   *           specified return type
    */
-  <B extends ElementBuilderBase<?>> B endStyle();
+  void endStyle();
 
   /**
    * Set the float css property.
@@ -325,7 +296,7 @@
    * <code>font: 'foo &lt;style&gt;&lt;script&gt;evil&lt;/script&gt;</code>'" is
    * used in a style sheet in a &lt;style&gt; tag, this could then break out of
    * the style context into HTML.
-   *
+   * 
    * @param unit the units of the value
    * @return this {@link StylesBuilder}
    */
diff --git a/user/test/com/google/gwt/dom/builder/shared/ElementBuilderTestBase.java b/user/test/com/google/gwt/dom/builder/shared/ElementBuilderTestBase.java
index 295467e..9c4e72f 100644
--- a/user/test/com/google/gwt/dom/builder/shared/ElementBuilderTestBase.java
+++ b/user/test/com/google/gwt/dom/builder/shared/ElementBuilderTestBase.java
@@ -135,11 +135,13 @@
         }
       }
 
-      try {
-        builder.startDiv();
-        fail("Expected IllegalStateException: appending a div after setting text");
-      } catch (IllegalStateException e) {
-        // Expected.
+      if (isChildElementSupported) {
+        try {
+          builder.startDiv();
+          fail("Expected IllegalStateException: appending a div after setting text");
+        } catch (IllegalStateException e) {
+          // Expected.
+        }
       }
     }
   }
@@ -198,41 +200,13 @@
     }, "Cannot add attribute after appending html");
   }
 
-  public void testEndReturnType() {
-    if (!isChildElementSupported) {
-      return;
-    }
-
-    for (ElementBuilderFactory factory : getFactories()) {
-      T builder = createElementBuilder(factory);
-      DivBuilder divBuilder0 = builder.startDiv();
-      DivBuilder divBuilder1 = divBuilder0.startDiv();
-      assertEquals(divBuilder0, divBuilder1.end());
-      assertEquals(builder, divBuilder0.end());
-      assertNull(builder.end());
-    }
-  }
-
-  public void testEndReturnTypeSpecified() {
-    if (!isChildElementSupported) {
-      return;
-    }
-
-    for (ElementBuilderFactory factory : getFactories()) {
-      T builder = createElementBuilder(factory);
-      DivBuilder divBuilder0 = builder.startDiv();
-      DivBuilder divBuilder1 = divBuilder0.startDiv();
-      assertEquals(divBuilder0, divBuilder1.<DivBuilder> end());
-    }
-  }
-
-  public void testEndSpecifiedType() {
+  public void testEnd() {
     for (ElementBuilderFactory factory : getFactories()) {
       // Test that a builder can be ended if it comes directly from the factory.
       {
         T builder = createElementBuilder(factory);
         builder.id("myid");
-        assertNull(endElement(builder));
+        endElement(builder);
       }
 
       /*
@@ -244,8 +218,8 @@
       if (isChildElementSupported) {
         T builder = createElementBuilder(factory);
         T elem = startElement(builder);
-        assertEquals(builder, endElement(elem));
-        assertNull(builder.end());
+        endElement(elem);
+        builder.end();
       }
     }
   }
@@ -640,9 +614,8 @@
    * End the element within an existing builder.
    * 
    * @param builder the existing builder
-   * @return the builder for the new element
    */
-  protected abstract T endElement(ElementBuilderBase<?> builder);
+  protected abstract void endElement(ElementBuilderBase<?> builder);
 
   /**
    * Get the array of factories to test.
diff --git a/user/test/com/google/gwt/dom/builder/shared/GwtElementBuilderImplTestBase.java b/user/test/com/google/gwt/dom/builder/shared/GwtElementBuilderImplTestBase.java
index 808ec1a..8747617 100644
--- a/user/test/com/google/gwt/dom/builder/shared/GwtElementBuilderImplTestBase.java
+++ b/user/test/com/google/gwt/dom/builder/shared/GwtElementBuilderImplTestBase.java
@@ -73,7 +73,8 @@
       }
       tr.endTR();
     }
-    tbody.endTBody().endTable();
+    tbody.endTBody();
+    tableBuilder.endTable();
 
     // Check the rendered element.
     TableElement table = tableBuilder.finish().cast();
@@ -167,9 +168,9 @@
    * </pre>
    */
   public void testStyleProperties() {
-    Element div =
-        factory.createDivBuilder().style().trustedColor("red").position(Position.ABSOLUTE)
-            .endStyle().text("hello world").finish();
+    DivBuilder divBuilder = factory.createDivBuilder();
+    divBuilder.style().trustedColor("red").position(Position.ABSOLUTE).endStyle();
+    Element div = divBuilder.text("hello world").finish();
     assertTrue("div".equalsIgnoreCase(div.getTagName()));
     assertEquals("hello world", div.getInnerText());
     assertEquals("red", div.getStyle().getColor());
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlAnchorBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlAnchorBuilderTest.java
index f22fb84..215589b 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlAnchorBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlAnchorBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected AnchorBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endAnchor();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endAnchor();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlAreaBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlAreaBuilderTest.java
index b97875d..8561304 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlAreaBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlAreaBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected AreaBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endArea();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endArea();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlAudioBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlAudioBuilderTest.java
index 846f9a6..51b0bf8 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlAudioBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlAudioBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected AudioBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endAudio();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endAudio();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlBRBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlBRBuilderTest.java
index d1b3758..b51ef5a 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlBRBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlBRBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected BRBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endBR();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endBR();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlBaseBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlBaseBuilderTest.java
index 9350a4e..c7efdbd 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlBaseBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlBaseBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected BaseBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endBase();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endBase();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlBodyBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlBodyBuilderTest.java
index c4583f8..674955d 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlBodyBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlBodyBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected BodyBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endBody();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endBody();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlButtonBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlButtonBuilderTest.java
index 7e47393..e99e561 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlButtonBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlButtonBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected ButtonBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endButton();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endButton();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlCanvasBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlCanvasBuilderTest.java
index 8d62b88..52a116a 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlCanvasBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlCanvasBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected CanvasBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endCanvas();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endCanvas();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlDListBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlDListBuilderTest.java
index 48221b5..fafba8f 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlDListBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlDListBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected DListBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endDList();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endDList();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlDivBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlDivBuilderTest.java
index 977c739..34c83c0 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlDivBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlDivBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected DivBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endDiv();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endDiv();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlFieldSetBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlFieldSetBuilderTest.java
index 9f9f47c..9ed0c1a 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlFieldSetBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlFieldSetBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected FieldSetBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endFieldSet();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endFieldSet();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlFormBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlFormBuilderTest.java
index 2af55bf..367179f 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlFormBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlFormBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected FormBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endForm();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endForm();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlFrameBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlFrameBuilderTest.java
index 4780542..272be7f 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlFrameBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlFrameBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected FrameBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endFrame();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endFrame();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlFrameSetBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlFrameSetBuilderTest.java
index fbb2e6f..a324c9d 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlFrameSetBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlFrameSetBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected FrameSetBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endFrameSet();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endFrameSet();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlHRBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlHRBuilderTest.java
index b8655cb..5a2f460 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlHRBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlHRBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected HRBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endHR();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endHR();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlHeadBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlHeadBuilderTest.java
index b360d29..a3b1306 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlHeadBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlHeadBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected HeadBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endHead();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endHead();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlHeadingBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlHeadingBuilderTest.java
index c85a14a..d3fb31f 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlHeadingBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlHeadingBuilderTest.java
@@ -26,22 +26,22 @@
   public void testEndAll() {
     for (ElementBuilderFactory factory : getFactories()) {
       HeadingBuilder h1 = factory.createH1Builder();
-      assertNull(h1.endH1());
+      h1.endH1();
 
       HeadingBuilder h2 = factory.createH2Builder();
-      assertNull(h2.endH2());
+      h2.endH2();
 
       HeadingBuilder h3 = factory.createH3Builder();
-      assertNull(h3.endH3());
+      h3.endH3();
 
       HeadingBuilder h4 = factory.createH4Builder();
-      assertNull(h4.endH4());
+      h4.endH4();
 
       HeadingBuilder h5 = factory.createH5Builder();
-      assertNull(h5.endH5());
+      h5.endH5();
 
       HeadingBuilder h6 = factory.createH6Builder();
-      assertNull(h6.endH6());
+      h6.endH6();
     }
   }
 
@@ -51,8 +51,8 @@
   }
 
   @Override
-  protected HeadingBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endH1();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endH1();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlIFrameBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlIFrameBuilderTest.java
index 88a3eed..7abc3e5 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlIFrameBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlIFrameBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected IFrameBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endIFrame();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endIFrame();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlImageBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlImageBuilderTest.java
index ecead6d..1eba774 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlImageBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlImageBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected ImageBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endImage();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endImage();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlInputBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlInputBuilderTest.java
index 17de4e7..2cac75c 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlInputBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlInputBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected InputBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endInput();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endInput();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlLIBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlLIBuilderTest.java
index bc4513b..4e3d735 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlLIBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlLIBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected LIBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endLI();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endLI();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlLabelBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlLabelBuilderTest.java
index 2da263a..5e1c762 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlLabelBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlLabelBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected LabelBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endLabel();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endLabel();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlLegendBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlLegendBuilderTest.java
index 210be9c..3b744d2 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlLegendBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlLegendBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected LegendBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endLegend();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endLegend();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlLinkBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlLinkBuilderTest.java
index 982d2a2..823e2cf 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlLinkBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlLinkBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected LinkBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endLink();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endLink();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlMapBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlMapBuilderTest.java
index 7746f1a..fa2e79f 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlMapBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlMapBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected MapBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endMap();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endMap();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlMetaBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlMetaBuilderTest.java
index 37b9df0..d01fb93 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlMetaBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlMetaBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected MetaBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endMeta();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endMeta();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlOListBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlOListBuilderTest.java
index e315354..33ea827 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlOListBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlOListBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected OListBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endOList();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endOList();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlOptGroupBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlOptGroupBuilderTest.java
index b064d48..8a1ceb9 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlOptGroupBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlOptGroupBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected OptGroupBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endOptGroup();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endOptGroup();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlOptionBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlOptionBuilderTest.java
index 17de36f..5414b29 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlOptionBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlOptionBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected OptionBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endOption();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endOption();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlParagraphBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlParagraphBuilderTest.java
index 70dce93..5d27c9d 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlParagraphBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlParagraphBuilderTest.java
@@ -25,8 +25,8 @@
     return factory.createParagraphBuilder();
   }
   @Override
-  protected ParagraphBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endParagraph();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endParagraph();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlParamBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlParamBuilderTest.java
index 53afb9a..6ce250c 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlParamBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlParamBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected ParamBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endParam();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endParam();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlPreBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlPreBuilderTest.java
index 5c78ae0..63f1fa8 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlPreBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlPreBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected PreBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endPre();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endPre();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlQuoteBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlQuoteBuilderTest.java
index 6ef75f1..cebe7cc 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlQuoteBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlQuoteBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected QuoteBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endQuote();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endQuote();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlScriptBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlScriptBuilderTest.java
index 83f110a..c440532 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlScriptBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlScriptBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected ScriptBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endScript();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endScript();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlSelectBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlSelectBuilderTest.java
index 0d73ebd..52fd62a 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlSelectBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlSelectBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected SelectBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endSelect();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endSelect();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlSourceBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlSourceBuilderTest.java
index 8489f4b..435bf1e 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlSourceBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlSourceBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected SourceBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endSource();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endSource();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlSpanBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlSpanBuilderTest.java
index 5094f44..240ed45 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlSpanBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlSpanBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected SpanBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endSpan();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endSpan();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlStyleBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlStyleBuilderTest.java
index 23dd36a..abe69c7 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlStyleBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlStyleBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected StyleBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endStyle();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endStyle();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlTableBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlTableBuilderTest.java
index 40835c9..189018b 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlTableBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlTableBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected TableBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endTable();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endTable();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlTableCaptionBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlTableCaptionBuilderTest.java
index a88abcb..7862590 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlTableCaptionBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlTableCaptionBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected TableCaptionBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endTableCaption();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endTableCaption();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlTableCellBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlTableCellBuilderTest.java
index 14e4b1f..719afd7 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlTableCellBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlTableCellBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected TableCellBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endTD();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endTD();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlTableColBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlTableColBuilderTest.java
index c9a5b86..2a786d3 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlTableColBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlTableColBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected TableColBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endCol();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endCol();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlTableRowBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlTableRowBuilderTest.java
index 3b555ba..bcd96df 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlTableRowBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlTableRowBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected TableRowBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endTR();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endTR();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlTableSectionBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlTableSectionBuilderTest.java
index 7db40e8..45228b7 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlTableSectionBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlTableSectionBuilderTest.java
@@ -26,13 +26,13 @@
   public void testEndAll() {
     for (ElementBuilderFactory factory : getFactories()) {
       TableSectionBuilder tbody = factory.createTBodyBuilder();
-      assertNull(tbody.endTBody());
+      tbody.endTBody();
 
       TableSectionBuilder thead = factory.createTHeadBuilder();
-      assertNull(thead.endTHead());
+      thead.endTHead();
 
       TableSectionBuilder tfoot = factory.createTFootBuilder();
-      assertNull(tfoot.endTFoot());
+      tfoot.endTFoot();
     }
   }
 
@@ -42,8 +42,8 @@
   }
 
   @Override
-  protected TableSectionBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endTBody();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endTBody();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlTextAreaBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlTextAreaBuilderTest.java
index 8e3fe61..ac389ed 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlTextAreaBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlTextAreaBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected TextAreaBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endTextArea();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endTextArea();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlTitleBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlTitleBuilderTest.java
index 64f2719..ab46968 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlTitleBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlTitleBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected TitleBuilder endElement(ElementBuilderBase<?> builder) {
-    return ((HtmlElementBuilderBase<?>) builder).endTitle();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    ((HtmlElementBuilderBase<?>) builder).endTitle();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlUListBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlUListBuilderTest.java
index 73289ab..79efd69 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlUListBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlUListBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected UListBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endUList();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endUList();
   }
 
   @Override
diff --git a/user/test/com/google/gwt/dom/builder/shared/HtmlVideoBuilderTest.java b/user/test/com/google/gwt/dom/builder/shared/HtmlVideoBuilderTest.java
index cdfd746..bed2511 100644
--- a/user/test/com/google/gwt/dom/builder/shared/HtmlVideoBuilderTest.java
+++ b/user/test/com/google/gwt/dom/builder/shared/HtmlVideoBuilderTest.java
@@ -26,8 +26,8 @@
   }
 
   @Override
-  protected VideoBuilder endElement(ElementBuilderBase<?> builder) {
-    return builder.endVideo();
+  protected void endElement(ElementBuilderBase<?> builder) {
+    builder.endVideo();
   }
 
   @Override