return a list of other invalidated boxes when reconciling layout

Instead of indicated that something has changed and outer boxes have to
adapt, we return a list of the boxes that need to adapt. This can e.g.
be used by table cells that span over several rows, to indicate which
rows need to be reconciled.

Signed-off-by: Florian Thienel <florian@thienel.org>
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/boxes/FakeContentBox.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/boxes/FakeContentBox.java
index 013c725..1e690eb 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/boxes/FakeContentBox.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/boxes/FakeContentBox.java
@@ -10,6 +10,8 @@
  *******************************************************************************/
 package org.eclipse.vex.core.internal.boxes;
 
+import java.util.Collection;
+
 import org.eclipse.vex.core.internal.core.Color;
 import org.eclipse.vex.core.internal.core.Graphics;
 import org.eclipse.vex.core.internal.core.Rectangle;
@@ -82,8 +84,8 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
-		return false;
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
+		return NOTHING_INVALIDATED;
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/GraphicalBullet.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/GraphicalBullet.java
index 416d3ec..e168d18 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/GraphicalBullet.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/GraphicalBullet.java
@@ -10,6 +10,9 @@
  *******************************************************************************/
 package org.eclipse.vex.core.internal.boxes;
 
+import java.util.Collection;
+import java.util.Collections;
+
 import org.eclipse.vex.core.internal.core.Color;
 import org.eclipse.vex.core.internal.core.FontResource;
 import org.eclipse.vex.core.internal.core.FontSpec;
@@ -86,12 +89,16 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		final int oldHeight = height;
 
 		layout(graphics);
 
-		return height != oldHeight;
+		if (height != oldHeight) {
+			return Collections.singleton(getParent());
+		} else {
+			return NOTHING_INVALIDATED;
+		}
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/HorizontalBar.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/HorizontalBar.java
index 7c89188..1310a97 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/HorizontalBar.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/HorizontalBar.java
@@ -10,6 +10,8 @@
  *******************************************************************************/
 package org.eclipse.vex.core.internal.boxes;
 
+import java.util.Collection;
+
 import org.eclipse.vex.core.internal.core.Color;
 import org.eclipse.vex.core.internal.core.ColorResource;
 import org.eclipse.vex.core.internal.core.Graphics;
@@ -116,9 +118,9 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		// ignore, everything is static
-		return false;
+		return NOTHING_INVALIDATED;
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/IBox.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/IBox.java
index 1592677..9cd82dd 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/IBox.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/IBox.java
@@ -10,6 +10,9 @@
  *******************************************************************************/
 package org.eclipse.vex.core.internal.boxes;
 
+import java.util.Collection;
+import java.util.Collections;
+
 import org.eclipse.vex.core.internal.core.Graphics;
 import org.eclipse.vex.core.internal.core.Rectangle;
 
@@ -18,6 +21,8 @@
  */
 public interface IBox {
 
+	Collection<IBox> NOTHING_INVALIDATED = Collections.emptyList();
+
 	int getAbsoluteTop();
 
 	int getAbsoluteLeft();
@@ -38,7 +43,7 @@
 
 	void layout(Graphics graphics);
 
-	boolean reconcileLayout(Graphics graphics);
+	Collection<IBox> reconcileLayout(Graphics graphics);
 
 	void paint(Graphics graphics);
 
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/Image.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/Image.java
index 9a0623e..473fed7 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/Image.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/Image.java
@@ -11,6 +11,8 @@
 package org.eclipse.vex.core.internal.boxes;
 
 import java.net.URL;
+import java.util.Collection;
+import java.util.Collections;
 
 import org.eclipse.vex.core.internal.core.Graphics;
 import org.eclipse.vex.core.internal.core.Length;
@@ -221,13 +223,17 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		final int oldHeight = height;
 		final int oldWidth = width;
 
 		layout(graphics);
 
-		return oldHeight != height || oldWidth != width;
+		if (oldHeight != height || oldWidth != width) {
+			return Collections.singleton(getParent());
+		} else {
+			return NOTHING_INVALIDATED;
+		}
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/InlineContainer.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/InlineContainer.java
index ffcee5d..459a0af 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/InlineContainer.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/InlineContainer.java
@@ -11,6 +11,7 @@
 package org.eclipse.vex.core.internal.boxes;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.LinkedList;
 import java.util.ListIterator;
 
@@ -263,12 +264,17 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		final int oldWidth = width;
 		final int oldHeight = height;
 		final int oldBaseline = baseline;
 		calculateBoundsAndBaseline();
-		return oldWidth != width || oldHeight != height || oldBaseline != baseline;
+
+		if (oldWidth != width || oldHeight != height || oldBaseline != baseline) {
+			return Collections.singleton(getParent());
+		} else {
+			return NOTHING_INVALIDATED;
+		}
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/InlineFrame.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/InlineFrame.java
index 2cad78a..1aa11e2 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/InlineFrame.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/InlineFrame.java
@@ -10,6 +10,9 @@
  *******************************************************************************/
 package org.eclipse.vex.core.internal.boxes;
 
+import java.util.Collection;
+import java.util.Collections;
+
 import org.eclipse.vex.core.internal.core.Color;
 import org.eclipse.vex.core.internal.core.Graphics;
 import org.eclipse.vex.core.internal.core.Rectangle;
@@ -227,13 +230,17 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		final int oldHeight = height;
 		final int oldWidth = width;
 
 		calculateBounds();
 
-		return oldHeight != height || oldWidth != width;
+		if (oldHeight != height || oldWidth != width) {
+			return Collections.singleton(getParent());
+		} else {
+			return NOTHING_INVALIDATED;
+		}
 	}
 
 	private int topFrame(final int componentHeight) {
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/InlineNodeReference.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/InlineNodeReference.java
index 5fae4e3..bf4b9e2 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/InlineNodeReference.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/InlineNodeReference.java
@@ -11,6 +11,8 @@
 package org.eclipse.vex.core.internal.boxes;
 
 import java.text.MessageFormat;
+import java.util.Collection;
+import java.util.Collections;
 
 import org.eclipse.core.runtime.Assert;
 import org.eclipse.vex.core.internal.core.Color;
@@ -210,7 +212,7 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		final int oldWidth = width;
 		final int oldHeight = height;
 		final int oldBaseline = baseline;
@@ -220,7 +222,11 @@
 
 		layout(graphics);
 
-		return oldWidth != width || oldHeight != height || oldBaseline != baseline;
+		if (oldWidth != width || oldHeight != height || oldBaseline != baseline) {
+			return Collections.singleton(getParent());
+		} else {
+			return NOTHING_INVALIDATED;
+		}
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/List.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/List.java
index b09a4fe..ebef04f 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/List.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/List.java
@@ -1,6 +1,8 @@
 package org.eclipse.vex.core.internal.boxes;
 
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
 
 import org.eclipse.vex.core.internal.core.Graphics;
 import org.eclipse.vex.core.internal.core.Rectangle;
@@ -174,14 +176,14 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		final int oldHeight = height;
 		height = component.getHeight();
 		if (oldHeight != height) {
 			layout(graphics);
-			return true;
+			return Collections.singleton(getParent());
 		}
-		return false;
+		return NOTHING_INVALIDATED;
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/ListItem.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/ListItem.java
index 6717e4f..fda1389 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/ListItem.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/ListItem.java
@@ -12,6 +12,8 @@
 
 import static org.eclipse.vex.core.internal.boxes.BoxFactory.frame;
 
+import java.util.Collection;
+import java.util.Collections;
 import java.util.Iterator;
 
 import org.eclipse.vex.core.internal.core.Graphics;
@@ -324,7 +326,7 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		final int oldHeight = height;
 
 		if (bulletPosition == BulletStyle.Position.INSIDE && component != null) {
@@ -334,7 +336,11 @@
 
 		height = Math.max(getBulletHeight(), getComponentHeight());
 
-		return oldHeight != height;
+		if (oldHeight != height) {
+			return Collections.singleton(getParent());
+		} else {
+			return NOTHING_INVALIDATED;
+		}
 	}
 
 	private int getBulletHeight() {
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/NodeEndOffsetPlaceholder.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/NodeEndOffsetPlaceholder.java
index eba4066..b76ddff 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/NodeEndOffsetPlaceholder.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/NodeEndOffsetPlaceholder.java
@@ -10,6 +10,9 @@
  *******************************************************************************/
 package org.eclipse.vex.core.internal.boxes;
 
+import java.util.Collection;
+import java.util.Collections;
+
 import org.eclipse.vex.core.internal.core.Color;
 import org.eclipse.vex.core.internal.core.FontMetrics;
 import org.eclipse.vex.core.internal.core.FontSpec;
@@ -187,12 +190,12 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		if (layoutValid) {
-			return false;
+			return NOTHING_INVALIDATED;
 		}
 		layout(graphics);
-		return true;
+		return Collections.singleton(getParent());
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/NodeTag.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/NodeTag.java
index 773115d..2b9a939 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/NodeTag.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/NodeTag.java
@@ -10,6 +10,9 @@
  *******************************************************************************/
 package org.eclipse.vex.core.internal.boxes;
 
+import java.util.Collection;
+import java.util.Collections;
+
 import org.eclipse.vex.core.internal.core.Color;
 import org.eclipse.vex.core.internal.core.Graphics;
 import org.eclipse.vex.core.internal.core.NodeGraphics;
@@ -135,11 +138,16 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		final int oldWidth = width;
 		final int oldHeight = height;
 		layout(graphics);
-		return oldWidth != width || oldHeight != height;
+
+		if (oldWidth != width || oldHeight != height) {
+			return Collections.singleton(getParent());
+		} else {
+			return NOTHING_INVALIDATED;
+		}
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/Paragraph.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/Paragraph.java
index 95dd647..213b7e5 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/Paragraph.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/Paragraph.java
@@ -11,6 +11,7 @@
 package org.eclipse.vex.core.internal.boxes;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.LinkedList;
 import java.util.ListIterator;
 
@@ -190,10 +191,15 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		final int oldHeight = lines.getHeight();
 		arrangeChildrenOnLines(graphics);
-		return oldHeight != lines.getHeight();
+
+		if (oldHeight != lines.getHeight()) {
+			return Collections.singleton(getParent());
+		} else {
+			return NOTHING_INVALIDATED;
+		}
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/RootBox.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/RootBox.java
index d8fb9fd..592c694 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/RootBox.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/RootBox.java
@@ -128,15 +128,14 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
-		final int oldHeight = height;
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		height = 0;
 		for (int i = 0; i < children.size(); i += 1) {
 			final IStructuralBox child = children.get(i);
 			child.setPosition(height, 0);
 			height += child.getHeight();
 		}
-		return oldHeight != height;
+		return NOTHING_INVALIDATED;
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/Square.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/Square.java
index 55526b4..d5f3ada 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/Square.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/Square.java
@@ -10,6 +10,8 @@
  *******************************************************************************/
 package org.eclipse.vex.core.internal.boxes;
 
+import java.util.Collection;
+
 import org.eclipse.vex.core.internal.core.Color;
 import org.eclipse.vex.core.internal.core.Graphics;
 
@@ -59,8 +61,8 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
-		return false; // static size
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
+		return NOTHING_INVALIDATED; // static size
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/StaticText.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/StaticText.java
index da7c9b4..77e5688 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/StaticText.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/StaticText.java
@@ -13,6 +13,9 @@
 import static org.eclipse.vex.core.internal.core.TextUtils.countWhitespaceAtEnd;
 import static org.eclipse.vex.core.internal.core.TextUtils.countWhitespaceAtStart;
 
+import java.util.Collection;
+import java.util.Collections;
+
 import org.eclipse.vex.core.internal.core.Color;
 import org.eclipse.vex.core.internal.core.FontMetrics;
 import org.eclipse.vex.core.internal.core.FontResource;
@@ -208,14 +211,18 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		final int oldHeight = height;
 		final int oldWidth = width;
 		final int oldBaseline = baseline;
 
 		layout(graphics);
 
-		return oldHeight != height || oldWidth != width || oldBaseline != baseline;
+		if (oldHeight != height || oldWidth != width || oldBaseline != baseline) {
+			return Collections.singleton(getParent());
+		} else {
+			return NOTHING_INVALIDATED;
+		}
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/StructuralFrame.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/StructuralFrame.java
index ee3c244..ede0334 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/StructuralFrame.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/StructuralFrame.java
@@ -10,6 +10,9 @@
  *******************************************************************************/
 package org.eclipse.vex.core.internal.boxes;
 
+import java.util.Collection;
+import java.util.Collections;
+
 import org.eclipse.vex.core.internal.core.Color;
 import org.eclipse.vex.core.internal.core.Graphics;
 import org.eclipse.vex.core.internal.core.Rectangle;
@@ -184,14 +187,18 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		final int oldHeight = height;
 
 		height = component.getHeight();
 		height += topFrame(component.getHeight());
 		height += bottomFrame(component.getHeight());
 
-		return oldHeight != height;
+		if (oldHeight != height) {
+			return Collections.singleton(getParent());
+		} else {
+			return NOTHING_INVALIDATED;
+		}
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/StructuralNodeReference.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/StructuralNodeReference.java
index 161c315..7969851 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/StructuralNodeReference.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/StructuralNodeReference.java
@@ -10,6 +10,9 @@
  *******************************************************************************/
 package org.eclipse.vex.core.internal.boxes;
 
+import java.util.Collection;
+import java.util.Collections;
+
 import org.eclipse.vex.core.internal.core.Color;
 import org.eclipse.vex.core.internal.core.Graphics;
 import org.eclipse.vex.core.internal.core.LineStyle;
@@ -158,10 +161,15 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		final int oldHeight = height;
 		height = component.getHeight();
-		return oldHeight != height;
+
+		if (oldHeight != height) {
+			return Collections.singleton(getParent());
+		} else {
+			return NOTHING_INVALIDATED;
+		}
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/Table.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/Table.java
index 11ed90d..e9a3c37 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/Table.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/Table.java
@@ -12,6 +12,7 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.ListIterator;
 
 import org.eclipse.vex.core.internal.core.Graphics;
@@ -173,9 +174,9 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		layout(graphics);
-		return true;
+		return Collections.singleton(getParent());
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableCell.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableCell.java
index e8ab3e8..f7393ff 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableCell.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableCell.java
@@ -10,6 +10,9 @@
  *******************************************************************************/
 package org.eclipse.vex.core.internal.boxes;
 
+import java.util.Collection;
+import java.util.Collections;
+
 import org.eclipse.vex.core.internal.core.Graphics;
 import org.eclipse.vex.core.internal.core.Rectangle;
 
@@ -189,17 +192,17 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		final int oldHeight = naturalHeight;
 		naturalHeight = calculateNaturalHeight(graphics, width);
 
 		if (oldHeight == naturalHeight) {
-			return false;
+			return NOTHING_INVALIDATED;
 		}
 
 		component.setPosition(0, 0);
 		adjustComponentHeight();
-		return true;
+		return Collections.singleton(getParent());
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableColumnSpec.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableColumnSpec.java
index 0a6e008..78a1210 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableColumnSpec.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableColumnSpec.java
@@ -10,6 +10,9 @@
  *******************************************************************************/
 package org.eclipse.vex.core.internal.boxes;
 
+import java.util.Collection;
+import java.util.Collections;
+
 import org.eclipse.vex.core.internal.core.Graphics;
 import org.eclipse.vex.core.internal.core.Rectangle;
 
@@ -176,10 +179,15 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		final int oldHeight = height;
 		height = component.getHeight();
-		return oldHeight != height;
+
+		if (oldHeight != height) {
+			return Collections.singleton(getParent());
+		} else {
+			return NOTHING_INVALIDATED;
+		}
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableRow.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableRow.java
index 1bf81af..d4eb273 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableRow.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableRow.java
@@ -12,6 +12,7 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.ListIterator;
 
 import org.eclipse.vex.core.internal.core.Graphics;
@@ -229,10 +230,15 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		final int oldHeight = height;
 		layout(graphics);
-		return oldHeight != height;
+
+		if (oldHeight != height) {
+			return Collections.singleton(getParent());
+		} else {
+			return NOTHING_INVALIDATED;
+		}
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableRowGroup.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableRowGroup.java
index a562ab8..0cdd41c 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableRowGroup.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableRowGroup.java
@@ -12,6 +12,7 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.ListIterator;
 
 import org.eclipse.vex.core.internal.core.Graphics;
@@ -173,7 +174,7 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		final int oldHeight = height;
 		height = 0;
 		for (int i = 0; i < children.size(); i += 1) {
@@ -181,7 +182,12 @@
 			child.setPosition(height, 0);
 			height += child.getHeight();
 		}
-		return oldHeight != height;
+
+		if (oldHeight != height) {
+			return Collections.singleton(getParent());
+		} else {
+			return NOTHING_INVALIDATED;
+		}
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TextContent.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TextContent.java
index 22f2bdc..017b533 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TextContent.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TextContent.java
@@ -13,6 +13,9 @@
 import static org.eclipse.vex.core.internal.core.TextUtils.countWhitespaceAtEnd;
 import static org.eclipse.vex.core.internal.core.TextUtils.countWhitespaceAtStart;
 
+import java.util.Collection;
+import java.util.Collections;
+
 import org.eclipse.core.runtime.Assert;
 import org.eclipse.vex.core.internal.core.Color;
 import org.eclipse.vex.core.internal.core.FontMetrics;
@@ -236,14 +239,18 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		final int oldHeight = height;
 		final int oldWidth = width;
 		final int oldBaseline = baseline;
 
 		layout(graphics);
 
-		return oldHeight != height || oldWidth != width || oldBaseline != baseline;
+		if (oldHeight != height || oldWidth != width || oldBaseline != baseline) {
+			return Collections.singleton(getParent());
+		} else {
+			return NOTHING_INVALIDATED;
+		}
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/VerticalBlock.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/VerticalBlock.java
index 43c6324..f78d774 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/VerticalBlock.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/VerticalBlock.java
@@ -12,6 +12,7 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.ListIterator;
 
 import org.eclipse.vex.core.internal.core.Graphics;
@@ -153,7 +154,7 @@
 	}
 
 	@Override
-	public boolean reconcileLayout(final Graphics graphics) {
+	public Collection<IBox> reconcileLayout(final Graphics graphics) {
 		final int oldHeight = height;
 		height = 0;
 		for (int i = 0; i < children.size(); i += 1) {
@@ -161,7 +162,12 @@
 			child.setPosition(height, 0);
 			height += child.getHeight();
 		}
-		return oldHeight != height;
+
+		if (oldHeight != height) {
+			return Collections.singleton(getParent());
+		} else {
+			return NOTHING_INVALIDATED;
+		}
 	}
 
 	@Override
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/BoxView.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/BoxView.java
index a19616e..fc0d810 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/BoxView.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/BoxView.java
@@ -10,8 +10,10 @@
  *******************************************************************************/
 package org.eclipse.vex.core.internal.widget;
 
+import java.util.Collection;
+import java.util.LinkedList;
+
 import org.eclipse.vex.core.internal.boxes.IBox;
-import org.eclipse.vex.core.internal.boxes.IChildBox;
 import org.eclipse.vex.core.internal.boxes.RootBox;
 import org.eclipse.vex.core.internal.core.Graphics;
 import org.eclipse.vex.core.internal.core.Rectangle;
@@ -109,8 +111,17 @@
 		return new IRenderStep() {
 			@Override
 			public void render(final Graphics graphics) {
-				box.layout(graphics);
-				reconcileParentsLayout(box, graphics);
+				final LinkedList<IBox> invalidatedBoxes = new LinkedList<IBox>();
+				invalidatedBoxes.add(box);
+
+				while (!invalidatedBoxes.isEmpty()) {
+					final IBox invalidatedBox = invalidatedBoxes.pollFirst();
+					final Collection<IBox> nextBoxes = invalidatedBox.reconcileLayout(graphics);
+
+					invalidatedBoxes.addAll(nextBoxes); // TODO add only required boxes
+					// TODO remove unneccessary boxes
+				}
+
 				reconcileViewPort();
 			}
 		};
@@ -120,20 +131,6 @@
 		viewPort.reconcile(rootBox.getHeight() + Cursor.CARET_BUFFER);
 	}
 
-	private void reconcileParentsLayout(final IBox box, final Graphics graphics) {
-		IBox parentBox = getParentBox(box);
-		while (parentBox != null && parentBox.reconcileLayout(graphics)) {
-			parentBox = getParentBox(parentBox);
-		}
-	}
-
-	private IBox getParentBox(final IBox box) {
-		if (box instanceof IChildBox) {
-			return ((IChildBox) box).getParent();
-		}
-		return null;
-	}
-
 	private IRenderStep renderCursorMovement() {
 		return new IRenderStep() {
 			@Override