diff --git a/user/javadoc/com/google/gwt/examples/LayoutPanelExample.java b/user/javadoc/com/google/gwt/examples/LayoutPanelExample.java
new file mode 100644
index 0000000..13372d7
--- /dev/null
+++ b/user/javadoc/com/google/gwt/examples/LayoutPanelExample.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2009 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.examples;
+
+import static com.google.gwt.dom.client.Style.Unit.PCT;
+
+import com.google.gwt.core.client.EntryPoint;
+import com.google.gwt.layout.client.Layout.Layer;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.LayoutPanel;
+import com.google.gwt.user.client.ui.RootLayoutPanel;
+import com.google.gwt.user.client.ui.Widget;
+
+public class LayoutPanelExample implements EntryPoint {
+
+  public void onModuleLoad() {
+    // Attach two child widgets to a LayoutPanel, laying them out horizontally,
+    // splitting at 50%.
+    Widget childOne = new HTML(), childTwo = new HTML();
+    LayoutPanel p = new LayoutPanel();
+    p.add(childOne);
+    p.add(childTwo);
+
+    Layer layerOne = p.getLayer(childOne), layerTwo = p.getLayer(childTwo);
+    layerOne.setLeftWidth(0, PCT, 50, PCT);
+    layerTwo.setRightWidth(0, PCT, 50, PCT);
+
+    // Note the explicit call to layout(). This is required for the layout to
+    // take effect.
+    p.layout();
+
+    // Attach the LayoutPanel to the RootLayoutPanel. The latter will listen for
+    // resize events on the window to ensure that its children are informed of
+    // possible size changes.
+    RootLayoutPanel rp = RootLayoutPanel.get();
+    rp.add(p);
+
+    // The RootLayoutPanel also requires that its layout() method be explicitly
+    // called for the initial layout to take effect.
+    rp.layout();
+  }
+}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/layout/Layout.gwt.xml b/user/src/com/google/gwt/layout/Layout.gwt.xml
new file mode 100644
index 0000000..6619b69
--- /dev/null
+++ b/user/src/com/google/gwt/layout/Layout.gwt.xml
@@ -0,0 +1,25 @@
+<!--                                                                        -->
+<!-- Copyright 2009 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.                                         -->
+
+<module>
+  <inherits name="com.google.gwt.core.Core"/>
+  <inherits name="com.google.gwt.user.UserAgent"/>
+  <inherits name="com.google.gwt.dom.DOM"/>
+  <inherits name="com.google.gwt.animation.Animation"/>
+
+  <replace-with class="com.google.gwt.layout.client.LayoutImplIE6">
+    <when-type-is class="com.google.gwt.layout.client.LayoutImpl"/>
+    <when-property-is name="user.agent" value="ie6"/>
+  </replace-with>
+</module>
diff --git a/user/src/com/google/gwt/layout/client/Layout.java b/user/src/com/google/gwt/layout/client/Layout.java
new file mode 100644
index 0000000..6df50e1
--- /dev/null
+++ b/user/src/com/google/gwt/layout/client/Layout.java
@@ -0,0 +1,640 @@
+/*
+ * Copyright 2009 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.layout.client;
+
+import static com.google.gwt.dom.client.Style.Unit.PX;
+
+import com.google.gwt.animation.client.Animation;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.Style.Unit;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Helper class for laying out a container element and its children.
+ * 
+ * <p>
+ * This class is typically used by higher-level widgets to implement layout on
+ * their behalf. It is intended to wrap an element (usually a &lt;div&gt;), and
+ * lay its children out in a predictable fashion, automatically accounting for
+ * changes to the parent's size, and for all elements' margins, borders, and
+ * padding.
+ * </p>
+ * 
+ * <p>
+ * To use this class, create a container element (again, usually a &lt;div&gt;)
+ * and pass it to {@link #Layout(Element)}. Rather than attaching child elements
+ * directly to the element managed by this {@link Layout}, use the
+ * {@link Layout#attachChild(Element)} method. This will attach the child
+ * element and return a {@link Layout.Layer} object which is used to manage the
+ * child.
+ * </p>
+ * 
+ * <p>
+ * A separate {@link Layout.Layer} instance is associated with each child
+ * element. There is a set of methods available on this class to manipulate the
+ * child element's position and size. In order for changes to a layer to take
+ * effect, you must finally call one of {@link #layout()} or
+ * {@link #animate(int)}. This allows many changes to different layers to be
+ * applied efficiently, and to be animated.
+ * </p>
+ * 
+ * <p>
+ * On most browsers, this is implemented using absolute positioning. It also
+ * contains extra logic to make IE6 work properly.
+ * </p>
+ * 
+ * <p>
+ * <h3>Example</h3>
+ * {@example com.google.gwt.examples.LayoutExample}
+ * </p>
+ * 
+ * <p>
+ * NOTE: This class will <em>only</em> work in standards mode, which requires
+ * that the HTML page in which it is run have an explicit &lt;!DOCTYPE&gt;
+ * declaration.
+ * </p>
+ * 
+ * <p>
+ * NOTE: This class is still very new, and its interface may change without
+ * warning. Use at your own risk.
+ * </p>
+ */
+public class Layout {
+
+  /**
+   * Callback interface used by {@link Layout#animate(int, AnimationCallback)}
+   * to provide updates on animation progress.
+   */
+  public interface AnimationCallback {
+
+    /**
+     * Called immediately after the animation is complete, and the entire layout
+     * is in its final state.
+     */
+    void onAnimationComplete();
+
+    /**
+     * Called at each step of the animation, for each layer being laid out.
+     * 
+     * @param layer the layer being laid out
+     */
+    void onLayout(Layer layer, double progress);
+  }
+
+  /**
+   * This class is used to set the position and size of child elements.
+   * 
+   * <p>
+   * Each child element has three values associated with each axis: {left,
+   * right, width} on the horizontal axis, and {top, bottom, height} on the
+   * vertical axis. Precisely two of three values may be set at a time, or the
+   * system will be over- or under-contrained. For this reason, the following
+   * methods are provided for setting these values:
+   * <ul>
+   * <li>{@link #setLeftRight(double, Unit, double, Unit)}</li>
+   * <li>{@link #setLeftWidth(double, Unit, double, Unit)}</li>
+   * <li>{@link #setRightWidth(double, Unit, double, Unit)}</li>
+   * <li>{@link #setTopBottom(double, Unit, double, Unit)}</li>
+   * <li>{@link #setTopHeight(double, Unit, double, Unit)}</li>
+   * <li>{@link #setBottomHeight(double, Unit, double, Unit)}</li>
+   * </ul>
+   * </p>
+   * 
+   * <p>
+   * By default, each layer is set to fill the entire parent (i.e., {left, top,
+   * right, bottom} = {0, 0, 0, 0}).
+   * </p>
+   */
+  public class Layer {
+    final Element container, child;
+
+    Object userObject;
+
+    boolean setLeft, setRight, setTop, setBottom, setWidth, setHeight;
+    boolean setTargetLeft = true, setTargetRight = true, setTargetTop = true,
+        setTargetBottom = true, setTargetWidth, setTargetHeight;
+    Unit leftUnit, topUnit, rightUnit, bottomUnit, widthUnit, heightUnit;
+    Unit targetLeftUnit = PX, targetTopUnit = PX, targetRightUnit = PX,
+        targetBottomUnit = PX, targetWidthUnit, targetHeightUnit;
+    double left, top, right, bottom, width, height;
+    double sourceLeft, sourceTop, sourceRight, sourceBottom, sourceWidth,
+        sourceHeight;
+    double targetLeft, targetTop, targetRight, targetBottom, targetWidth,
+        targetHeight;
+
+    Layer(Element container, Element child, Object userObject) {
+      this.container = container;
+      this.child = child;
+      this.userObject = userObject;
+    }
+
+    /**
+     * Gets the container element associated with this layer.
+     * 
+     * <p>
+     * This is the element that sits between the parent and child elements. It
+     * is normally necessary to operate on this element only when you need to
+     * modify certain CSS properties, such as visibility.
+     * </p>
+     * 
+     * @return the container element
+     */
+    public Element getContainerElement() {
+      return container;
+    }
+
+    /**
+     * Gets the user-data associated with this layer.
+     * 
+     * @return the layer's user-data object
+     */
+    public Object getUserObject() {
+      return this.userObject;
+    }
+
+    /**
+     * Sets the layer's bottom and height values.
+     * 
+     * @param bottom
+     * @param bottomUnit
+     * @param height
+     * @param heightUnit
+     */
+    public void setBottomHeight(double bottom, Unit bottomUnit, double height,
+        Unit heightUnit) {
+      this.setTargetBottom = this.setTargetHeight = true;
+      this.setTargetTop = false;
+      this.targetBottom = bottom;
+      this.targetHeight = height;
+      this.targetBottomUnit = bottomUnit;
+      this.targetHeightUnit = heightUnit;
+    }
+
+    /**
+     * Sets the layer's left and right values.
+     * 
+     * @param left
+     * @param leftUnit
+     * @param right
+     * @param rightUnit
+     */
+    public void setLeftRight(double left, Unit leftUnit, double right,
+        Unit rightUnit) {
+      this.setTargetLeft = this.setTargetRight = true;
+      this.setTargetWidth = false;
+      this.targetLeft = left;
+      this.targetRight = right;
+      this.targetLeftUnit = leftUnit;
+      this.targetRightUnit = rightUnit;
+    }
+
+    /**
+     * Sets the layer's left and width values.
+     * 
+     * @param left
+     * @param leftUnit
+     * @param width
+     * @param widthUnit
+     */
+    public void setLeftWidth(double left, Unit leftUnit, double width,
+        Unit widthUnit) {
+      this.setTargetLeft = this.setTargetWidth = true;
+      this.setTargetRight = false;
+      this.targetLeft = left;
+      this.targetWidth = width;
+      this.targetLeftUnit = leftUnit;
+      this.targetWidthUnit = widthUnit;
+    }
+
+    /**
+     * Sets the layer's right and width values.
+     * 
+     * @param right
+     * @param rightUnit
+     * @param width
+     * @param widthUnit
+     */
+    public void setRightWidth(double right, Unit rightUnit, double width,
+        Unit widthUnit) {
+      this.setTargetRight = this.setTargetWidth = true;
+      this.setTargetLeft = false;
+      this.targetRight = right;
+      this.targetWidth = width;
+      this.targetRightUnit = rightUnit;
+      this.targetWidthUnit = widthUnit;
+    }
+
+    /**
+     * Sets the layer's top and bottom values.
+     * 
+     * @param top
+     * @param topUnit
+     * @param bottom
+     * @param bottomUnit
+     */
+    public void setTopBottom(double top, Unit topUnit, double bottom,
+        Unit bottomUnit) {
+      this.setTargetTop = this.setTargetBottom = true;
+      this.setTargetHeight = false;
+      this.targetTop = top;
+      this.targetBottom = bottom;
+      this.targetTopUnit = topUnit;
+      this.targetBottomUnit = bottomUnit;
+    }
+
+    /**
+     * Sets the layer's top and height values.
+     * 
+     * @param top
+     * @param topUnit
+     * @param height
+     * @param heightUnit
+     */
+    public void setTopHeight(double top, Unit topUnit, double height,
+        Unit heightUnit) {
+      this.setTargetTop = this.setTargetHeight = true;
+      this.setTargetBottom = false;
+      this.targetTop = top;
+      this.targetHeight = height;
+      this.targetTopUnit = topUnit;
+      this.targetHeightUnit = heightUnit;
+    }
+  }
+
+  private static LayoutImpl impl = GWT.create(LayoutImpl.class);
+
+  private List<Layer> layers = new ArrayList<Layer>();
+  private final Element parentElem;
+  private Animation animation;
+
+  /**
+   * Constructs a new layout associated with the given parent element.
+   * 
+   * @param parent the element to serve as the layout parent
+   */
+  public Layout(Element parent) {
+    this.parentElem = parent;
+    impl.initParent(parent);
+  }
+
+  /**
+   * Updates the layout by animating it over time.
+   * 
+   * @param duration the duration of the animation
+   * @see #animate(int, AnimationCallback)
+   */
+  public void animate(int duration) {
+    animate(duration, null);
+  }
+
+  /**
+   * Updates the layout by animating it over time, with a callback on each frame
+   * of the animation, and upon completion.
+   * 
+   * @param duration the duration of the animation
+   * @param callback the animation callback
+   */
+  public void animate(int duration, final AnimationCallback callback) {
+    // Deal with constraint changes (e.g. left-width => right-width, etc)
+    int parentWidth = parentElem.getClientWidth();
+    int parentHeight = parentElem.getClientHeight();
+    for (Layer l : layers) {
+      adjustHorizontalConstraints(parentWidth, l);
+      adjustVerticalConstraints(parentHeight, l);
+    }
+
+    // Cancel the old animation, if there is one.
+    if (animation != null) {
+      animation.cancel();
+    }
+
+    animation = new Animation() {
+      @Override
+      protected void onCancel() {
+        onComplete();
+      }
+
+      @Override
+      protected void onComplete() {
+        layout();
+        if (callback != null) {
+          callback.onAnimationComplete();
+        }
+        animation = null;
+      }
+
+      @Override
+      protected void onUpdate(double progress) {
+        for (Layer l : layers) {
+          if (l.setTargetLeft) {
+            l.left = l.sourceLeft + (l.targetLeft - l.sourceLeft) * progress;
+          }
+          if (l.setTargetRight) {
+            l.right = l.sourceRight + (l.targetRight - l.sourceRight)
+                * progress;
+          }
+          if (l.setTargetTop) {
+            l.top = l.sourceTop + (l.targetTop - l.sourceTop) * progress;
+          }
+          if (l.setTargetBottom) {
+            l.bottom = l.sourceBottom + (l.targetBottom - l.sourceBottom)
+                * progress;
+          }
+          if (l.setTargetWidth) {
+            l.width = l.sourceWidth + (l.targetWidth - l.sourceWidth)
+                * progress;
+          }
+          if (l.setTargetHeight) {
+            l.height = l.sourceHeight + (l.targetHeight - l.sourceHeight)
+                * progress;
+          }
+
+          impl.layout(l);
+          if (callback != null) {
+            callback.onLayout(l, progress);
+          }
+        }
+        impl.finalizeLayout(parentElem);
+      }
+    };
+
+    animation.run(duration);
+  }
+
+  /**
+   * Asserts that the given child element is managed by this layout
+   * 
+   * @param elem the element to be tested
+   */
+  public void assertIsChild(Element elem) {
+    assert elem.getParentElement().getParentElement() == this.parentElem : "Element is not a child of this layout";
+  }
+
+  /**
+   * This method must be called when the parent element becomes attached to the
+   * document.
+   * 
+   * @see #detach()
+   */
+  public void attach() {
+    impl.attach(parentElem);
+  }
+
+  /**
+   * Attaches a child element to this layout.
+   * 
+   * <p>
+   * This method will attach the child to the layout, removing it from its
+   * current parent element. Use the {@link Layer} it returns to manipulate the
+   * child.
+   * </p>
+   * 
+   * @param child the child to be attached
+   * @return the {@link Layer} associated with the element
+   */
+  public Layer attachChild(Element child) {
+    return attachChild(child, null);
+  }
+
+  /**
+   * Attaches a child element to this layout.
+   * 
+   * <p>
+   * This method will attach the child to the layout, removing it from its
+   * current parent element. Use the {@link Layer} it returns to manipulate the
+   * child.
+   * </p>
+   * 
+   * @param child the child to be attached
+   * @param userObject an arbitrary object to be associated with this layer
+   * @return the {@link Layer} associated with the element
+   */
+  public Layer attachChild(Element child, Object userObject) {
+    Element container = impl.attachChild(parentElem, child);
+    Layer layer = new Layer(container, child, userObject);
+    layers.add(layer);
+    return layer;
+  }
+
+  /**
+   * This method must be called when the parent element becomes detached from
+   * the document.
+   * 
+   * @see #attach()
+   */
+  public void detach() {
+    impl.detach(parentElem);
+  }
+
+  /**
+   * Causes the parent element to fill its own parent.
+   * 
+   * <p>
+   * This is most useful for top-level layouts that need to follow the size of
+   * another element, such as the &lt;body&gt;.
+   * </p>
+   */
+  public void fillParent() {
+    impl.fillParent(parentElem);
+  }
+
+  /**
+   * Returns the size of one unit, in pixels, in the context of this layout.
+   * 
+   * <p>
+   * This will work for any unit type, but be aware that certain unit types,
+   * such as {@link Unit#EM}, and {@link Unit#EX}, will return different values
+   * based upon the parent's associated font size. {@link Unit#PCT} is dependent
+   * upon the parent's actual size, and the axis to be measured.
+   * </p>
+   * 
+   * @param unit the unit type to be measured
+   * @param vertical whether the unit to be measured is on the vertical or
+   *          horizontal axis (this matters only for {@link Unit#PCT})
+   * @return the unit size, in pixels
+   */
+  public double getUnitSize(Unit unit, boolean vertical) {
+    return impl.getUnitSizeInPixels(parentElem, unit, vertical);
+  }
+
+  /**
+   * Updates this layout's children immediately. This method <em>must</em> be
+   * called after updating any of its children's {@link Layer layers}.
+   */
+  public void layout() {
+    for (Layer l : layers) {
+      l.left = l.sourceLeft = l.targetLeft;
+      l.top = l.sourceTop = l.targetTop;
+      l.right = l.sourceRight = l.targetRight;
+      l.bottom = l.sourceBottom = l.targetBottom;
+      l.width = l.sourceWidth = l.targetWidth;
+      l.height = l.sourceHeight = l.targetHeight;
+
+      l.setLeft = l.setTargetLeft;
+      l.setTop = l.setTargetTop;
+      l.setRight = l.setTargetRight;
+      l.setBottom = l.setTargetBottom;
+      l.setWidth = l.setTargetWidth;
+      l.setHeight = l.setTargetHeight;
+
+      l.leftUnit = l.targetLeftUnit;
+      l.topUnit = l.targetTopUnit;
+      l.rightUnit = l.targetRightUnit;
+      l.bottomUnit = l.targetBottomUnit;
+      l.widthUnit = l.targetWidthUnit;
+      l.heightUnit = l.targetHeightUnit;
+
+      impl.layout(l);
+    }
+
+    impl.finalizeLayout(parentElem);
+  }
+
+  /**
+   * Removes a child element from this layout.
+   * 
+   * @param layer the layer associated with the child to be removed
+   */
+  public void removeChild(Layer layer) {
+    impl.removeChild(layer.container, layer.child);
+    layers.remove(layer);
+  }
+
+  private void adjustHorizontalConstraints(int parentWidth, Layer l) {
+    double leftPx = l.left * getUnitSize(l.leftUnit, false);
+    double rightPx = l.right * getUnitSize(l.rightUnit, false);
+    double widthPx = l.width * getUnitSize(l.widthUnit, false);
+
+    if (l.setLeft && !l.setTargetLeft) {
+      // -left
+      l.setLeft = false;
+
+      if (!l.setWidth) {
+        // +width
+        l.setTargetWidth = true;
+        l.sourceWidth = (parentWidth - (leftPx + rightPx))
+            / getUnitSize(l.targetWidthUnit, false);
+      } else {
+        // +right
+        l.setTargetRight = true;
+        l.sourceRight = (parentWidth - (leftPx + widthPx))
+            / getUnitSize(l.targetRightUnit, false);
+      }
+    } else if (l.setWidth && !l.setTargetWidth) {
+      // -width
+      l.setWidth = false;
+
+      if (!l.setLeft) {
+        // +left
+        l.setTargetLeft = true;
+        l.sourceLeft = (parentWidth - (rightPx + widthPx))
+            / getUnitSize(l.targetLeftUnit, false);
+      } else {
+        // +right
+        l.setTargetRight = true;
+        l.sourceRight = (parentWidth - (leftPx + widthPx))
+            / getUnitSize(l.targetRightUnit, false);
+      }
+    } else if (l.setRight && !l.setTargetRight) {
+      // -right
+      l.setRight = false;
+
+      if (!l.setWidth) {
+        // +width
+        l.setTargetWidth = true;
+        l.sourceWidth = (parentWidth - (leftPx + rightPx))
+            / getUnitSize(l.targetWidthUnit, false);
+      } else {
+        // +left
+        l.setTargetLeft = true;
+        l.sourceLeft = (parentWidth - (rightPx + widthPx))
+            / getUnitSize(l.targetLeftUnit, false);
+      }
+    }
+
+    l.setLeft = l.setTargetLeft;
+    l.setRight = l.setTargetRight;
+    l.setWidth = l.setTargetWidth;
+
+    l.leftUnit = l.targetLeftUnit;
+    l.rightUnit = l.targetRightUnit;
+    l.widthUnit = l.targetWidthUnit;
+  }
+
+  private void adjustVerticalConstraints(int parentHeight, Layer l) {
+    double topPx = l.top * getUnitSize(l.topUnit, true);
+    double bottomPx = l.bottom * getUnitSize(l.bottomUnit, true);
+    double heightPx = l.height * getUnitSize(l.heightUnit, true);
+
+    if (l.setTop && !l.setTargetTop) {
+      // -top
+      l.setTop = false;
+
+      if (!l.setHeight) {
+        // +height
+        l.setTargetHeight = true;
+        l.sourceHeight = (parentHeight - (topPx + bottomPx))
+            / getUnitSize(l.targetHeightUnit, true);
+      } else {
+        // +bottom
+        l.setTargetBottom = true;
+        l.sourceBottom = (parentHeight - (topPx + heightPx))
+            / getUnitSize(l.targetBottomUnit, true);
+      }
+    } else if (l.setHeight && !l.setTargetHeight) {
+      // -height
+      l.setHeight = false;
+
+      if (!l.setTop) {
+        // +top
+        l.setTargetTop = true;
+        l.sourceTop = (parentHeight - (bottomPx + heightPx))
+            / getUnitSize(l.targetTopUnit, true);
+      } else {
+        // +bottom
+        l.setTargetBottom = true;
+        l.sourceBottom = (parentHeight - (topPx + heightPx))
+            / getUnitSize(l.targetBottomUnit, true);
+      }
+    } else if (l.setBottom && !l.setTargetBottom) {
+      // -bottom
+      l.setBottom = false;
+
+      if (!l.setHeight) {
+        // +height
+        l.setTargetHeight = true;
+        l.sourceHeight = (parentHeight - (topPx + bottomPx))
+            / getUnitSize(l.targetHeightUnit, true);
+      } else {
+        // +top
+        l.setTargetTop = true;
+        l.sourceTop = (parentHeight - (bottomPx + heightPx))
+            / getUnitSize(l.targetTopUnit, true);
+      }
+    }
+
+    l.setTop = l.setTargetTop;
+    l.setBottom = l.setTargetBottom;
+    l.setHeight = l.setTargetHeight;
+
+    l.topUnit = l.targetTopUnit;
+    l.bottomUnit = l.targetBottomUnit;
+    l.heightUnit = l.targetHeightUnit;
+  }
+}
diff --git a/user/src/com/google/gwt/layout/client/LayoutImpl.java b/user/src/com/google/gwt/layout/client/LayoutImpl.java
new file mode 100644
index 0000000..a5e9730
--- /dev/null
+++ b/user/src/com/google/gwt/layout/client/LayoutImpl.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2009 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.layout.client;
+
+import static com.google.gwt.dom.client.Style.Unit.EM;
+import static com.google.gwt.dom.client.Style.Unit.EX;
+import static com.google.gwt.dom.client.Style.Unit.IN;
+import static com.google.gwt.dom.client.Style.Unit.PX;
+
+import com.google.gwt.dom.client.DivElement;
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.Style;
+import com.google.gwt.dom.client.Style.Position;
+import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.layout.client.Layout.Layer;
+
+/**
+ * Default implementation, which works with all browsers except for IE6. It uses
+ * only the "top", "left", "bottom", "right", "width", and "height" CSS
+ * properties.
+ * 
+ * Note: This implementation class has state, so {@link Layout} must create a
+ * new instance for each layout-parent.
+ */
+class LayoutImpl {
+
+  private static DivElement fixedRuler;
+
+  static {
+    Document doc = Document.get();
+    fixedRuler = createRuler(IN, IN);
+    doc.getBody().appendChild(fixedRuler);
+  }
+
+  protected static DivElement createRuler(Unit widthUnit, Unit heightUnit) {
+    DivElement ruler = Document.get().createDivElement();
+    ruler.setInnerHTML("&nbsp;");
+    Style style = ruler.getStyle();
+    style.setPosition(Position.ABSOLUTE);
+    style.setZIndex(-32767);
+    style.setLeft(-10000, PX);
+    style.setWidth(1, widthUnit);
+    style.setHeight(1, heightUnit);
+    return ruler;
+  }
+
+  protected DivElement relativeRuler;
+
+  public Element attachChild(Element parent, Element child) {
+    DivElement container = Document.get().createDivElement();
+    container.appendChild(child);
+
+    container.getStyle().setProperty("position", "absolute");
+    container.getStyle().setProperty("overflow", "hidden");
+
+    fillParent(child);
+
+    Style style = child.getStyle();
+    style.setWidth(100, Unit.PCT);
+    style.setHeight(100, Unit.PCT);
+
+    parent.appendChild(container);
+    return container;
+  }
+
+  public void fillParent(Element elem) {
+    Style style = elem.getStyle();
+    style.setPosition(Position.ABSOLUTE);
+    style.setLeft(0, PX);
+    style.setTop(0, PX);
+    style.setRight(0, PX);
+    style.setBottom(0, PX);
+  }
+
+  public void finalizeLayout(Element parent) {
+  }
+
+  public double getUnitSizeInPixels(Element parent, Unit unit, boolean vertical) {
+    if (unit == null) {
+      return 1;
+    }
+
+    switch (unit) {
+      default:
+      case PX:
+        return 1;
+      case PCT:
+        return (vertical ? parent.getClientHeight() : parent.getClientWidth()) / 100.0;
+      case EM:
+        return relativeRuler.getOffsetWidth();
+      case EX:
+        return relativeRuler.getOffsetHeight();
+      case CM:
+        return fixedRuler.getOffsetWidth();
+      case MM:
+        return fixedRuler.getOffsetWidth() / 10.0;
+      case IN:
+        return fixedRuler.getOffsetWidth() / 2.54;
+      case PT:
+        return fixedRuler.getOffsetWidth() / 28.4;
+      case PC:
+        return fixedRuler.getOffsetWidth() / 2.36;
+    }
+  }
+
+  public void initParent(Element parent) {
+    parent.getStyle().setProperty("position", "relative");
+    parent.appendChild(relativeRuler = createRuler(EM, EX));
+  }
+
+  public void layout(Layer layer) {
+    Style style = layer.container.getStyle();
+
+    style.setProperty("left", layer.setLeft
+        ? (layer.left + layer.leftUnit.getType()) : "");
+    style.setProperty("top", layer.setTop
+        ? (layer.top + layer.topUnit.getType()) : "");
+    style.setProperty("right", layer.setRight
+        ? (layer.right + layer.rightUnit.getType()) : "");
+    style.setProperty("bottom", layer.setBottom
+        ? (layer.bottom + layer.bottomUnit.getType()) : "");
+    style.setProperty("width", layer.setWidth
+        ? (layer.width + layer.widthUnit.getType()) : "");
+    style.setProperty("height", layer.setHeight
+        ? (layer.height + layer.heightUnit.getType()) : "");
+  }
+
+  public void removeChild(Element container, Element child) {
+    container.removeFromParent();
+
+    // We want this code to be resilient to the child having already been
+    // removed from its container (perhaps by widget code).
+    if (child.getParentElement() == container) {
+      child.removeFromParent();
+    }
+
+    // Cleanup child styles set by fillParent().
+    Style style = child.getStyle();
+    style.clearPosition();
+    style.clearLeft();
+    style.clearTop();
+    style.clearWidth();
+    style.clearHeight();
+  }
+
+  public void detach(Element parent) {
+    // Do nothing. This exists only to help LayoutImplIE6 avoid memory leaks.
+  }
+
+  public void attach(Element parent) {
+    // Do nothing. This exists only to help LayoutImplIE6 avoid memory leaks.
+  }
+}
diff --git a/user/src/com/google/gwt/layout/client/LayoutImplIE6.java b/user/src/com/google/gwt/layout/client/LayoutImplIE6.java
new file mode 100644
index 0000000..38231a5
--- /dev/null
+++ b/user/src/com/google/gwt/layout/client/LayoutImplIE6.java
@@ -0,0 +1,352 @@
+/*
+ * Copyright 2009 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.layout.client;
+
+import static com.google.gwt.dom.client.Style.Unit.PX;
+
+import com.google.gwt.dom.client.DivElement;
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.Style.Overflow;
+import com.google.gwt.dom.client.Style.Position;
+import com.google.gwt.event.logical.shared.ResizeEvent;
+import com.google.gwt.event.logical.shared.ResizeHandler;
+import com.google.gwt.layout.client.Layout.Layer;
+import com.google.gwt.user.client.Window;
+
+/**
+ * IE6-specific implementation, which uses the "onresize" event, along with a
+ * series of measurement tools, to deal with several IE6 bugs. Specifically,
+ * IE6 doesn't support simultaneous left-right and top-bottom values, and it
+ * misplaces by one pixel elements whose right/bottom properties are set.
+ * 
+ * Because this implementation gets compiled in for both IE6 and 7, it
+ * dynamically detects IE7 and punts to the super implementation.
+ */
+class LayoutImplIE6 extends LayoutImpl {
+
+  private static Element createStyleRuler(Element parent) {
+    DivElement styleRuler = Document.get().createDivElement();
+    DivElement styleInner = Document.get().createDivElement();
+
+    styleRuler.getStyle().setPosition(Position.ABSOLUTE);
+    styleRuler.getStyle().setLeft(-10000, PX);
+
+    parent.appendChild(styleRuler);
+    styleRuler.appendChild(styleInner);
+    return styleRuler;
+  }
+
+  private static void hookWindowResize(final Element elem) {
+    Window.addResizeHandler(new ResizeHandler() {
+      public void onResize(ResizeEvent event) {
+        resizeRelativeToParent(elem);
+      }
+    });
+  }
+
+  private static native void measureDecoration(Element elem) /*-{
+    var ruler = elem.__styleRuler;
+    var inner = ruler.children[0];
+    var s = inner.style, cs = elem.currentStyle;
+
+    s.borderLeftStyle = cs.borderLeftStyle;
+    s.borderRightStyle = cs.borderRightStyle;
+    s.borderTopStyle = cs.borderTopStyle;
+    s.borderBottomStyle = cs.borderBottomStyle;
+
+    s.borderLeftWidth = cs.borderLeftWidth;
+    s.borderRightWidth = cs.borderRightWidth;
+    s.borderTopWidth = cs.borderTopWidth;
+    s.borderBottomWidth = cs.borderBottomWidth;
+
+    // Oddly enough, allowing the word 'auto' to creep into the style
+    // ruler's margin causes it to take up all of its parent's space.
+    s.marginLeft = (cs.marginLeft == 'auto') ? '' : cs.marginLeft;
+    s.marginRight = (cs.marginRight == 'auto') ? '' : cs.marginRight;
+    s.marginTop = (cs.marginTop == 'auto') ? '' : cs.marginTop;
+    s.marginBottom = (cs.marginBottom == 'auto') ? '' : cs.marginBottom;
+
+    s.paddingLeft = cs.paddingLeft;
+    s.paddingRight = cs.paddingRight;
+    s.paddingTop = cs.paddingTop;
+    s.paddingBottom = cs.paddingBottom;
+
+    s.width = s.height = 32;
+    elem.__decoWidth = ruler.offsetWidth - 32;
+    elem.__decoHeight = ruler.offsetHeight - 32;
+  }-*/;
+
+  private static native void resizeRelativeToParent(Element elem) /*-{
+    var parent = elem.__resizeParent;
+    if (parent) {
+      @com.google.gwt.layout.client.LayoutImplIE6::measureDecoration(Lcom/google/gwt/dom/client/Element;)(elem);
+      elem.style.left = 0;
+      elem.style.top = 0;
+      elem.style.width = parent.clientWidth - elem.__decoWidth;
+      elem.style.height = parent.clientHeight - elem.__decoHeight;
+    }
+  }-*/;
+
+  private static native void setLayer(Element container, Layer layer) /*-{
+    // Potential leak: This is cleaned up in detach().
+    container.__layer = layer;
+  }-*/;
+
+  private static native void setPropertyElement(Element elem, String name,
+      Element value) /*-{
+    elem[name] = value;
+  }-*/;
+
+  @Override
+  public void attach(Element parent) {
+    if (UserAgent.isIE6()) {
+      // No need to re-connect layer refs. This will be taken care of
+      // automatically in layout().
+      initResizeHandler(parent);
+      initUnitChangeHandler(parent, relativeRuler);
+    }
+  }
+
+  public Element attachChild(Element parent, Element child) {
+    if (!UserAgent.isIE6()) {
+      return super.attachChild(parent, child);
+    }
+
+    DivElement container = Document.get().createDivElement();
+    container.appendChild(child);
+
+    container.getStyle().setPosition(Position.ABSOLUTE);
+    container.getStyle().setOverflow(Overflow.HIDDEN);
+    child.getStyle().setPosition(Position.ABSOLUTE);
+
+    // Hang the style ruler from the container element, but associate it with
+    // the child element, so that measureDecoration(child) will work.
+    setPropertyElement(child, "__styleRuler", createStyleRuler(container));
+
+    parent.appendChild(container);
+    return container;
+  }
+
+  @Override
+  public void detach(Element parent) {
+    if (UserAgent.isIE6()) {
+      removeLayerRefs(parent);
+      removeResizeHandler(parent);
+      removeUnitChangeHandler(relativeRuler);
+    }
+  }
+
+  @Override
+  public void fillParent(Element elem) {
+    if (!UserAgent.isIE6()) {
+      super.fillParent(elem);
+      return;
+    }
+
+    fillParentImpl(elem);
+  }
+
+  @Override
+  public void finalizeLayout(Element parent) {
+    if (!UserAgent.isIE6()) {
+      super.finalizeLayout(parent);
+      return;
+    }
+
+    resizeRelativeToParent(parent);
+    resizeHandler(parent, true);
+  }
+
+  @Override
+  public void initParent(Element parent) {
+    super.initParent(parent);
+
+    if (UserAgent.isIE6()) {
+      setPropertyElement(parent, "__styleRuler", createStyleRuler(parent));
+    }
+  }
+
+  public void layout(Layer layer) {
+    if (!UserAgent.isIE6()) {
+      super.layout(layer);
+      return;
+    }
+
+    Element elem = layer.getContainerElement();
+    setLayer(elem, layer);
+  }
+
+  private native void fillParentImpl(Element elem) /*-{
+    // Hook the parent element's onresize event. If the parent is the <body>,
+    // then we have to go through the Window class to get the resize event,
+    // because IE6 requires a bunch of foul hackery to safely hook it.
+    var parent = elem.parentElement;
+    if (parent.tagName.toLowerCase() == 'body') {
+      elem.style.position = 'absolute';
+      var docElem = parent.parentElement;
+      elem.__resizeParent = docElem;
+      @com.google.gwt.layout.client.LayoutImplIE6::hookWindowResize(Lcom/google/gwt/dom/client/Element;)(elem);
+      return;
+    }
+
+    function resize() {
+      @com.google.gwt.layout.client.LayoutImplIE6::resizeRelativeToParent(Lcom/google/gwt/dom/client/Element;)(elem);
+    }
+
+    elem.__resizeParent = parent;
+    parent.onresize = resize;
+    resize();
+  }-*/;
+
+  private native void initResizeHandler(Element parent) /*-{
+    // Potential leak: This is cleaned up in detach().
+    var self = this;
+    parent.onresize = function() {
+      self.@com.google.gwt.layout.client.LayoutImplIE6::resizeHandler(Lcom/google/gwt/dom/client/Element;)(parent);
+    };
+  }-*/;
+
+  private native void initUnitChangeHandler(Element parent, Element ruler) /*-{
+    // Potential leak: This is cleaned up in detach().
+    var self = this;
+    ruler.onresize = function() {
+      self.@com.google.gwt.layout.client.LayoutImplIE6::resizeHandler(Lcom/google/gwt/dom/client/Element;Z)(parent, true);
+    };
+  }-*/;
+
+  private native void removeLayerRefs(Element parent) /*-{
+    for (var i = 0; i < parent.childNodes.length; ++i) {
+      var container = parent.childNodes[i];
+      if (container.__layer) {
+        container.__layer = null;
+      }
+    }
+  }-*/;
+
+  private native void removeResizeHandler(Element parent) /*-{
+    parent.onresize = null;
+  }-*/;
+
+  private native void removeUnitChangeHandler(Element ruler) /*-{
+    ruler.onresize = null;
+  }-*/;
+
+  private void resizeHandler(Element parent) {
+    resizeHandler(parent, false);
+  }
+  
+  private native void resizeHandler(Element parent, boolean force) /*-{
+    if (!force &&
+        ((parent.offsetWidth == parent.__oldWidth) &&
+         (parent.offsetHeight == parent.__oldHeight))) {
+      return;
+    }
+    parent.__oldWidth = parent.offsetWidth;
+    parent.__oldHeight = parent.offsetHeight;
+
+    var parentWidth = parent.clientWidth;
+    var parentHeight = parent.clientHeight;
+
+    // Iterate over the children, assuming each of them is an unstyled
+    // container element.
+    for (var i = 0; i < parent.childNodes.length; ++i) {
+      // Don't attempt to layout the rulers.
+      var container = parent.childNodes[i];
+      var layer = container.__layer;
+      if (!layer) {
+        continue;
+      }
+
+      // This is ugly, but it's less ugly than writing all these JSNI refs inline.
+      var _setLeft = layer.@com.google.gwt.layout.client.Layout.Layer::setLeft;
+      var _setTop = layer.@com.google.gwt.layout.client.Layout.Layer::setTop;
+      var _setWidth = layer.@com.google.gwt.layout.client.Layout.Layer::setWidth;
+      var _setHeight = layer.@com.google.gwt.layout.client.Layout.Layer::setHeight;
+      var _setRight = layer.@com.google.gwt.layout.client.Layout.Layer::setRight;
+      var _setBottom = layer.@com.google.gwt.layout.client.Layout.Layer::setBottom;
+
+      var _left = layer.@com.google.gwt.layout.client.Layout.Layer::left;
+      var _top = layer.@com.google.gwt.layout.client.Layout.Layer::top;
+      var _width = layer.@com.google.gwt.layout.client.Layout.Layer::width;
+      var _height = layer.@com.google.gwt.layout.client.Layout.Layer::height;
+      var _right = layer.@com.google.gwt.layout.client.Layout.Layer::right;
+      var _bottom = layer.@com.google.gwt.layout.client.Layout.Layer::bottom;
+
+      var _leftUnit = layer.@com.google.gwt.layout.client.Layout.Layer::leftUnit;
+      var _topUnit = layer.@com.google.gwt.layout.client.Layout.Layer::topUnit;
+      var _widthUnit = layer.@com.google.gwt.layout.client.Layout.Layer::widthUnit;
+      var _heightUnit = layer.@com.google.gwt.layout.client.Layout.Layer::heightUnit;
+      var _rightUnit = layer.@com.google.gwt.layout.client.Layout.Layer::rightUnit;
+      var _bottomUnit = layer.@com.google.gwt.layout.client.Layout.Layer::bottomUnit;
+
+      // Apply the requested position & size values to the element's style.
+      var style = container.style;
+      style.left = _setLeft ? (_left + _leftUnit.@com.google.gwt.dom.client.Style.Unit::getType()()) : "";
+      style.top = _setTop ? (_top + _topUnit.@com.google.gwt.dom.client.Style.Unit::getType()()) : "";
+      style.width = _setWidth ? (_width + _widthUnit.@com.google.gwt.dom.client.Style.Unit::getType()()) : "";
+      style.height = _setHeight ? (_height + _heightUnit.@com.google.gwt.dom.client.Style.Unit::getType()()) : "";
+
+      // If right is defined, reposition/size the container horizontally.
+      if (_setRight) {
+        var ratio = this.@com.google.gwt.layout.client.LayoutImplIE6::getUnitSizeInPixels(Lcom/google/gwt/dom/client/Element;Lcom/google/gwt/dom/client/Style$Unit;Z)(parent, _rightUnit, false);
+        var right = parentWidth - (_right * ratio);
+
+        if (!_setLeft) {
+          // There's no left defined; adjust the left position move the element to the right edge.
+          container.style.left = (right - container.offsetWidth) + 'px';
+        } else {
+          // Both left and right are defined; calculate the width and set it.
+          var leftRatio = this.@com.google.gwt.layout.client.LayoutImplIE6::getUnitSizeInPixels(Lcom/google/gwt/dom/client/Element;Lcom/google/gwt/dom/client/Style$Unit;Z)(parent, _leftUnit, false);
+          var left = (_left * leftRatio);
+          if (right > left) {
+            container.style.width = (right - left) + 'px';
+          }
+        }
+      }
+
+      // If bottom is defined, reposition/size the container vertically.
+      if (_setBottom) {
+        var ratio = this.@com.google.gwt.layout.client.LayoutImplIE6::getUnitSizeInPixels(Lcom/google/gwt/dom/client/Element;Lcom/google/gwt/dom/client/Style$Unit;Z)(parent, _bottomUnit, true);
+        var bottom = parentHeight - (_bottom * ratio);
+
+        if (!_setTop) {
+          // There's no top defined; adjust the left position move the element to the bottom edge.
+          container.style.top = (bottom - container.offsetHeight) + 'px';
+        } else {
+          // Both top and bottom are defined; calculate the height and set it.
+          var topRatio = this.@com.google.gwt.layout.client.LayoutImplIE6::getUnitSizeInPixels(Lcom/google/gwt/dom/client/Element;Lcom/google/gwt/dom/client/Style$Unit;Z)(parent, _topUnit, true);
+          var top = (_top * topRatio);
+          if (bottom > top) {
+            container.style.height = (bottom - top) + 'px';
+          }
+        }
+      }
+
+      // Resize the child to take up all of its container's width and height.
+      var child = container.firstChild;
+      @com.google.gwt.layout.client.LayoutImplIE6::measureDecoration(Lcom/google/gwt/dom/client/Element;)(child);
+      var childDecoWidth = child.__decoWidth;
+      var childDecoHeight = child.__decoHeight;
+      if (container.offsetWidth > childDecoWidth) {
+        child.style.width = (container.offsetWidth - childDecoWidth) + 'px';
+      }
+      if (container.offsetHeight > childDecoHeight) {
+        child.style.height = (container.offsetHeight - childDecoHeight) + 'px';
+      }
+    }
+  }-*/;
+}
diff --git a/user/src/com/google/gwt/layout/client/UserAgent.java b/user/src/com/google/gwt/layout/client/UserAgent.java
new file mode 100644
index 0000000..2127a59
--- /dev/null
+++ b/user/src/com/google/gwt/layout/client/UserAgent.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2009 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.layout.client;
+
+/**
+ * User-Agent utility methods used by {@link LayoutImplIE6}.
+ * 
+ * TODO: Generalize this, move it into a common place, and make it available for
+ * use by other classes.
+ */
+class UserAgent {
+
+  // Stolen and modified from UserAgent.gwt.xml.
+  public static native boolean isIE6() /*-{
+     function makeVersion(result) {
+       return (parseInt(result[1]) * 1000) + parseInt(result[2]);
+     }
+
+     var ua = navigator.userAgent.toLowerCase();
+     if (ua.indexOf("msie") != -1) {
+       var result = /msie ([0-9]+)\.([0-9]+)/.exec(ua);
+       if (result && result.length == 3) {
+         var v = makeVersion(result);
+         if (v < 7000) {
+           return true;
+         }
+       }
+     }
+
+     return false;
+   }-*/;
+}
diff --git a/user/src/com/google/gwt/user/client/ui/LayoutComposite.java b/user/src/com/google/gwt/user/client/ui/LayoutComposite.java
new file mode 100644
index 0000000..f4f5067
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/ui/LayoutComposite.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2009 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;
+
+/**
+ * A {@link Composite} implementation that implements {@link RequiresLayout} and
+ * automatically delegates that interface's methods to its wrapped widget, which
+ * must itself implement {@link RequiresLayout}.
+ */
+public abstract class LayoutComposite extends Composite implements RequiresLayout {
+
+  @Override
+  protected void initWidget(Widget widget) {
+    assert widget instanceof RequiresLayout :
+      "LayoutComposite requires that its wrapped widget implement HasLayout";
+    super.initWidget(widget);
+  }
+
+  public void onLayout() {
+    ((RequiresLayout) getWidget()).onLayout();
+  }
+}
diff --git a/user/src/com/google/gwt/user/client/ui/LayoutPanel.java b/user/src/com/google/gwt/user/client/ui/LayoutPanel.java
new file mode 100644
index 0000000..880b8ae
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/ui/LayoutPanel.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2009 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.dom.client.Document;
+import com.google.gwt.layout.client.Layout;
+import com.google.gwt.layout.client.Layout.Layer;
+
+/**
+ * A panel that lays its children out in arbitrary {@link Layout.Layer layers}
+ * using the {@link Layout} class.
+ * 
+ * <p>
+ * NOTE: This widget will <em>only</em> work in standards mode, which requires
+ * that the HTML page in which it is run have an explicit &lt;!DOCTYPE&gt;
+ * declaration.
+ * </p>
+ * 
+ * <p>
+ * NOTE: This class is still very new, and its interface may change without
+ * warning. Use at your own risk.
+ * </p>
+ * 
+ * <p>
+ * <h3>Example</h3>
+ * {@example com.google.gwt.examples.LayoutPanelExample}
+ * </p>
+ */
+public class LayoutPanel extends ComplexPanel implements RequiresLayout,
+    ProvidesLayout {
+
+  private final Layout layout;
+
+  /**
+   * Creates an empty layout panel.
+   */
+  public LayoutPanel() {
+    setElement(Document.get().createDivElement());
+    layout = new Layout(getElement());
+  }
+
+  /**
+   * Adds a widget to this panel.
+   * 
+   * <p>
+   * By default, each child will fill the panel. To build more interesting
+   * layouts, use {@link #getLayer(Widget)} to get the {@link Layout.Layer}
+   * associated with each child, and set its layout constraints as desired.
+   * </p>
+   * 
+   * @param widget the widget to be added
+   */
+  public void add(Widget widget) {
+    // Detach new child.
+    widget.removeFromParent();
+
+    // Logical attach.
+    getChildren().add(widget);
+
+    // Physical attach.
+    Layer layer = layout.attachChild(widget.getElement(), widget);
+    widget.setLayoutData(layer);
+
+    // Adopt.
+    adopt(widget);
+  }
+
+  /**
+   * This method, or one of its overloads, must be called whenever any of the
+   * {@link Layout.Layer layers} associated with its children is modified.
+   * 
+   * @see #layout(int)
+   * @see #layout(int, com.google.gwt.layout.client.Layout.AnimationCallback)
+   */
+  public void layout() {
+    layout.layout();
+  }
+
+  /**
+   * This method, or one of its overloads, must be called whenever any of the
+   * {@link Layout.Layer layers} associated with its children is modified.
+   * 
+   * <p>
+   * This overload will cause the layout to be updated by animating over a
+   * specified period of time.
+   * </p>
+   * 
+   * @param duration the animation duration, in milliseconds
+   * 
+   * @see #layout()
+   * @see #layout(int, com.google.gwt.layout.client.Layout.AnimationCallback)
+   */
+  public void layout(int duration) {
+    layout.animate(duration);
+  }
+
+  /**
+   * This method, or one of its overloads, must be called whenever any of the
+   * {@link Layout.Layer layers} associated with its children is modified.
+   * 
+   * <p>
+   * This overload will cause the layout to be updated by animating over a
+   * specified period of time. In addition, it provides a callback that will be
+   * informed of updates to the layers. This can be used to create more complex
+   * animation effects.
+   * </p>
+   * 
+   * @param duration the animation duration, in milliseconds
+   * @param callback the animation callback
+   * 
+   * @see #layout()
+   * @see #layout(int, com.google.gwt.layout.client.Layout.AnimationCallback)
+   */
+  public void layout(int duration, final Layout.AnimationCallback callback) {
+    layout.animate(duration, new Layout.AnimationCallback() {
+      public void onAnimationComplete() {
+        // Chain to the passed callback.
+        if (callback != null) {
+          callback.onAnimationComplete();
+        }
+      }
+
+      public void onLayout(Layer layer, double progress) {
+        // Inform the child associated with this layer that its size may have
+        // changed.
+        Widget child = (Widget) layer.getUserObject();
+        if (child instanceof RequiresLayout) {
+          ((RequiresLayout) child).onLayout();
+        }
+
+        // Chain to the passed callback.
+        if (callback != null) {
+          callback.onLayout(layer, progress);
+        }
+      }
+    });
+  }
+
+  public void onLayout() {
+    for (Widget child : getChildren()) {
+      if (child instanceof RequiresLayout) {
+        ((RequiresLayout) child).onLayout();
+      }
+    }
+  }
+
+  /**
+   * Gets the {@link Layer} associated with the given widget. This layer may be
+   * used to manipulate the child widget's layout constraints.
+   * 
+   * <p>
+   * After you have made changes to any of the child widgets' constraints, you
+   * must call one of the {@link HasAnimatedLayout} methods for those changes to
+   * be reflected visually.
+   * </p>
+   * 
+   * @param child the child widget whose layer is to be retrieved
+   * @return the associated layer
+   */
+  public Layout.Layer getLayer(Widget child) {
+    assert child.getParent() == this : "The requested widget is not a child of this panel";
+    return (Layout.Layer) child.getLayoutData();
+  }
+
+  @Override
+  public boolean remove(Widget w) {
+    boolean removed = super.remove(w);
+    if (removed) {
+      layout.removeChild((Layer) w.getLayoutData());
+    }
+    return removed;
+  }
+
+  /**
+   * Gets the {@link Layout} instance associated with this widget.
+   * 
+   * @return this widget's layout instance
+   */
+  protected Layout getLayout() {
+    return layout;
+  }
+
+  @Override
+  protected void onLoad() {
+    layout.attach();
+  }
+
+  @Override
+  protected void onUnload() {
+    layout.detach();
+  }
+}
diff --git a/user/src/com/google/gwt/user/client/ui/ProvidesLayout.java b/user/src/com/google/gwt/user/client/ui/ProvidesLayout.java
new file mode 100644
index 0000000..f6e6d07
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/ui/ProvidesLayout.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2009 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;
+
+/**
+ * This tag interface specifies that the implementing widget will call
+ * {@link RequiresLayout#onLayout()} on its children whenever their size may
+ * have changed.
+ * 
+ * <p>
+ * With limited exceptions (such as {@link RootLayoutPanel}), widgets that
+ * implement this interface will also implement {@link RequiresLayout}. A typical
+ * widget will implement {@link RequiresLayout#onLayout()} like this:
+ * 
+ * <code>
+ * public void onLayout() {
+ *   for (Widget child : getChildren()) {
+ *     if (child instanceof RequiresLayout) {
+ *       ((RequiresLayout) child).onLayout();
+ *     }
+ *   }
+ * }
+ * </code>
+ * </p>
+ */
+public interface ProvidesLayout {
+}
diff --git a/user/src/com/google/gwt/user/client/ui/RequiresLayout.java b/user/src/com/google/gwt/user/client/ui/RequiresLayout.java
new file mode 100644
index 0000000..be81be6
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/ui/RequiresLayout.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2009 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;
+
+/**
+ * This interface designates that its implementor needs to be informed whenever
+ * its size is modified.
+ * 
+ * <p>
+ * Widgets that implement this interface should only be added to those that
+ * implement {@link ProvidesLayout}. Failure to do so will usually result in
+ * {@link #onLayout()} not being called.
+ * </p>
+ */
+public interface RequiresLayout {
+
+  /**
+   * Update the layout immediately.
+   */
+  void onLayout();
+}
diff --git a/user/src/com/google/gwt/user/client/ui/RootLayoutPanel.java b/user/src/com/google/gwt/user/client/ui/RootLayoutPanel.java
new file mode 100644
index 0000000..9c30378
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/ui/RootLayoutPanel.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2009 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.event.logical.shared.ResizeEvent;
+import com.google.gwt.event.logical.shared.ResizeHandler;
+import com.google.gwt.user.client.Window;
+
+/**
+ * A singleton implementation of {@link LayoutPanel} that always attaches itself
+ * to the document body (i.e. {@link RootPanel#get()}).
+ * 
+ * <p>
+ * This panel automatically calls {@link RequiresLayout#layout()} on itself when
+ * initially created, and whenever the window is resized.
+ * </p>
+ * 
+ * <p>
+ * NOTE: This widget will <em>only</em> work in standards mode, which requires
+ * that the HTML page in which it is run have an explicit &lt;!DOCTYPE&gt;
+ * declaration.
+ * </p>
+ * 
+ * <p>
+ * NOTE: This class is still very new, and its interface may change without
+ * warning. Use at your own risk.
+ * </p>
+ * 
+ * <p>
+ * <h3>Example</h3>
+ * {@example com.google.gwt.examples.LayoutPanelExample}
+ * </p>
+ */
+public class RootLayoutPanel extends LayoutPanel implements ProvidesLayout {
+
+  private static RootLayoutPanel singleton;
+
+  /**
+   * Gets the singleton instance of RootLayoutPanel. This instance will always
+   * be attached to the document body via {@link RootPanel#get()}.
+   * 
+   * <p>
+   * Note that, unlike {@link RootPanel#get(String)}, this class provides no way
+   * to get an instance for any element on the page other than the document
+   * body. This is because we know of no way to get resize events for anything
+   * but the window.
+   * </p>
+   */
+  public static RootLayoutPanel get() {
+    if (singleton == null) {
+      singleton = new RootLayoutPanel();
+      RootPanel.get().add(singleton);
+    }
+    return singleton;
+  }
+
+  private RootLayoutPanel() {
+    Window.addResizeHandler(new ResizeHandler() {
+      public void onResize(ResizeEvent event) {
+        onLayout();
+      }
+    });
+
+    // TODO: We need notification of font-size changes as well.
+    // I believe there's a hidden iframe trick that we can use to get
+    // a font-size-change event (really an em-definition-change event).
+  }
+
+  @Override
+  protected void onLoad() {
+    getLayout().attach();
+    getLayout().fillParent();
+  }
+}
diff --git a/user/src/com/google/gwt/user/client/ui/Widget.java b/user/src/com/google/gwt/user/client/ui/Widget.java
index 8c998b3..dcc0a73 100644
--- a/user/src/com/google/gwt/user/client/ui/Widget.java
+++ b/user/src/com/google/gwt/user/client/ui/Widget.java
@@ -54,6 +54,16 @@
   }
 
   /**
+   * Gets the panel-defined layout data associated with this widget.
+   * 
+   * @return the widget's layout data
+   * @see #setLayoutData
+   */
+  public Object getLayoutData() {
+    return layoutData;
+  }
+
+  /**
    * Gets this widget's parent panel.
    * 
    * @return the widget's parent panel
@@ -120,6 +130,18 @@
   }
 
   /**
+   * Sets the panel-defined layout data associated with this widget. Only the
+   * panel that currently contains a widget should ever set this value. It
+   * serves as a place to store layout bookkeeping data associated with a
+   * widget.
+   * 
+   * @param layoutData the widget's layout data
+   */
+  public void setLayoutData(Object layoutData) {
+    this.layoutData = layoutData;
+  }
+
+  /**
    * Overridden to defer the call to super.sinkEvents until the first time this
    * widget is attached to the dom, as a performance enhancement. Subclasses
    * wishing to customize sinkEvents can preserve this deferred sink behavior by
@@ -325,16 +347,6 @@
     return handlerManager;
   }
 
-  /**
-   * Gets the panel-defined layout data associated with this widget.
-   * 
-   * @return the widget's layout data
-   * @see #setLayoutData
-   */
-  Object getLayoutData() {
-    return layoutData;
-  }
-
   @Override
   void replaceElement(com.google.gwt.dom.client.Element elem) {
     if (isAttached()) {
@@ -355,18 +367,6 @@
   }
 
   /**
-   * Sets the panel-defined layout data associated with this widget. Only the
-   * panel that currently contains a widget should ever set this value. It
-   * serves as a place to store layout bookkeeping data associated with a
-   * widget.
-   * 
-   * @param layoutData the widget's layout data
-   */
-  void setLayoutData(Object layoutData) {
-    this.layoutData = layoutData;
-  }
-
-  /**
    * Sets this widget's parent. This method should only be called by
    * {@link Panel} and {@link Composite}.
    * 
diff --git a/user/test/com/google/gwt/layout/LayoutTest.gwt.xml b/user/test/com/google/gwt/layout/LayoutTest.gwt.xml
new file mode 100644
index 0000000..bae48b5
--- /dev/null
+++ b/user/test/com/google/gwt/layout/LayoutTest.gwt.xml
@@ -0,0 +1,17 @@
+<!--                                                                        -->
+<!-- Copyright 2009 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.                                         -->
+
+<module rename-to="LayoutTest">
+	<inherits name="com.google.gwt.layout.Layout"/>
+</module>
diff --git a/user/test/com/google/gwt/layout/client/LayoutTest.java b/user/test/com/google/gwt/layout/client/LayoutTest.java
new file mode 100644
index 0000000..7611556
--- /dev/null
+++ b/user/test/com/google/gwt/layout/client/LayoutTest.java
@@ -0,0 +1,551 @@
+/*
+ * Copyright 2009 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.layout.client;
+
+import static com.google.gwt.dom.client.Style.Unit.CM;
+import static com.google.gwt.dom.client.Style.Unit.EM;
+import static com.google.gwt.dom.client.Style.Unit.EX;
+import static com.google.gwt.dom.client.Style.Unit.IN;
+import static com.google.gwt.dom.client.Style.Unit.MM;
+import static com.google.gwt.dom.client.Style.Unit.PC;
+import static com.google.gwt.dom.client.Style.Unit.PCT;
+import static com.google.gwt.dom.client.Style.Unit.PT;
+import static com.google.gwt.dom.client.Style.Unit.PX;
+
+import com.google.gwt.dom.client.DivElement;
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.Style.Position;
+import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.layout.client.Layout.Layer;
+import com.google.gwt.user.client.Window;
+
+/**
+ * Tests for the {@link Layout} class.
+ * 
+ * TODO: Note that this test is *not* currently part of any suite. We can't run
+ * it reliably until we have a way to switch on "standards" mode in
+ * GWTTestCases.
+ */
+public class LayoutTest extends GWTTestCase {
+
+  private static interface LayerInitializer {
+    void setupLayers(Layer l0, Layer l1);
+  }
+
+  private DivElement parent, child0, child1;
+  private Element wrapper0, wrapper1;
+  private Layout layout;
+  private Layer layer0, layer1;
+
+  @Override
+  public String getModuleName() {
+    return "com.google.gwt.layout.Layout";
+  }
+
+  /**
+   * Tests animation constraint- and unit-transitions.
+   */
+  public void testAnimationTransitions_LTWH_LTRB_PX_CM() {
+    testAnimationTransitions_LTWH_LTRB(PX, CM);
+  }
+
+  /**
+   * Tests animation constraint- and unit-transitions.
+   */
+  public void testAnimationTransitions_LTWH_LTRB_PX_EM() {
+    testAnimationTransitions_LTWH_LTRB(PX, EM);
+  }
+
+  /**
+   * Tests animation constraint- and unit-transitions.
+   */
+  public void testAnimationTransitions_LTWH_LTRB_PX_EX() {
+    testAnimationTransitions_LTWH_LTRB(PX, EX);
+  }
+
+  /**
+   * Tests animation constraint- and unit-transitions.
+   */
+  public void testAnimationTransitions_LTWH_LTRB_PX_PCT() {
+    testAnimationTransitions_LTWH_LTRB(PX, PCT);
+  }
+
+  /**
+   * Tests animation constraint- and unit-transitions.
+   */
+  public void testAnimationTransitions_LTWH_RBWH_PX_CM() {
+    testAnimationTransitions_LTWH_RBWH(PX, CM);
+  }
+
+  /**
+   * Tests animation constraint- and unit-transitions.
+   */
+  public void testAnimationTransitions_LTWH_RBWH_PX_EM() {
+    testAnimationTransitions_LTWH_RBWH(PX, EM);
+  }
+
+  /**
+   * Tests animation constraint- and unit-transitions.
+   */
+  public void testAnimationTransitions_LTWH_RBWH_PX_EX() {
+    testAnimationTransitions_LTWH_RBWH(PX, EX);
+  }
+
+  /**
+   * Tests animation constraint- and unit-transitions.
+   */
+  public void testAnimationTransitions_LTWH_RBWH_PX_PCT() {
+    testAnimationTransitions_LTWH_RBWH(PX, PCT);
+  }
+
+  /**
+   * Tests animation constraint- and unit-transitions.
+   */
+  public void testAnimationTransitions_RBWH_LTRB_PX_CM() {
+    testAnimationTransitions_RBWH_LTRB(PX, CM);
+  }
+
+  /**
+   * Tests animation constraint- and unit-transitions.
+   */
+  public void testAnimationTransitions_RBWH_LTRB_PX_EM() {
+    testAnimationTransitions_RBWH_LTRB(PX, EM);
+  }
+
+  /**
+   * Tests animation constraint- and unit-transitions.
+   */
+  public void testAnimationTransitions_RBWH_LTRB_PX_EX() {
+    testAnimationTransitions_RBWH_LTRB(PX, EX);
+  }
+
+  /**
+   * Tests animation constraint- and unit-transitions.
+   */
+  public void testAnimationTransitions_RBWH_LTRB_PX_PCT() {
+    testAnimationTransitions_RBWH_LTRB(PX, PCT);
+  }
+
+  /**
+   * Test that fillParent() works properly when the outer div is a child of
+   * another div, and that it correctly follows that div's size.
+   */
+  public void testFillParent() {
+    // We don't use the default elements created in gwtSetUp() because we need
+    // to test the behavior when the layout is contained by an element other
+    // than the <body>.
+    Document doc = Document.get();
+    DivElement container = doc.createDivElement();
+    DivElement parent = doc.createDivElement();
+    DivElement child = doc.createDivElement();
+    child.setInnerHTML("&nbsp;");
+    doc.getBody().appendChild(container);
+    container.appendChild(parent);
+
+    // The container has to be position:relative so that it serves as an offset
+    // parent.
+    container.getStyle().setPosition(Position.RELATIVE);
+    container.getStyle().setWidth(128, PX);
+    container.getStyle().setHeight(256, PX);
+
+    Layout layout = new Layout(parent);
+    layout.attach();
+    Layer layer = layout.attachChild(child);
+    layer.setTopBottom(0, PX, 0, PX);
+    layer.setLeftRight(0, PX, 0, PX);
+
+    layout.fillParent();
+    layout.layout();
+
+    // Test 128x256.
+    assertEquals(128, container.getOffsetWidth());
+    assertEquals(256, container.getOffsetHeight());
+    assertEquals(128, parent.getOffsetWidth());
+    assertEquals(256, parent.getOffsetHeight());
+    assertEquals(128, child.getOffsetWidth());
+    assertEquals(256, child.getOffsetHeight());
+
+    // Expand to 256x256. The layout should react automatically.
+    container.getStyle().setWidth(256, PX);
+    container.getStyle().setHeight(128, PX);
+    assertEquals(256, container.getOffsetWidth());
+    assertEquals(256, parent.getOffsetWidth());
+    assertEquals(256, child.getOffsetWidth());
+
+    layout.detach();
+  }
+
+  /**
+   * Test that fillParent() works properly when the outer div is a child of the
+   * document body.
+   */
+  public void testFillWindow() {
+    layer0.setTopBottom(0, PX, 0, PX);
+    layer0.setLeftRight(0, PX, 0, PX);
+    layout.layout();
+
+    int w = Window.getClientWidth();
+    int h = Window.getClientHeight();
+    assertEquals(w, parent.getOffsetWidth());
+    assertEquals(h, parent.getOffsetHeight());
+    assertEquals(w, child0.getOffsetWidth());
+    assertEquals(h, child0.getOffsetHeight());
+  }
+
+  /**
+   * Tests that the layout reacts to font-size changes.
+   */
+  public void testFontSizeChange() {
+    layer0.setLeftWidth(0, PX, 1, EM);
+    layer0.setTopHeight(0, PX, 1, EM);
+    layout.layout();
+
+    parent.getStyle().setFontSize(12, PT);
+    int cw = child0.getOffsetWidth();
+    int ch = child0.getOffsetHeight();
+
+    parent.getStyle().setFontSize(24, PT);
+    int nw = child0.getOffsetWidth();
+    int nh = child0.getOffsetHeight();
+    assertTrue(nw > cw);
+    assertTrue(nh > ch);
+
+    parent.getStyle().clearFontSize();
+  }
+
+  /**
+   * Ensures that two children laid out using various units in such a way that
+   * they should abut one another actually do so.
+   */
+  public void testLayoutStructure() {
+    testHorizontalSplit(CM);
+    testHorizontalSplit(EM);
+    testHorizontalSplit(EX);
+    testHorizontalSplit(IN);
+    testHorizontalSplit(MM);
+    testHorizontalSplit(PC);
+    testHorizontalSplit(PT);
+    testHorizontalSplit(PX);
+  }
+
+  /**
+   * Tests (left-right, left-width, right-width) x (top-bottom, top-height,
+   * bottom-height). Ok, so we don't test the *entire* cross-product, but enough
+   * to be comfortable.
+   */
+  public void testStaticConstraints() {
+    // left-right, top-bottom
+    layer0.setTopBottom(32, PX, 32, PX);
+    layer0.setLeftRight(32, PX, 32, PX);
+    layout.layout();
+
+    int w = parent.getClientWidth();
+    int h = parent.getClientHeight();
+    assertEquals(32, wrapper0.getOffsetLeft());
+    assertEquals(32, wrapper0.getOffsetTop());
+    assertEquals(w - 64, wrapper0.getOffsetWidth());
+    assertEquals(h - 64, wrapper0.getOffsetHeight());
+
+    // left-width, top-height
+    layer0.setTopHeight(16, PX, 128, PX);
+    layer0.setLeftWidth(16, PX, 128, PX);
+    layout.layout();
+
+    assertEquals(16, wrapper0.getOffsetLeft());
+    assertEquals(16, wrapper0.getOffsetTop());
+    assertEquals(128, wrapper0.getOffsetWidth());
+    assertEquals(128, wrapper0.getOffsetHeight());
+
+    // right-width, bottom-height
+    layer0.setBottomHeight(16, PX, 128, PX);
+    layer0.setRightWidth(16, PX, 128, PX);
+    layout.layout();
+
+    assertEquals(w - (16 + 128), wrapper0.getOffsetLeft());
+    assertEquals(h - (16 + 128), wrapper0.getOffsetTop());
+    assertEquals(128, wrapper0.getOffsetWidth());
+    assertEquals(128, wrapper0.getOffsetHeight());
+  }
+
+  /**
+   * Tests all unit types.
+   */
+  public void testUnits() {
+    // CM
+    layer0.setTopBottom(1, CM, 1, CM);
+    layer0.setLeftRight(1, CM, 1, CM);
+    layout.layout();
+    assertLeftRightTopBottomUnitsMakeSense(wrapper0);
+
+    // MM
+    layer0.setTopBottom(1, MM, 1, MM);
+    layer0.setLeftRight(1, MM, 1, MM);
+    layout.layout();
+    assertLeftRightTopBottomUnitsMakeSense(wrapper0);
+
+    // IN
+    layer0.setTopBottom(1, IN, 1, IN);
+    layer0.setLeftRight(1, IN, 1, IN);
+    layout.layout();
+    assertLeftRightTopBottomUnitsMakeSense(wrapper0);
+
+    // EM
+    layer0.setTopBottom(1, EM, 1, EM);
+    layer0.setLeftRight(1, EM, 1, EM);
+    layout.layout();
+    assertLeftRightTopBottomUnitsMakeSense(wrapper0);
+
+    // EX
+    layer0.setTopBottom(1, EX, 1, EX);
+    layer0.setLeftRight(1, EX, 1, EX);
+    layout.layout();
+    assertLeftRightTopBottomUnitsMakeSense(wrapper0);
+
+    // PC
+    layer0.setTopBottom(1, PC, 1, PC);
+    layer0.setLeftRight(1, PC, 1, PC);
+    layout.layout();
+    assertLeftRightTopBottomUnitsMakeSense(wrapper0);
+
+    // PT
+    layer0.setTopBottom(10, PT, 10, PT);
+    layer0.setLeftRight(10, PT, 10, PT);
+    layout.layout();
+    assertLeftRightTopBottomUnitsMakeSense(wrapper0);
+
+    // PCT
+    layer0.setTopBottom(10, PCT, 10, PCT);
+    layer0.setLeftRight(10, PCT, 10, PCT);
+    layout.layout();
+    assertLeftRightTopBottomUnitsMakeSense(wrapper0);
+  }
+
+  /**
+   * Tests layout in the presence of decorations on the parent and child
+   * elements.
+   */
+  public void testWithDecorations() {
+    layer0.setTopBottom(0, PX, 0, PX);
+    layer0.setLeftRight(0, PX, 0, PX);
+    layout.layout();
+
+    // Give each of the parent and child 1px margin and 1px border.
+    parent.getStyle().setMargin(1, PX);
+    parent.getStyle().setProperty("border", "1px solid black");
+
+    child0.getStyle().setMargin(1, PX);
+    child0.getStyle().setProperty("border", "1px solid black");
+    layout.layout();
+
+    int w = Window.getClientWidth();
+    int h = Window.getClientHeight();
+    int pw = parent.getOffsetWidth();
+    int ph = parent.getOffsetHeight();
+
+    // The parent's offsetSize should be 2px smaller than the window's client
+    // area, because of the margin (the border is *included* in the offsetSize).
+    assertEquals(w - 2, pw);
+    assertEquals(h - 2, ph);
+
+    // The child's offsetSize (actually that of its wrapper element), should be
+    // 2px smaller than the parent, for precisely the same reason.
+    assertEquals(pw - 2, wrapper0.getOffsetWidth());
+    assertEquals(ph - 2, wrapper0.getOffsetHeight());
+  }
+
+  @Override
+  protected void gwtSetUp() throws Exception {
+    Window.enableScrolling(false);
+
+    Document doc = Document.get();
+    parent = doc.createDivElement();
+    child0 = doc.createDivElement();
+    child1 = doc.createDivElement();
+    doc.getBody().appendChild(parent);
+
+    layout = new Layout(parent);
+    layout.attach();
+    layout.fillParent();
+
+    layer0 = layout.attachChild(child0);
+    layer1 = layout.attachChild(child1);
+
+    wrapper0 = child0.getParentElement();
+    wrapper1 = child1.getParentElement();
+  }
+
+  @Override
+  protected void gwtTearDown() throws Exception {
+    Window.enableScrolling(true);
+    Document.get().getBody().removeChild(parent);
+    layout.detach();
+  }
+
+  private void assertLeftRightTopBottomUnitsMakeSense(Element elem) {
+    // Assume that the element has been laid out to (l, t, r, b) = (1u, 1u, 1u,
+    // 1u). Assert that the element's clientLeft/Top are non-zero, and that the
+    // clientLeft/Top/Width/Height are consistent with the parent's size.
+    int w = parent.getClientWidth();
+    int h = parent.getClientHeight();
+    int cl = elem.getOffsetLeft();
+    int ct = elem.getOffsetTop();
+    int cw = elem.getOffsetWidth();
+    int ch = elem.getOffsetHeight();
+
+    // Assert that the left-top unit came out at least non-zero size.
+    assertTrue(cl > 0);
+    assertTrue(ct > 0);
+
+    // Assert that the right-bottom also came out non-zero. We should be able
+    // to assert that it came out the same size as the top-left, but it turns
+    // out that this isn't quite reliable because of rounding errors.
+    assertTrue(w - (cl + cw) > 0);
+    assertTrue(h - (ct + ch) > 0);
+  }
+
+  // This method may only be called once per test, as it uses delayTestFinish()
+  // internally.
+  private void testAnimationTransitions_LTWH_LTRB(final Unit unit0,
+      final Unit unit1) {
+    testAnimationTransitionsHelper(new LayerInitializer() {
+      public void setupLayers(Layer l0, Layer l1) {
+        l0.setLeftWidth(0, unit0, 10, unit0);
+        l0.setTopHeight(0, unit0, 10, unit0);
+        l1.setLeftRight(1, unit1, 1, unit1);
+        l1.setTopBottom(1, unit1, 1, unit1);
+      }
+    }, new LayerInitializer() {
+      public void setupLayers(Layer l0, Layer l1) {
+        l1.setLeftWidth(0, unit0, 10, unit0);
+        l1.setTopHeight(0, unit0, 10, unit0);
+        l0.setLeftRight(1, unit1, 1, unit1);
+        l0.setTopBottom(1, unit1, 1, unit1);
+      }
+    });
+  }
+
+  // This method may only be called once per test, as it uses delayTestFinish()
+  // internally.
+  private void testAnimationTransitions_LTWH_RBWH(final Unit unit0,
+      final Unit unit1) {
+    testAnimationTransitionsHelper(new LayerInitializer() {
+      public void setupLayers(Layer l0, Layer l1) {
+        l0.setLeftWidth(0, unit0, 10, unit0);
+        l0.setTopHeight(0, unit0, 10, unit0);
+        l1.setRightWidth(0, unit1, 10, unit1);
+        l1.setBottomHeight(0, unit1, 10, unit1);
+      }
+    }, new LayerInitializer() {
+      public void setupLayers(Layer l0, Layer l1) {
+        l1.setLeftWidth(0, unit0, 10, unit0);
+        l1.setTopHeight(0, unit0, 10, unit0);
+        l0.setRightWidth(0, unit1, 10, unit1);
+        l0.setBottomHeight(0, unit1, 10, unit1);
+      }
+    });
+  }
+
+  // This method may only be called once per test, as it uses delayTestFinish()
+  // internally.
+  private void testAnimationTransitions_RBWH_LTRB(final Unit unit0,
+      final Unit unit1) {
+    testAnimationTransitionsHelper(new LayerInitializer() {
+      public void setupLayers(Layer l0, Layer l1) {
+        l0.setRightWidth(0, unit0, 10, unit0);
+        l0.setBottomHeight(0, unit0, 10, unit0);
+        l1.setLeftRight(1, unit1, 1, unit1);
+        l1.setTopBottom(1, unit1, 1, unit1);
+      }
+    }, new LayerInitializer() {
+      public void setupLayers(Layer l0, Layer l1) {
+        l1.setRightWidth(0, unit0, 10, unit0);
+        l1.setBottomHeight(0, unit0, 10, unit0);
+        l0.setLeftRight(1, unit1, 1, unit1);
+        l0.setTopBottom(1, unit1, 1, unit1);
+      }
+    });
+  }
+
+  // This method may only be called once per test, as it uses delayTestFinish()
+  // internally.
+  private void testAnimationTransitionsHelper(LayerInitializer before,
+      LayerInitializer after) {
+    before.setupLayers(layer0, layer1);
+    layout.layout();
+
+    final int l0 = wrapper0.getOffsetLeft();
+    final int t0 = wrapper0.getOffsetTop();
+    final int w0 = wrapper0.getOffsetWidth();
+    final int h0 = wrapper0.getOffsetHeight();
+
+    final int l1 = wrapper1.getOffsetLeft();
+    final int t1 = wrapper1.getOffsetTop();
+    final int w1 = wrapper1.getOffsetWidth();
+    final int h1 = wrapper1.getOffsetHeight();
+
+    after.setupLayers(layer0, layer1);
+    delayTestFinish(200);
+    layout.animate(100, new Layout.AnimationCallback() {
+      public void onAnimationComplete() {
+        // Assert that the two layers have swapped positions.
+        assertEquals(l0, wrapper1.getOffsetLeft());
+        assertEquals(t0, wrapper1.getOffsetTop());
+        assertEquals(w0, wrapper1.getOffsetWidth());
+        assertEquals(h0, wrapper1.getOffsetHeight());
+
+        assertEquals(l1, wrapper0.getOffsetLeft());
+        assertEquals(t1, wrapper0.getOffsetTop());
+        assertEquals(w1, wrapper0.getOffsetWidth());
+        assertEquals(h1, wrapper0.getOffsetHeight());
+
+        finishTest();
+      }
+
+      public void onLayout(Layer layer, double progress) {
+      }
+    });
+  }
+
+  private void testHorizontalSplit(Unit unit) {
+    // Line them up horizontally, split at 5 units.
+    layer0.setTopBottom(0, PX, 0, PX);
+    layer0.setLeftWidth(0, PX, 5, unit);
+
+    layer1.setTopBottom(0, PX, 0, PX);
+    layer1.setLeftRight(5, unit, 0, PX);
+    layout.layout();
+
+    int child0Right = wrapper0.getOffsetWidth();
+    int child1Left = wrapper1.getOffsetLeft();
+    assertEquals(child0Right, child1Left);
+  }
+
+  private void testVerticalSplit(Unit unit) {
+    // Line them up vertically, split at 5em.
+    layer0.setTopHeight(0, PX, 5, unit);
+    layer0.setLeftRight(0, PX, 0, PX);
+
+    layer1.setTopBottom(5, unit, 0, PX);
+    layer1.setLeftRight(0, PX, 0, PX);
+    layout.layout();
+
+    int child0Bottom = wrapper0.getOffsetHeight();
+    int child1Top = wrapper1.getOffsetTop();
+    assertEquals(child0Bottom, child1Top);
+  }
+}
