diff --git a/user/src/com/google/gwt/user/ResizeLayoutPanel.gwt.xml b/user/src/com/google/gwt/user/ResizeLayoutPanel.gwt.xml
new file mode 100644
index 0000000..761ef60
--- /dev/null
+++ b/user/src/com/google/gwt/user/ResizeLayoutPanel.gwt.xml
@@ -0,0 +1,39 @@
+<!--                                                                        -->
+<!-- Copyright 2011 Google Inc.                                             -->
+<!-- Licensed under the Apache License, Version 2.0 (the "License"); you    -->
+<!-- may not use this file except in compliance with the License. You may   -->
+<!-- may obtain a copy of the License at                                    -->
+<!--                                                                        -->
+<!-- http://www.apache.org/licenses/LICENSE-2.0                             -->
+<!--                                                                        -->
+<!-- Unless required by applicable law or agreed to in writing, software    -->
+<!-- distributed under the License is distributed on an "AS IS" BASIS,      -->
+<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        -->
+<!-- implied. License for the specific language governing permissions and   -->
+<!-- limitations under the License.                                         -->
+
+<!-- Deferred binding rules for ResizeLayoutPanel.                          -->
+<!--                                                                        -->
+<!-- This module is typically inherited via com.google.gwt.user.User        -->
+<!--                                                                        -->
+<module>
+  <inherits name="com.google.gwt.core.Core"/>
+  <inherits name="com.google.gwt.user.UserAgent"/>
+
+  <!-- Most browsers do not support onresize. -->
+  <replace-with class="com.google.gwt.user.client.ui.ResizeLayoutPanel.ImplStandard">
+    <when-type-is class="com.google.gwt.user.client.ui.ResizeLayoutPanel.Impl"/>
+  </replace-with>
+
+  <!-- IE supports onresize. -->
+  <replace-with class="com.google.gwt.user.client.ui.ResizeLayoutPanel.ImplTrident">
+    <when-type-is class="com.google.gwt.user.client.ui.ResizeLayoutPanel.Impl"/>
+    <when-property-is name="user.agent" value="ie8"/>
+  </replace-with>
+
+  <!-- IE6 needs to be kicked to render correctly. -->
+  <replace-with class="com.google.gwt.user.client.ui.ResizeLayoutPanel.ImplIE6">
+    <when-type-is class="com.google.gwt.user.client.ui.ResizeLayoutPanel.Impl"/>
+    <when-property-is name="user.agent" value="ie6"/>
+  </replace-with>
+</module>
diff --git a/user/src/com/google/gwt/user/User.gwt.xml b/user/src/com/google/gwt/user/User.gwt.xml
index 905c37e..062966a 100644
--- a/user/src/com/google/gwt/user/User.gwt.xml
+++ b/user/src/com/google/gwt/user/User.gwt.xml
@@ -48,6 +48,7 @@
    <inherits name="com.google.gwt.user.Tree"/>
    <inherits name="com.google.gwt.user.Hyperlink"/>
    <inherits name="com.google.gwt.user.FileUpload"/>
+   <inherits name="com.google.gwt.user.ResizeLayoutPanel"/>
    <inherits name="com.google.gwt.user.datepicker.DatePicker"/>
    <inherits name="com.google.gwt.user.cellview.CellView"/>
    <inherits name="com.google.gwt.safehtml.SafeHtml" />
diff --git a/user/src/com/google/gwt/user/client/ui/HeaderPanel.java b/user/src/com/google/gwt/user/client/ui/HeaderPanel.java
new file mode 100644
index 0000000..4a58724
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/ui/HeaderPanel.java
@@ -0,0 +1,376 @@
+/*
+ * Copyright 2011 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.user.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.Style.Display;
+import com.google.gwt.dom.client.Style.Overflow;
+import com.google.gwt.dom.client.Style.Position;
+import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.user.client.Element;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * A panel that includes a header (top), footer (bottom), and content (middle)
+ * area. The header and footer areas resize naturally. The content area is
+ * allocated all of the remaining space between the header and footer area.
+ */
+public class HeaderPanel extends Panel implements RequiresResize {
+
+  private Widget content;
+  private final Element contentContainer;
+  private Widget footer;
+  private final Element footerContainer;
+  private final ResizeLayoutPanel.Impl footerImpl =
+    GWT.create(ResizeLayoutPanel.Impl.class);
+  private Widget header;
+  private final Element headerContainer;
+  private final ResizeLayoutPanel.Impl headerImpl =
+    GWT.create(ResizeLayoutPanel.Impl.class);
+  private final ScheduledCommand layoutCmd = new ScheduledCommand() {
+    public void execute() {
+      layoutScheduled = false;
+      forceLayout();
+    }
+  };
+  private boolean layoutScheduled = false;
+
+  public HeaderPanel() {
+    // Create the outer element
+    Element elem = Document.get().createDivElement().cast();
+    elem.getStyle().setPosition(Position.RELATIVE);
+    elem.getStyle().setOverflow(Overflow.HIDDEN);
+    setElement(elem);
+
+    // Create a delegate to handle resize from the header and footer.
+    ResizeLayoutPanel.Impl.Delegate resizeDelegate = new ResizeLayoutPanel.Impl.Delegate() {
+      public void onResize() {
+        scheduledLayout();
+      }
+    };
+
+    // Create the header container.
+    headerContainer = createContainer();
+    headerContainer.getStyle().setTop(0.0, Unit.PX);
+    headerImpl.init(headerContainer, resizeDelegate);
+    elem.appendChild(headerContainer);
+
+    // Create the footer container.
+    footerContainer = createContainer();
+    footerContainer.getStyle().setBottom(0.0, Unit.PX);
+    footerImpl.init(footerContainer, resizeDelegate);
+    elem.appendChild(footerContainer);
+
+    // Create the content container.
+    contentContainer = createContainer();
+    contentContainer.getStyle().setOverflow(Overflow.HIDDEN);
+    contentContainer.getStyle().setTop(0.0, Unit.PX);
+    contentContainer.getStyle().setHeight(0.0, Unit.PX);
+    elem.appendChild(contentContainer);
+  }
+
+  /**
+   * Adds a widget to this panel.
+   * 
+   * @param w the child widget to be added
+   */
+  @Override
+  public void add(Widget w) {
+    // Add widgets in the order that they appear.
+    if (header == null) {
+      setHeaderWidget(w);
+    } else if (content == null) {
+      setContentWidget(w);
+    } else if (footer == null) {
+      setFooterWidget(w);
+    } else {
+      throw new IllegalStateException(
+          "HeaderPanel already contains header, content, and footer widgets.");
+    }
+  }
+
+  /**
+   * Get the content widget that appears between the header and footer.
+   * 
+   * @return the content {@link Widget}
+   */
+  public Widget getContentWidget() {
+    return content;
+  }
+
+  /**
+   * Get the footer widget at the bottom of the panel.
+   * 
+   * @return the footer {@link Widget}
+   */
+  public Widget getFooterWidget() {
+    return footer;
+  }
+
+  /**
+   * Get the header widget at the top of the panel.
+   * 
+   * @return the header {@link Widget}
+   */
+  public Widget getHeaderWidget() {
+    return header;
+  }
+
+  public Iterator<Widget> iterator() {
+    // Return a simple iterator that iterates over the header, content, and
+    // footer in order.
+    return new Iterator<Widget>() {
+      private int index = -1;
+
+      public boolean hasNext() {
+        switch (index) {
+          case -1:
+            if (header != null) {
+              return true;
+            }
+          case 0: // Intentional fallthrough.
+            if (content != null) {
+              return true;
+            }
+          case 1: // Intentional fallthrough.
+            if (footer != null) {
+              return true;
+            }
+        }
+        return false;
+      }
+
+      public Widget next() {
+        switch (index) {
+          case -1:
+            index++;
+            if (header != null) {
+              return header;
+            }
+          case 0: // Intentional fallthrough.
+            index++;
+            if (content != null) {
+              return content;
+            }
+          case 1: // Intentional fallthrough.
+            index++;
+            if (footer != null) {
+              return footer;
+            }
+        }
+        throw new NoSuchElementException();
+      }
+
+      public void remove() {
+        switch (index) {
+          case 0:
+            doRemove(header, "Header");
+            break;
+          case 1:
+            doRemove(content, "Content");
+            break;
+          case 2:
+            doRemove(footer, "Footer");
+            break;
+          default:
+            throw new IllegalStateException();
+        }
+      }
+
+      private void doRemove(Widget widget, String position) {
+        if (widget == null) {
+          throw new IllegalStateException(position + " was already removed.");
+        }
+        HeaderPanel.this.remove(widget);
+      }
+    };
+  }
+
+  @Override
+  public void onAttach() {
+    super.onAttach();
+    headerImpl.onAttach();
+    footerImpl.onAttach();
+    scheduledLayout();
+  }
+
+  @Override
+  public void onDetach() {
+    super.onDetach();
+    headerImpl.onDetach();
+    footerImpl.onDetach();
+  }
+
+  public void onResize() {
+    // Handle the outer element resizing.
+    scheduledLayout();
+  }
+
+  @Override
+  public boolean remove(Widget w) {
+    // Validate.
+    if (w.getParent() != this) {
+      return false;
+    }
+    // Orphan.
+    try {
+      orphan(w);
+    } finally {
+      // Physical detach.
+      w.getElement().removeFromParent();
+
+      // Logical detach.
+      if (w == content) {
+        content = null;
+        contentContainer.getStyle().setDisplay(Display.NONE);
+      } else if (w == header) {
+        header = null;
+        headerContainer.getStyle().setDisplay(Display.NONE);
+      } else if (w == footer) {
+        footer = null;
+        footerContainer.getStyle().setDisplay(Display.NONE);
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Set the widget in the content portion between the header and footer.
+   * 
+   * @param w the widget to use as the content
+   */
+  public void setContentWidget(Widget w) {
+    contentContainer.getStyle().clearDisplay();
+    add(w, content, contentContainer);
+
+    // Logical attach.
+    content = w;
+    scheduledLayout();
+  }
+
+  /**
+   * Set the widget in the footer portion at the bottom of the panel.
+   * 
+   * @param w the widget to use as the footer
+   */
+  public void setFooterWidget(Widget w) {
+    footerContainer.getStyle().clearDisplay();
+    add(w, footer, footerContainer);
+
+    // Logical attach.
+    footer = w;
+    scheduledLayout();
+  }
+
+  /**
+   * Set the widget in the header portion at the top of the panel.
+   * 
+   * @param w the widget to use as the header
+   */
+  public void setHeaderWidget(Widget w) {
+    headerContainer.getStyle().clearDisplay();
+    add(w, header, headerContainer);
+
+    // Logical attach.
+    header = w;
+    scheduledLayout();
+  }
+
+  /**
+   * Add a widget to the panel in the specified container. Note that this method
+   * does not do the logical attach.
+   * 
+   * @param w the widget to add
+   * @param toReplace the widget to replace
+   * @param container the container in which to place the widget
+   */
+  private void add(Widget w, Widget toReplace, Element container) {
+    // Validate.
+    if (w == toReplace) {
+      return;
+    }
+
+    // Detach new child.
+    if (w != null) {
+      w.removeFromParent();
+    }
+
+    // Remove old child.
+    if (toReplace != null) {
+      remove(toReplace);
+    }
+
+    if (w != null) {
+      // Physical attach.
+      container.appendChild(w.getElement());
+
+      adopt(w);
+    }
+  }
+
+  private Element createContainer() {
+    Element container = Document.get().createDivElement().cast();
+    container.getStyle().setPosition(Position.ABSOLUTE);
+    container.getStyle().setDisplay(Display.NONE);
+    container.getStyle().setLeft(0.0, Unit.PX);
+    container.getStyle().setWidth(100.0, Unit.PCT);
+    return container;
+  }
+
+  /**
+   * Update the layout.
+   */
+  private void forceLayout() {
+    // No sense in doing layout if we aren't attached or have no content.
+    if (!isAttached() || content == null) {
+      return;
+    }
+
+    // Resize the content area to fit between the header and footer.
+    int remainingHeight = getElement().getClientHeight();
+    if (header != null) {
+      int height = Math.max(0, headerContainer.getOffsetHeight());
+      remainingHeight -= height;
+      contentContainer.getStyle().setTop(height, Unit.PX);
+    } else {
+      contentContainer.getStyle().setTop(0.0, Unit.PX);
+    }
+    if (footer != null) {
+      remainingHeight -= footerContainer.getOffsetHeight();
+    }
+    contentContainer.getStyle().setHeight(Math.max(0, remainingHeight), Unit.PX);
+
+    // Provide resize to child.
+    if (content instanceof RequiresResize) {
+      ((RequiresResize) content).onResize();
+    }
+  }
+
+  /**
+   * Schedule layout to adjust the height of the content area.
+   */
+  private void scheduledLayout() {
+    if (isAttached() && !layoutScheduled) {
+      layoutScheduled = true;
+      Scheduler.get().scheduleDeferred(layoutCmd);
+    }
+  }
+}
diff --git a/user/src/com/google/gwt/user/client/ui/ResizeLayoutPanel.java b/user/src/com/google/gwt/user/client/ui/ResizeLayoutPanel.java
new file mode 100644
index 0000000..ab9a885
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/ui/ResizeLayoutPanel.java
@@ -0,0 +1,440 @@
+/*
+ * Copyright 2011 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.user.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.EventTarget;
+import com.google.gwt.dom.client.Style.Overflow;
+import com.google.gwt.dom.client.Style.Position;
+import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.dom.client.Style.Visibility;
+import com.google.gwt.event.logical.shared.HasResizeHandlers;
+import com.google.gwt.event.logical.shared.ResizeEvent;
+import com.google.gwt.event.logical.shared.ResizeHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.layout.client.Layout;
+import com.google.gwt.layout.client.Layout.Layer;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.EventListener;
+import com.google.gwt.user.client.ui.ResizeLayoutPanel.Impl.Delegate;
+
+/**
+ * A simple panel that {@link ProvidesResize} to its one child, but does not
+ * {@link RequiresResize}. Use this to embed layout panels in any location
+ * within your application.
+ */
+public class ResizeLayoutPanel extends SimplePanel implements ProvidesResize,
+    HasResizeHandlers {
+
+  /**
+   * Implementation of resize event.
+   */
+  abstract static class Impl {
+    /**
+     * Delegate event handler.
+     */
+    abstract static interface Delegate {
+      /**
+       * Called when the element is resized.
+       */
+      void onResize();
+    }
+
+    boolean isAttached;
+    Element parent;
+    private Delegate delegate;
+
+    /**
+     * Initialize the implementation.
+     * 
+     * @param elem the element to listen for resize
+     * @param delegate the {@link Delegate} to inform when resize occurs
+     */
+    public void init(Element elem, Delegate delegate) {
+      this.parent = elem;
+      this.delegate = delegate;
+    }
+
+    /**
+     * Called on attach.
+     */
+    public void onAttach() {
+      isAttached = true;
+    }
+
+    /**
+     * Called on detach.
+     * 
+     * @param panel the panel
+     */
+    public void onDetach() {
+      isAttached = false;
+    }
+
+    /**
+     * Handle a resize event.
+     * 
+     * @param panel the panel
+     */
+    protected void handleResize() {
+      if (isAttached && delegate != null) {
+        delegate.onResize();
+      }
+    }
+  }
+
+  /**
+   * Implementation of resize event.
+   */
+  static class ImplStandard extends Impl implements EventListener {
+    /**
+     * Chrome does not fire an onresize event if the dimensions are too small to
+     * render a scrollbar.
+     */
+    private static final String MIN_SIZE = "20px";
+
+    private Element collapsible;
+    private Element collapsibleInner;
+    private Element expandable;
+    private Element expandableInner;
+    private int lastOffsetHeight = -1;
+    private int lastOffsetWidth = -1;
+
+    @Override
+    public void init(Element elem, Delegate delegate) {
+      super.init(elem, delegate);
+
+      /*
+       * Set the minimum dimensions to ensure that scrollbars are rendered and
+       * fire onscroll events.
+       */
+      elem.getStyle().setProperty("minWidth", MIN_SIZE);
+      elem.getStyle().setProperty("minHeight", MIN_SIZE);
+
+      /*
+       * Detect expansion. In order to detect an increase in the size of the
+       * widget, we create an absolutely positioned, scrollable div with
+       * height=width=100%. We then add an inner div that has fixed height and
+       * width equal to 100% (converted to pixels) and set scrollLeft/scrollTop
+       * to their maximum. When the outer div expands, scrollLeft/scrollTop
+       * automatically becomes a smaller number and trigger an onscroll event.
+       */
+      expandable = Document.get().createDivElement().cast();
+      expandable.getStyle().setVisibility(Visibility.HIDDEN);
+      expandable.getStyle().setPosition(Position.ABSOLUTE);
+      expandable.getStyle().setHeight(100.0, Unit.PCT);
+      expandable.getStyle().setWidth(100.0, Unit.PCT);
+      expandable.getStyle().setOverflow(Overflow.SCROLL);
+      elem.appendChild(expandable);
+      expandableInner = Document.get().createDivElement().cast();
+      expandable.appendChild(expandableInner);
+      DOM.sinkEvents(expandable, Event.ONSCROLL);
+
+      /*
+       * Detect collapse. In order to detect a decrease in the size of the
+       * widget, we create an absolutely positioned, scrollable div with
+       * height=width=100%. We then add an inner div that has height=width=200%
+       * and max out the scrollTop/scrollLeft. When the height or width
+       * decreases, the inner div loses 2px for every 1px that the scrollable
+       * div loses, so the scrollTop/scrollLeft decrease and we get an onscroll
+       * event.
+       */
+      collapsible = Document.get().createDivElement().cast();
+      collapsible.getStyle().setVisibility(Visibility.HIDDEN);
+      collapsible.getStyle().setPosition(Position.ABSOLUTE);
+      collapsible.getStyle().setHeight(100.0, Unit.PCT);
+      collapsible.getStyle().setWidth(100.0, Unit.PCT);
+      collapsible.getStyle().setOverflow(Overflow.SCROLL);
+      elem.appendChild(collapsible);
+      collapsibleInner = Document.get().createDivElement().cast();
+      collapsibleInner.getStyle().setWidth(200, Unit.PCT);
+      collapsibleInner.getStyle().setHeight(200, Unit.PCT);
+      collapsible.appendChild(collapsibleInner);
+      DOM.sinkEvents(collapsible, Event.ONSCROLL);
+    }
+
+    @Override
+    public void onAttach() {
+      super.onAttach();
+      DOM.setEventListener(expandable, this);
+      DOM.setEventListener(collapsible, this);
+
+      /*
+       * Update the scrollables in a deferred command so the browser calculates
+       * the offsetHeight/Width correctly.
+       */
+      Scheduler.get().scheduleDeferred(new ScheduledCommand() {
+        public void execute() {
+          resetScrollables();
+        }
+      });
+    }
+
+    public void onBrowserEvent(Event event) {
+      if (Event.ONSCROLL == event.getTypeInt()) {
+        EventTarget eventTarget = event.getEventTarget();
+        if (!Element.is(eventTarget)) {
+          return;
+        }
+        Element target = eventTarget.cast();
+        if (target == collapsible || target == expandable) {
+          handleResize();
+        }
+      }
+    }
+
+    @Override
+    public void onDetach() {
+      super.onDetach();
+      DOM.setEventListener(expandable, null);
+      DOM.setEventListener(collapsible, null);
+      lastOffsetHeight = -1;
+      lastOffsetWidth = -1;
+    }
+
+    @Override
+    protected void handleResize() {
+      if (resetScrollables()) {
+        super.handleResize();
+      }
+    }
+
+    /**
+     * Reset the positions of the scrollable elements.
+     * 
+     * @return true if the size changed, false if not
+     */
+    private boolean resetScrollables() {
+      /*
+       * Reset expandable element. Scrollbars are not rendered if the div is too
+       * small, so we need to set the dimensions of the inner div to a value
+       * greater than the offsetWidth/Height.
+       */
+      int offsetHeight = parent.getOffsetHeight();
+      int offsetWidth = parent.getOffsetWidth();
+      int height = offsetHeight + 100;
+      int width = offsetWidth + 100;
+      expandableInner.getStyle().setHeight(height, Unit.PX);
+      expandableInner.getStyle().setWidth(width, Unit.PX);
+      expandable.setScrollTop(height);
+      expandable.setScrollLeft(width);
+
+      // Reset collapsible element.
+      collapsible.setScrollTop(collapsible.getScrollHeight() + 100);
+      collapsible.setScrollLeft(collapsible.getScrollWidth() + 100);
+
+      if (lastOffsetHeight != offsetHeight || lastOffsetWidth != offsetWidth) {
+        lastOffsetHeight = offsetHeight;
+        lastOffsetWidth = offsetWidth;
+        return true;
+      }
+      return false;
+    }
+  }
+
+  /**
+   * Implementation of resize event used by IE.
+   */
+  static class ImplTrident extends Impl {
+
+    @Override
+    public void init(Element elem, Delegate delegate) {
+      super.init(elem, delegate);
+      initResizeEventListener(elem);
+    }
+
+    @Override
+    public void onAttach() {
+      super.onAttach();
+      setResizeEventListener(parent, this);
+    }
+
+    @Override
+    public void onDetach() {
+      super.onDetach();
+      setResizeEventListener(parent, null);
+    }
+
+    /**
+     * Initalize the onresize listener. This method doesn't create a memory leak
+     * because we don't set a back reference to the Impl class until we attach
+     * to the DOM.
+     */
+    private native void initResizeEventListener(Element elem) /*-{
+      var theElem = elem;
+      var handleResize = $entry(function() {
+        if (theElem.__resizeImpl) {
+          theElem.__resizeImpl.@com.google.gwt.user.client.ui.ResizeLayoutPanel.Impl::handleResize()();
+        }
+      });
+      elem.attachEvent('onresize', handleResize);
+    }-*/;
+
+    /**
+     * Set the event listener that handles resize events.
+     */
+    private native void setResizeEventListener(Element elem, Impl listener) /*-{
+      elem.__resizeImpl = listener;
+    }-*/;
+  }
+
+  /**
+   * Implementation of resize event used by IE6.
+   */
+  static class ImplIE6 extends ImplTrident {
+    @Override
+    public void onAttach() {
+      super.onAttach();
+
+      /*
+       * IE6 doesn't render this panel unless you kick it after its been
+       * attached.
+       */
+      Scheduler.get().scheduleDeferred(new ScheduledCommand() {
+        public void execute() {
+          if (isAttached) {
+            parent.getStyle().setProperty("zoom", "1");
+          }
+        }
+      });
+    }
+  }
+
+  private final Impl impl = GWT.create(Impl.class);
+  private Layer layer;
+  private final Layout layout;
+  private final ScheduledCommand resizeCmd = new ScheduledCommand() {
+    public void execute() {
+      resizeCmdScheduled = false;
+      handleResize();
+    }
+  };
+  private boolean resizeCmdScheduled = false;
+
+  public ResizeLayoutPanel() {
+    layout = new Layout(getElement());
+    impl.init(getElement(), new Delegate() {
+      public void onResize() {
+        scheduleResize();
+      }
+    });
+  }
+
+  public HandlerRegistration addResizeHandler(ResizeHandler handler) {
+    return addHandler(handler, ResizeEvent.getType());
+  }
+
+  @Override
+  public boolean remove(Widget w) {
+    // Validate.
+    if (widget != w) {
+      return false;
+    }
+
+    // Orphan.
+    try {
+      orphan(w);
+    } finally {
+      // Physical detach.
+      layout.removeChild(layer);
+      layer = null;
+
+      // Logical detach.
+      widget = null;
+    }
+    return true;
+  }
+
+  @Override
+  public void setWidget(Widget w) {
+    // Validate
+    if (w == widget) {
+      return;
+    }
+
+    // Detach new child.
+    if (w != null) {
+      w.removeFromParent();
+    }
+
+    // Remove old child.
+    if (widget != null) {
+      remove(widget);
+    }
+
+    // Logical attach.
+    widget = w;
+
+    if (w != null) {
+      // Physical attach.
+      layer = layout.attachChild(widget.getElement(), widget);
+      layer.setTopHeight(0.0, Unit.PX, 100.0, Unit.PCT);
+      layer.setLeftWidth(0.0, Unit.PX, 100.0, Unit.PCT);
+
+      adopt(w);
+
+      // Update the layout.
+      layout.layout();
+      scheduleResize();
+    }
+  }
+
+  @Override
+  protected void onAttach() {
+    super.onAttach();
+    impl.onAttach();
+    layout.onAttach();
+    scheduleResize();
+  }
+
+  @Override
+  protected void onDetach() {
+    super.onDetach();
+    impl.onDetach();
+    layout.onDetach();
+  }
+
+  private void handleResize() {
+    if (!isAttached()) {
+      return;
+    }
+
+    // Provide resize to child.
+    if (widget instanceof RequiresResize) {
+      ((RequiresResize) widget).onResize();
+    }
+
+    // Fire resize event.
+    ResizeEvent.fire(this, getOffsetWidth(), getOffsetHeight());
+  }
+
+  /**
+   * Schedule a resize handler. We schedule the event so the DOM has time to
+   * update the offset sizes, and to avoid duplicate resize events from both a
+   * height and width resize.
+   */
+  private void scheduleResize() {
+    if (isAttached() && !resizeCmdScheduled) {
+      resizeCmdScheduled = true;
+      Scheduler.get().scheduleDeferred(resizeCmd);
+    }
+  }
+}
diff --git a/user/test/com/google/gwt/user/UISuite.java b/user/test/com/google/gwt/user/UISuite.java
index 0befacf..d88f438 100644
--- a/user/test/com/google/gwt/user/UISuite.java
+++ b/user/test/com/google/gwt/user/UISuite.java
@@ -62,6 +62,7 @@
 import com.google.gwt.user.client.ui.GridTest;
 import com.google.gwt.user.client.ui.HTMLPanelTest;
 import com.google.gwt.user.client.ui.HTMLTest;
+import com.google.gwt.user.client.ui.HeaderPanelTest;
 import com.google.gwt.user.client.ui.HiddenTest;
 import com.google.gwt.user.client.ui.HistoryTest;
 import com.google.gwt.user.client.ui.HorizontalPanelTest;
@@ -82,6 +83,7 @@
 import com.google.gwt.user.client.ui.PrefixTreeTest;
 import com.google.gwt.user.client.ui.RadioButtonTest;
 import com.google.gwt.user.client.ui.ResetButtonTest;
+import com.google.gwt.user.client.ui.ResizeLayoutPanelTest;
 import com.google.gwt.user.client.ui.RichTextAreaTest;
 import com.google.gwt.user.client.ui.RootPanelTest;
 import com.google.gwt.user.client.ui.ScrollPanelTest;
@@ -169,6 +171,7 @@
     suite.addTestSuite(FormPanelTest.class);
     suite.addTestSuite(GestureEventSinkTest.class);
     suite.addTestSuite(GridTest.class);
+    suite.addTestSuite(HeaderPanelTest.class);
     suite.addTestSuite(HiddenTest.class);
     suite.addTestSuite(HistoryTest.class);
     suite.addTestSuite(HistoryDisabledTest.class);
@@ -194,6 +197,7 @@
     suite.addTestSuite(PrefixTreeTest.class);
     suite.addTestSuite(RadioButtonTest.class);
     suite.addTestSuite(ResetButtonTest.class);
+    suite.addTestSuite(ResizeLayoutPanelTest.class);
     suite.addTestSuite(RichTextAreaTest.class);
     suite.addTestSuite(RootPanelTest.class);
     suite.addTestSuite(ScrollPanelTest.class);
diff --git a/user/test/com/google/gwt/user/client/ui/HeaderPanelTest.java b/user/test/com/google/gwt/user/client/ui/HeaderPanelTest.java
new file mode 100644
index 0000000..f90cafd
--- /dev/null
+++ b/user/test/com/google/gwt/user/client/ui/HeaderPanelTest.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2011 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.user.client.ui;
+
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+import com.google.gwt.junit.DoNotRunWith;
+import com.google.gwt.junit.Platform;
+import com.google.gwt.user.client.Timer;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Tests for {@link HeaderPanel}.
+ */
+public class HeaderPanelTest extends PanelTestBase<HeaderPanel> {
+
+  public void testAdd() {
+    HeaderPanel panel = createPanel();
+
+    // Add the header first.
+    Label header = new Label("header");
+    panel.add(header);
+    assertEquals(header, panel.getHeaderWidget());
+    assertEquals(null, panel.getContentWidget());
+    assertEquals(null, panel.getFooterWidget());
+
+    // Add the content second.
+    Label content = new Label("content");
+    panel.add(content);
+    assertEquals(header, panel.getHeaderWidget());
+    assertEquals(content, panel.getContentWidget());
+    assertEquals(null, panel.getFooterWidget());
+
+    // Add the footer third.
+    Label footer = new Label("footer");
+    panel.add(footer);
+    assertEquals(header, panel.getHeaderWidget());
+    assertEquals(content, panel.getContentWidget());
+    assertEquals(footer, panel.getFooterWidget());
+
+    // Cannot add a fourth widget.
+    try {
+      panel.add(new Label());
+      fail("Expected IllegalStateException");
+    } catch (IllegalStateException e) {
+      // Expected.
+    }
+  }
+
+  public void testIterator() {
+    final HeaderPanel panel = createPanel();
+
+    // Empty iterator.
+    Iterator<Widget> iter = panel.iterator();
+    assertFalse(iter.hasNext());
+    try {
+      iter.next();
+      fail("Expected NoSuchElementException");
+    } catch (NoSuchElementException e) {
+      // Expected.
+    }
+    try {
+      iter.remove();
+      fail("Expected IllegalStateException");
+    } catch (IllegalStateException e) {
+      // Expected.
+    }
+
+    // Only a content.
+    Label content = new Label("content");
+    panel.setContentWidget(content);
+    iter = panel.iterator();
+    assertTrue(iter.hasNext());
+    assertEquals(content, iter.next());
+    assertFalse(iter.hasNext());
+    try {
+      iter.next();
+      fail("Expected NoSuchElementException");
+    } catch (NoSuchElementException e) {
+      // Expected.
+    }
+
+    // Header, Content, Footer.
+    Label header = new Label("header");
+    Label footer = new Label("footer");
+    panel.setHeaderWidget(header);
+    panel.setFooterWidget(footer);
+    iter = panel.iterator();
+    assertTrue(iter.hasNext());
+    assertEquals(header, iter.next());
+    assertTrue(iter.hasNext());
+    assertEquals(content, iter.next());
+    assertTrue(iter.hasNext());
+    assertEquals(footer, iter.next());
+    assertFalse(iter.hasNext());
+    try {
+      iter.next();
+      fail("Expected NoSuchElementException");
+    } catch (NoSuchElementException e) {
+      // Expected.
+    }
+
+    // Remove Content.
+    iter = panel.iterator();
+    assertEquals(header, iter.next());
+    assertEquals(content, iter.next());
+    iter.remove();
+    assertEquals(header, panel.getHeaderWidget());
+    assertNull(panel.getContentWidget());
+    assertEquals(footer, panel.getFooterWidget());
+    try {
+      iter.remove();
+      fail("Expected IllegalStateException");
+    } catch (IllegalStateException e) {
+      // Expected - cannot remove twice.
+    }
+    assertEquals(footer, iter.next());
+  }
+
+  @DoNotRunWith(Platform.HtmlUnitLayout)
+  public void testResizeFooter() {
+    final HeaderPanel panel = createPanel();
+    panel.setSize("200px", "400px");
+    RootPanel.get().add(panel);
+
+    final Label header = new Label();
+    header.setSize("100%", "50px");
+    panel.setHeaderWidget(header);
+
+    final Label content = new Label();
+    content.setHeight("100%");
+    panel.setContentWidget(content);
+
+    final Label footer = new Label();
+    footer.setSize("100%", "50px");
+    panel.setFooterWidget(footer);
+
+    delayTestFinish(5000);
+    Scheduler.get().scheduleDeferred(new ScheduledCommand() {
+      public void execute() {
+        assertEquals(300, content.getOffsetHeight());
+
+        // Resize the footer.
+        footer.setHeight("75px");
+        new Timer() {
+          @Override
+          public void run() {
+            assertEquals(275, content.getOffsetHeight());
+            RootPanel.get().remove(panel);
+            finishTest();
+          }
+        }.schedule(250);;
+      }
+    });
+  }
+
+  @DoNotRunWith(Platform.HtmlUnitLayout)
+  public void testResizeHeader() {
+    final HeaderPanel panel = createPanel();
+    panel.setSize("200px", "400px");
+    RootPanel.get().add(panel);
+
+    final Label header = new Label();
+    header.setSize("100%", "50px");
+    panel.setHeaderWidget(header);
+
+    final Label content = new Label();
+    content.setHeight("100%");
+    panel.setContentWidget(content);
+
+    final Label footer = new Label();
+    footer.setSize("100%", "50px");
+    panel.setFooterWidget(footer);
+
+    delayTestFinish(5000);
+    Scheduler.get().scheduleDeferred(new ScheduledCommand() {
+      public void execute() {
+        assertEquals(300, content.getOffsetHeight());
+
+        // Resize the header.
+        header.setHeight("75px");
+        new Timer() {
+          @Override
+          public void run() {
+            assertEquals(275, content.getOffsetHeight());
+            RootPanel.get().remove(panel);
+            finishTest();
+          }
+        }.schedule(250);;
+      }
+    });
+  }
+
+  public void testSetContentWidget() {
+    HeaderPanel panel = createPanel();
+    Label widget = new Label("hello world");
+    panel.setContentWidget(widget);
+    assertEquals(widget, panel.getContentWidget());
+
+    panel.remove(widget);
+    assertNull(panel.getContentWidget());
+  }
+
+  public void testSetFooterWidget() {
+    HeaderPanel panel = createPanel();
+    Label widget = new Label("hello world");
+    panel.setHeaderWidget(widget);
+    assertEquals(widget, panel.getHeaderWidget());
+
+    panel.remove(widget);
+    assertNull(panel.getHeaderWidget());
+  }
+
+  public void testSetHeaderWidget() {
+    HeaderPanel panel = createPanel();
+    Label widget = new Label("hello world");
+    panel.setFooterWidget(widget);
+    assertEquals(widget, panel.getFooterWidget());
+
+    panel.remove(widget);
+    assertNull(panel.getFooterWidget());
+  }
+
+  @Override
+  protected HeaderPanel createPanel() {
+    return new HeaderPanel();
+  }
+
+  @Override
+  protected boolean supportsMultipleWidgets() {
+    // HeaderPanel supports up to 3 widgets, but not an unbounded number.
+    return false;
+  }
+}
diff --git a/user/test/com/google/gwt/user/client/ui/ResizeLayoutPanelTest.java b/user/test/com/google/gwt/user/client/ui/ResizeLayoutPanelTest.java
new file mode 100644
index 0000000..ca82d5d
--- /dev/null
+++ b/user/test/com/google/gwt/user/client/ui/ResizeLayoutPanelTest.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright 2011 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.user.client.ui;
+
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.event.logical.shared.ResizeEvent;
+import com.google.gwt.event.logical.shared.ResizeHandler;
+import com.google.gwt.junit.DoNotRunWith;
+import com.google.gwt.junit.Platform;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.Timer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link ResizeLayoutPanel}.
+ */
+public class ResizeLayoutPanelTest extends
+    SimplePanelTestBase<ResizeLayoutPanel> {
+
+  /**
+   * A custom implementation of {@link ResizeHandler} used for testing.
+   */
+  private static class CustomResizeHandler implements ResizeHandler {
+
+    private boolean resizeFired;
+
+    public void assertResizeFired(boolean expected) {
+      assertEquals(expected, resizeFired);
+      resizeFired = false;
+    }
+
+    public void onResize(ResizeEvent event) {
+      assertFalse(resizeFired);
+      resizeFired = true;
+    }
+  }
+
+  @Override
+  public String getModuleName() {
+    return "com.google.gwt.user.User";
+  }
+
+  /**
+   * Test that a resize event is fired on attach.
+   */
+  public void testAttach() {
+    final ResizeLayoutPanel panel = createPanel();
+    panel.setWidget(new Label("hello world"));
+    final CustomResizeHandler handler = new CustomResizeHandler();
+    panel.addResizeHandler(handler);
+    handler.assertResizeFired(false);
+
+    delayTestFinish(10000);
+    RootPanel.get().add(panel);
+    Scheduler.get().scheduleDeferred(new ScheduledCommand() {
+      public void execute() {
+        handler.assertResizeFired(true);
+        panel.removeFromParent();
+        finishTest();
+      }
+    });
+  }
+
+  /**
+   * Test that changing the font size triggers a resize event.
+   */
+  @DoNotRunWith(Platform.HtmlUnitLayout)
+  public void testChangeFontSize() {
+    // Create a panel and add a handler.
+    ResizeLayoutPanel panel = createPanel();
+    panel.setWidget(new Label("hello world"));
+    panel.setWidth("10em");
+    panel.setHeight("10em");
+    final CustomResizeHandler handler = new CustomResizeHandler();
+    panel.addResizeHandler(handler);
+    handler.assertResizeFired(false);
+
+    // Create an outer container and attach it.
+    final SimplePanel container = new SimplePanel();
+    container.getElement().getStyle().setFontSize(10, Unit.PT);
+    container.setHeight("10em");
+    container.setWidth("10em");
+    container.setWidget(panel);
+    RootPanel.get().add(container);
+
+    // Wait for the resize event from attaching.
+    delayTestFinish(10000);
+    Scheduler.get().scheduleDeferred(new ScheduledCommand() {
+      public void execute() {
+        handler.assertResizeFired(true); // Triggered by attach.
+        handler.assertResizeFired(false);
+
+        // Change the font size.
+        container.getElement().getStyle().setFontSize(12, Unit.PT);
+        new Timer() {
+          @Override
+          public void run() {
+            handler.assertResizeFired(true);
+            container.removeFromParent();
+            finishTest();
+          }
+        }.schedule(250);
+      }
+    });
+  }
+
+  /**
+   * Test that resizing the outer container triggers a resize event.
+   */
+  @DoNotRunWith(Platform.HtmlUnitLayout)
+  public void testEnlargeContainerHeight() {
+    final SimplePanel container = new SimplePanel();
+    container.setPixelSize(100, 100);
+    testResizeContainer(container, new Command() {
+      public void execute() {
+        container.setHeight("101px");
+      }
+    });
+  }
+
+  /**
+   * Test that resizing the outer container triggers a resize event.
+   */
+  @DoNotRunWith(Platform.HtmlUnitLayout)
+  public void testEnlargeContainerWidth() {
+    final SimplePanel container = new SimplePanel();
+    container.setPixelSize(100, 100);
+    testResizeContainer(container, new Command() {
+      public void execute() {
+        container.setWidth("101px");
+      }
+    });
+  }
+
+  /**
+   * Test that resizing the outer container triggers a resize event even if the
+   * dimensions are too small to render a scrollbar.
+   */
+  @DoNotRunWith(Platform.HtmlUnitLayout)
+  public void testEnlargeSmallContainerHeight() {
+    final SimplePanel container = new SimplePanel();
+    container.setPixelSize(20, 20);
+    testResizeContainer(container, new Command() {
+      public void execute() {
+        container.setHeight("21px");
+      }
+    });
+  }
+
+  /**
+   * Test that resizing the outer container triggers a resize event even if the
+   * dimensions are too small to render a scrollbar.
+   */
+  @DoNotRunWith(Platform.HtmlUnitLayout)
+  public void testEnlargeSmallContainerWidth() {
+    final SimplePanel container = new SimplePanel();
+    container.setPixelSize(20, 20);
+    testResizeContainer(container, new Command() {
+      public void execute() {
+        container.setWidth("21px");
+      }
+    });
+  }
+
+  public void testProvidesResize() {
+    final List<String> resized = new ArrayList<String>();
+    ResizeLayoutPanel panel = createPanel();
+    panel.setWidget(new LayoutPanel() {
+      @Override
+      public void onResize() {
+        super.onResize();
+        resized.add("resized");
+      }
+    });
+
+    delayTestFinish(10000);
+    RootPanel.get().add(panel);
+    Scheduler.get().scheduleDeferred(new ScheduledCommand() {
+      public void execute() {
+        assertEquals(1, resized.size());
+        finishTest();
+      }
+    });
+  }
+
+  /**
+   * Test that resizing the outer container triggers a resize event.
+   */
+  @DoNotRunWith(Platform.HtmlUnitLayout)
+  public void testShrinkContainerHeight() {
+    final SimplePanel container = new SimplePanel();
+    container.setPixelSize(100, 100);
+    testResizeContainer(container, new Command() {
+      public void execute() {
+        container.setHeight("99px");
+      }
+    });
+  }
+
+  /**
+   * Test that resizing the outer container triggers a resize event.
+   */
+  @DoNotRunWith(Platform.HtmlUnitLayout)
+  public void testShrinkContainerWidth() {
+    final SimplePanel container = new SimplePanel();
+    container.setPixelSize(100, 100);
+    testResizeContainer(container, new Command() {
+      public void execute() {
+        container.setWidth("99px");
+      }
+    });
+  }
+
+  /**
+   * Test that resizing the outer container triggers a resize event even if the
+   * dimensions are too small to render a scrollbar.
+   */
+  @DoNotRunWith(Platform.HtmlUnitLayout)
+  public void testShrinkSmallContainerHeight() {
+    final SimplePanel container = new SimplePanel();
+    container.setPixelSize(21, 21);
+    testResizeContainer(container, new Command() {
+      public void execute() {
+        container.setHeight("20px");
+      }
+    });
+  }
+
+  /**
+   * Test that resizing the outer container triggers a resize event even if the
+   * dimensions are too small to render a scrollbar.
+   */
+  @DoNotRunWith(Platform.HtmlUnitLayout)
+  public void testShrinkSmallContainerWidth() {
+    final SimplePanel container = new SimplePanel();
+    container.setPixelSize(21, 21);
+    testResizeContainer(container, new Command() {
+      public void execute() {
+        container.setWidth("20px");
+      }
+    });
+  }
+
+  @Override
+  protected ResizeLayoutPanel createPanel() {
+    return new ResizeLayoutPanel();
+  }
+
+  /**
+   * Test that resizing the outer container triggers a resize event.
+   * 
+   * @param container the container that will hold the panel
+   * @param resizeCommand the command that resizes the container
+   */
+  private void testResizeContainer(final SimplePanel container,
+      final Command resizeCommand) {
+    // Create a panel and add a handler.
+    ResizeLayoutPanel panel = createPanel();
+    panel.setWidget(new Label("hello world"));
+    panel.setWidth("100%");
+    panel.setHeight("100%");
+    final CustomResizeHandler handler = new CustomResizeHandler();
+    panel.addResizeHandler(handler);
+    handler.assertResizeFired(false);
+
+    // Create an outer container and attach it.
+    container.setWidget(panel);
+    RootPanel.get().add(container);
+
+    // Wait for the resize event from attaching.
+    delayTestFinish(10000);
+    Scheduler.get().scheduleDeferred(new ScheduledCommand() {
+      public void execute() {
+        handler.assertResizeFired(true); // Triggered by attach.
+
+        // Change the size of the container.
+        resizeCommand.execute();
+        new Timer() {
+          @Override
+          public void run() {
+            handler.assertResizeFired(true);
+            container.removeFromParent();
+            finishTest();
+          }
+        }.schedule(250);
+      }
+    });
+  }
+}
