Index: src/java/org/apache/fop/layoutmgr/LayoutManager.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/apache/fop/layoutmgr/LayoutManager.java	(revision 1686091)
+++ src/java/org/apache/fop/layoutmgr/LayoutManager.java	(revision )
@@ -114,7 +114,7 @@
     /**
      * @return the list of child LMs
      */
-    List getChildLMs();
+    List<LayoutManager> getChildLMs();
 
     /**
      * Add the LM in the argument to the list of child LMs;
@@ -271,4 +271,13 @@
      */
     List getNextKnuthElements(LayoutContext context, int alignment, Stack lmStack,
             Position positionAtIPDChange, LayoutManager restartAtLM);
+
+
+    /**
+     * Iterates over all childLMs to obtain the minimal width required to render all of them (i.e. their content)
+     * without an overflow.
+     * @return returns the longest required minimal width of all contained layout managers
+     */
+    int getMinimumIPD();
+
 }
Index: src/java/org/apache/fop/fo/flow/table/Table.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/apache/fop/fo/flow/table/Table.java	(revision 1686091)
+++ src/java/org/apache/fop/fo/flow/table/Table.java	(revision )
@@ -152,10 +152,6 @@
             eventProducer.nonAutoBPDOnTable(this, getLocator());
             // Anyway, the bpd of a table is not used by the layout code
         }
-        if (tableLayout == EN_AUTO) {
-            getFOValidationEventProducer().unimplementedFeature(this, getName(),
-                    "table-layout=\"auto\"", getLocator());
-        }
         if (!isSeparateBorderModel()) {
             if (borderCollapse == EN_COLLAPSE_WITH_PRECEDENCE) {
                 getFOValidationEventProducer().unimplementedFeature(this, getName(),
Index: src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java	(revision 1686091)
+++ src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java	(revision )
@@ -131,6 +131,8 @@
 
     private final Position auxiliaryPosition = new LeafPosition(this, -1);
 
+    private int minimumIPD = -1;
+
     /**
      * Create a Text layout manager.
      *
@@ -873,12 +875,42 @@
         if (returnList.isEmpty()) {
             return null;
         } else {
+            determineMinIPD(returnList, context);
             return returnList;
         }
 
 
     }
 
+    /**
+     * Determines the minIPD of the textLM's {@link #foText} by returning the width of its longest string.<br>
+     * TODO: Currently, this dedicated iteration is rather wasteful and should be integrated 
+     * into {@link #getNextKnuthElements(LayoutContext, int)}, if possible. Additionally, the
+     * algorithm is quite trivial and does not take any linebreak possibilities etc. into account.
+     * @param returnList KnuthSequence of KnuthElements representing the object's {@link #foText}
+     * @param context 
+     */
+    private void determineMinIPD(List returnList, LayoutContext context) {
+        minimumIPD = 0;
+        ListIterator iter = returnList.listIterator();
+        while (iter.hasNext()) {
+            KnuthSequence sequence = (KnuthSequence) iter.next();
+
+            if (context.isInAutoLayoutDeterminationMode()) {
+                final ListIterator i = sequence.listIterator();
+
+                while (i.hasNext()) {
+                    final KnuthElement element = (KnuthElement) i.next();
+                    if (element instanceof KnuthBox) {
+                        //TODO: improve algorithm!
+                        minimumIPD = Math.max(minimumIPD, element.getWidth());
+                    }
+                }
+            log.debug("TextLayoutManager with minIPD:=" + minimumIPD);
+            }
+        }
+    }
+
     private KnuthSequence processLinebreak(List returnList, KnuthSequence sequence) {
         if (lineEndBAP != 0) {
             sequence.add(new KnuthGlue(lineEndBAP, 0, 0, auxiliaryPosition, true));
@@ -1464,6 +1496,16 @@
             + "\'"
             + ", len = " + foText.length()
             + "}";
+    }
+    
+    /**
+     * returns the minimum IPD (aka 'the longest box') required for the line.
+     * Must only be used for table with table-layout="auto".
+     * @return the longest KnuthBox encountered
+     */
+    public int getMinimumIPD() {
+        assert minimumIPD > -1;
+        return minimumIPD;
     }
 
 }
Index: src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java	(revision 1686091)
+++ src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java	(revision )
@@ -86,7 +86,7 @@
     private int halfBorderSeparationIPD;
 
     /** See {@link TableLayoutManager#registerColumnBackgroundArea(TableColumn, Block, int)}. */
-    private List columnBackgroundAreas;
+    private List<ColumnBackgroundInfo> columnBackgroundAreas;
 
     private Position auxiliaryPosition;
 
@@ -220,7 +220,7 @@
                         getTable().getUserAgent().getEventBroadcaster());
                 eventProducer.tableFixedAutoWidthNotSupported(this, getTable().getLocator());
             }
-            updateContentAreaIPDwithOverconstrainedAdjust();
+            updateContentAreaIPDwithOverconstrainedAdjust(context);
         }
         int sumOfColumns = columns.getSumOfColumnWidths(this);
         if (!autoLayout && sumOfColumns > getContentAreaIPD()) {
@@ -242,7 +242,7 @@
          * for proportional-column-width()
          */
         if (tableUnit == 0.0) {
-            this.tableUnit = columns.computeTableUnit(this);
+            this.tableUnit = columns.computeTableUnit(this, context);
         }
 
         if (!firstVisibleMarkServed) {
@@ -270,6 +270,24 @@
         childLC.setRefIPD(context.getRefIPD());
         childLC.copyPendingMarksFrom(context);
 
+        // width determination is required for any elements in auto-layout containers
+        if (isAutoLayout() || context.isChildOfAutoLayoutElement()) {
+        	childLC.setChildOfAutoLayoutElement(true);
+        	childLC.setInAutoLayoutDeterminationMode(true);
+            contentLM.determineAutoLayoutWidths(childLC, alignment);
+
+            // determination mode ends only if the parent is not still in this mode
+            if (!context.isInAutoLayoutDeterminationMode()) {
+            	childLC.setInAutoLayoutDeterminationMode(false);
+            }
+
+            int maxCol = columns.computeOptimalColumnWidthsForAutoLayout(this, context);
+            // report the determined maximum width to the enquiring parent
+            if (context.isChildOfAutoLayoutElement() && context.isInAutoLayoutDeterminationMode()) {
+                context.setRefIPD(maxCol);
+            }
+        }
+
         contentKnuthElements = contentLM.getNextKnuthElements(childLC, alignment);
         //Set index values on elements coming from the content LM
         Iterator iter = contentKnuthElements.iterator();
@@ -346,7 +364,7 @@
     void registerColumnBackgroundArea(TableColumn column, Block backgroundArea, int xShift) {
         addBackgroundArea(backgroundArea);
         if (columnBackgroundAreas == null) {
-            columnBackgroundAreas = new ArrayList();
+            columnBackgroundAreas = new ArrayList<ColumnBackgroundInfo>();
         }
         columnBackgroundAreas.add(new ColumnBackgroundInfo(column, backgroundArea, xShift));
     }
@@ -386,8 +404,7 @@
         curBlockArea.setBPD(tableHeight);
 
         if (columnBackgroundAreas != null) {
-            for (Iterator iter = columnBackgroundAreas.iterator(); iter.hasNext();) {
-                ColumnBackgroundInfo b = (ColumnBackgroundInfo) iter.next();
+            for (ColumnBackgroundInfo b : columnBackgroundAreas) {
                 TraitSetter.addBackground(b.backgroundArea,
                         b.column.getCommonBorderPaddingBackground(), this,
                         b.xShift, -b.backgroundArea.getYOffset(),
@@ -500,6 +517,116 @@
         return getTable().getKeepWithNext();
     }
 
+
+    /**
+     * Takes a {@link TableColumn} and looks up its {@link MinOptMax} width values.
+     * However, returns <code>null</code> for {@link TableColumn}s which have a static
+     * width value or any columns which do not have a {@link MinOptMax} object associated
+     * with them (i.e. columns which do not contain a {@link PrimaryGridUnit} but only
+     * {@link GridUnit}s which do not define a width themselves).
+     *
+     * @param tcol
+     * @param context
+     * @return {@link MinOptMax} or <code>null</code>
+     */
+    public MinOptMax getPossibleWidths(TableColumn tcol, LayoutContext context) {
+    	if (this.contentLM != null && (isAutoLayout() || context.isChildOfAutoLayoutElement())) {
+            if (tcol.isAutoLayout()) {
+                final MinOptMax length = this.contentLM.getBaseLength(tcol);
+                if (length != null) {
+                    return length;
+                }
+            } else {
+                // column uses a static value instead
+                return null;
+            }
+        }
+      /** we may end up here if the table contains cells with invalid columns-spanned attribute
+       * UPDATE: since there is no such thing as an invalid columns-spanned attribute (columns
+       * are simply dynamically added as required) this case cannot be considered to be an error
+       * anymore - simply return null and let the caller take care of this case. */
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    final boolean isAutoLayout() {
+        return getTable().isAutoLayout();
+    }
+
+    /** {@inheritDoc}<br>Determination is based on the type of layout used for the table. */
+    public int getMinimumIPD() {
+        int minimumIPD = -1;
+        int curMinIPD = 0;
+        if (contentLM != null) {
+            if (this.isAutoLayout()) {
+                curMinIPD = getMinimumIPDforAutoLayout();
+            } else {
+                curMinIPD = getMinimumIPDforFixedLayout();
+            }
+            // TODO: add Indents/Paddings/...
+            minimumIPD = Math.max(minimumIPD, curMinIPD);
+        }
+        return minimumIPD;
+    }
+
+    /**
+     * obtains the width of the widest column and returns this width times the number of columns
+     * @return width of widest columns times number of columns
+     */
+    private int getMinimumIPDforFixedLayout() {
+        int staticWidth = 0;
+        int widestMinWidthForAutoColumns = 0;
+        int curMinIPD = 0;
+        int autoColumns = 0;
+        for (Iterator<TableColumn> iter = columns.iterator(); iter.hasNext(); ) {
+            TableColumn tcol = iter.next();
+
+            if (!tcol.isAutoLayout()) {
+                // a static column should always requires the same amount of space
+                staticWidth += tcol.getColumnWidth().getValue(this);
+            } else {
+                MinOptMax width = contentLM.getBaseLength(tcol);
+                if (width != null) {
+                    widestMinWidthForAutoColumns = Math.max(widestMinWidthForAutoColumns, width.getMin());
+                }
+                autoColumns++;
+            }
+        }
+        return widestMinWidthForAutoColumns * autoColumns + staticWidth;
+    }
+
+    /**
+     * obtains the width of each individual column and returns the sum of these widths
+     * @return sum of the width of all columns
+     */
+    private int getMinimumIPDforAutoLayout() {
+        int curMinIPD = 0;
+        for (Iterator<TableColumn> iter = columns.iterator(); iter.hasNext(); ) {
+            TableColumn tcol = iter.next();
+            MinOptMax width = contentLM.getBaseLength(tcol);
+            if (width != null) {
+                curMinIPD += width.getMin();
+            }
+        }
+        return curMinIPD;
+    }
+
+    /**
+     * Used only for auto layout tables.
+     * Forwards the new width values ({@link MinOptMax} widths)
+     * of a column to the appropriate {@link TableContentLayoutManager}.
+     * @param tcol {@link TableColumn} which acts as key to get/set the width
+     * @param mom {@link MinOptMax} containing the appropriate values for the column
+     */
+    public void setPossibleWidths(TableColumn tcol, MinOptMax mom) {
+        assert this.contentLM != null;
+        //assert isAutoLayout();
+        if (tcol.isAutoLayout()) {
+            this.contentLM.setBaseLength(tcol, mom);
+        }
+    }
+
+
     // --------- Property Resolution related functions --------- //
 
     /**
@@ -512,6 +639,12 @@
             case LengthBase.CONTAINING_BLOCK_WIDTH:
                 return getContentAreaIPD();
             case LengthBase.TABLE_UNITS:
+                if (this.contentLM != null && isAutoLayout()) {
+                    if (((TableColumn) fobj).isAutoLayout()) {
+                        final MinOptMax length = this.contentLM.getBaseLength(fobj);
+                        return length == null ? 0 : length.getOpt();
+                    }
+                }
                 return (int) this.tableUnit;
             default:
                 log.error("Unknown base type for LengthBase.");
Index: src/java/org/apache/fop/layoutmgr/inline/ExternalGraphicLayoutManager.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/apache/fop/layoutmgr/inline/ExternalGraphicLayoutManager.java	(revision 1686091)
+++ src/java/org/apache/fop/layoutmgr/inline/ExternalGraphicLayoutManager.java	(revision )
@@ -21,6 +21,7 @@
 
 import org.apache.fop.area.Area;
 import org.apache.fop.area.inline.Image;
+import org.apache.fop.area.inline.InlineViewport;
 import org.apache.fop.fo.flow.ExternalGraphic;
 
 
@@ -43,6 +44,17 @@
     /** {@inheritDoc} */
     protected Area getChildArea() {
         return new Image(((ExternalGraphic) fobj).getSrc());
+    }
+    
+    /** {@inheritDoc}<br>TODO: currently only defined for one specific type of image. */
+    public int getMinimumIPD() {
+        if (curArea instanceof InlineViewport) {
+            InlineViewport iVP = (InlineViewport) curArea;
+            return (int) iVP.getContentPosition().getWidth();
+        } else {
+            log.warn("this type does not provide its dimensions, yet.");
+            return 0;
+        }
     }
 
 }
Index: src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java	(revision 1686091)
+++ src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java	(revision )
@@ -94,11 +94,8 @@
     private void createElementsForRowGroup(LayoutContext context, int alignment,
             int bodyType, LinkedList returnList) {
         log.debug("Handling row group with " + rowGroup.length + " rows...");
-        EffRow row;
-        for (int rgi = 0; rgi < rowGroup.length; rgi++) {
-            row = rowGroup[rgi];
-            for (Iterator iter = row.getGridUnits().iterator(); iter.hasNext();) {
-                GridUnit gu = (GridUnit) iter.next();
+        for (EffRow row : rowGroup) {
+            for (GridUnit gu : row.getGridUnits()) {
                 if (gu.isPrimary()) {
                     PrimaryGridUnit primary = gu.getPrimary();
                     // TODO a new LM must be created for every new static-content
@@ -112,13 +109,13 @@
                         spanWidth += ((TableColumn) colIter.next()).getColumnWidth().getValue(
                                 tableLM);
                     }
-                    LayoutContext childLC = LayoutContext.newInstance();
+                    LayoutContext childLC = LayoutContext.offspringOf(context);
                     childLC.setStackLimitBP(context.getStackLimitBP()); //necessary?
                     childLC.setRefIPD(spanWidth);
 
                     //Get the element list for the cell contents
                     List elems = primary.getCellLM().getNextKnuthElements(
-                                            childLC, alignment);
+                            childLC, alignment);
                     ElementListObserver.observe(elems, "table-cell", primary.getCell().getId());
                     primary.setElements(elems);
                 }
@@ -155,8 +152,7 @@
                 rowHeights[rgi] = rowBPD.toMinOptMax(tableLM);
                 explicitRowHeight = rowBPD.toMinOptMax(tableLM);
             }
-            for (Iterator iter = row.getGridUnits().iterator(); iter.hasNext();) {
-                GridUnit gu = (GridUnit) iter.next();
+            for (GridUnit gu : row.getGridUnits()) {
                 if (!gu.isEmpty() && gu.getColSpanIndex() == 0 && gu.isLastGridUnitRowSpan()) {
                     PrimaryGridUnit primary = gu.getPrimary();
                     int effectiveCellBPD = 0;
Index: src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java	(revision 1686091)
+++ src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java	(revision )
@@ -22,6 +22,7 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.ListIterator;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -165,6 +166,36 @@
         return startIndent + endIndent;
     }
 
+    /** {@inheritDoc}<br>Also adds any indents required by the tablecell */
+    public int getMinimumIPD() {
+        int minimumIPD = -1;
+        ListIterator iterLM = getChildLMs().listIterator();
+        while (iterLM.hasNext()) {
+            LayoutManager childLM = (LayoutManager)iterLM.next();
+            int curMinIPD = childLM.getMinimumIPD();
+            minimumIPD = Math.max(minimumIPD, curMinIPD);
+        }
+        minimumIPD += getIPIndents();
+        return minimumIPD;
+    }
+
+    final int getRefIPD() {
+        return this.referenceIPD;
+    }
+
+    /** {@inheritDoc} */
+    final boolean isAutoLayout() {
+        final Table table = getTable();
+
+        if (table.isAutoLayout()) {
+            final int index = this.primaryGridUnit.getColIndex();
+            final TableColumn column = table.getColumn(index);
+            return column.isAutoLayout();
+        }
+
+        return false;
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -182,13 +213,22 @@
         LayoutManager curLM; // currently active LM
         LayoutManager prevLM = null; // previously active LM
         while ((curLM = getChildLM()) != null) {
-            LayoutContext childLC = LayoutContext.newInstance();
+            LayoutContext childLC = LayoutContext.offspringOf(context);
             // curLM is a ?
             childLC.setStackLimitBP(context.getStackLimitBP().minus(stackLimit));
             childLC.setRefIPD(cellIPD);
 
             // get elements from curLM
             returnedList = curLM.getNextKnuthElements(childLC, alignment);
+
+            final int ipd = childLC.getRefIPD() + getIPIndents();
+
+            if (this.referenceIPD < ipd && (isAutoLayout() || context.isChildOfAutoLayoutElement())) {
+                this.referenceIPD = ipd;
+                this.cellIPD = getRefIPD() - getIPIndents();
+                context.setRefIPD(ipd);
+            }
+
             if (childLC.isKeepWithNextPending()) {
                 log.debug("child LM signals pending keep with next");
             }
@@ -443,7 +483,7 @@
                 adjustYOffset(curBlockArea, borderBeforeWidth);
                 Block[][] blocks = new Block[getTableCell().getNumberRowsSpanned()][getTableCell()
                         .getNumberColumnsSpanned()];
-                GridUnit[] gridUnits = (GridUnit[]) primaryGridUnit.getRows().get(startRow);
+                GridUnit[] gridUnits = primaryGridUnit.getRows().get(startRow);
                 int level = getTableCell().getBidiLevelRecursive();
                 for (int x = 0; x < getTableCell().getNumberColumnsSpanned(); x++) {
                     GridUnit gu = gridUnits[x];
@@ -456,7 +496,7 @@
                         adjustBPD(blocks[startRow][x], -borderWidth);
                     }
                 }
-                gridUnits = (GridUnit[]) primaryGridUnit.getRows().get(endRow);
+                gridUnits = primaryGridUnit.getRows().get(endRow);
                 for (int x = 0; x < getTableCell().getNumberColumnsSpanned(); x++) {
                     GridUnit gu = gridUnits[x];
                     BorderInfo border = gu.getBorderAfter(borderAfterWhich);
@@ -468,7 +508,7 @@
                     }
                 }
                 for (int y = startRow; y <= endRow; y++) {
-                    gridUnits = (GridUnit[]) primaryGridUnit.getRows().get(y);
+                    gridUnits = primaryGridUnit.getRows().get(y);
                     BorderInfo border = gridUnits[0].getBorderStart();
                     int borderWidth = border.getRetainedWidth() / 2;
                     if (borderWidth > 0) {
Index: src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java	(revision 1686091)
+++ src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java	(revision )
@@ -19,6 +19,7 @@
 
 package org.apache.fop.layoutmgr.table;
 
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
@@ -33,7 +34,10 @@
 import org.apache.fop.fo.flow.table.Table;
 import org.apache.fop.fo.flow.table.TableColumn;
 import org.apache.fop.fo.properties.TableColLength;
+import org.apache.fop.layoutmgr.BlockLevelEventProducer;
+import org.apache.fop.layoutmgr.LayoutContext;
 import org.apache.fop.traits.Direction;
+import org.apache.fop.traits.MinOptMax;
 import org.apache.fop.traits.WritingModeTraits;
 import org.apache.fop.traits.WritingModeTraitsGetter;
 
@@ -47,8 +51,8 @@
 
     private Table table;
     private WritingModeTraitsGetter wmTraits;
-    private List columns = new java.util.ArrayList();
-    private List colWidths = new java.util.ArrayList();
+    private List<TableColumn> columns = new java.util.ArrayList<TableColumn>();
+    private List<Length> colWidths = new java.util.ArrayList<Length>();
 
     private int maxColIndexReferenced;
 
@@ -86,9 +90,9 @@
             //Post-processing the list (looking for gaps)
             //TODO The following block could possibly be removed
             int pos = 1;
-            ListIterator ppIter = columns.listIterator();
+            ListIterator<TableColumn> ppIter = columns.listIterator();
             while (ppIter.hasNext()) {
-                TableColumn col = (TableColumn)ppIter.next();
+                TableColumn col = ppIter.next();
                 if (col == null) {
                     assert false; //Gaps are filled earlier by fo.flow.table.Table.finalizeColumns()
                     //log.error("Found a gap in the table-columns at position " + pos);
@@ -125,9 +129,9 @@
                     }
                 }
             }
-            return (TableColumn) columns.get(size - 1);
+            return columns.get(size - 1);
         } else {
-            return (TableColumn) columns.get(index - 1);
+            return columns.get(index - 1);
         }
     }
 
@@ -146,7 +150,7 @@
    }
 
     /** @return an Iterator over all columns */
-    public Iterator iterator() {
+    public Iterator<TableColumn> iterator() {
         return this.columns.iterator();
     }
 
@@ -174,7 +178,7 @@
 
         for (int i = columns.size(); --i >= 0;) {
             if (columns.get(i) != null) {
-                col = (TableColumn) columns.get(i);
+                col = columns.get(i);
                 colWidth = col.getColumnWidth();
                 colWidths.add(0, colWidth);
             }
@@ -187,10 +191,11 @@
      * [p-c-w(x) = x * base_unit_ipd]
      *
      * @param tlm   the TableLayoutManager
+     * @param context
      * @return the computed base unit (in millipoint)
      */
-    protected double computeTableUnit(TableLayoutManager tlm) {
-        return computeTableUnit(tlm, tlm.getContentAreaIPD());
+    protected double computeTableUnit(TableLayoutManager tlm, LayoutContext context) {
+        return computeTableUnit(tlm, tlm.getContentAreaIPD(), context);
     }
 
     /**
@@ -199,9 +204,10 @@
      *
      * @param percentBaseContext the percent base context for relative values
      * @param contentAreaIPD the IPD of the available content area
+     * @param context
      * @return the computed base unit (in millipoints)
      */
-    public float computeTableUnit(PercentBaseContext percentBaseContext, int contentAreaIPD) {
+    public float computeTableUnit(PercentBaseContext percentBaseContext, int contentAreaIPD, LayoutContext context) {
 
         int sumCols = 0;
         float factors = 0;
@@ -211,8 +217,7 @@
          * and work out the total number of factors to use to distribute
          * the remaining space (if any)
          */
-        for (Iterator i = colWidths.iterator(); i.hasNext();) {
-            Length colWidth = (Length) i.next();
+        for (Length colWidth : colWidths) {
             if (colWidth != null) {
                 sumCols += colWidth.getValue(percentBaseContext);
                 if (colWidth instanceof RelativeNumericProperty) {
@@ -230,6 +235,13 @@
             if (sumCols < contentAreaIPD) {
                 unit = (contentAreaIPD - sumCols) / factors;
             } else {
+                // this warning occurs during the pre-processing (AutoLayoutDeterminationMode)
+                // and can be ignored in these cases.
+                if (percentBaseContext instanceof TableLayoutManager) {
+                    if (context.isInAutoLayoutDeterminationMode()) {
+                        return unit;
+                    }
+                }
                 log.warn("No space remaining to distribute over columns.");
             }
         }
@@ -266,9 +278,8 @@
     private int getXOffsetRTL(int col, int nrColSpan, PercentBaseContext context) {
         int xoffset = 0;
         for (int i = (col + nrColSpan - 1), nc = colWidths.size(); ++i < nc;) {
-            int effCol = i;
-            if (colWidths.get(effCol) != null) {
-                xoffset += ((Length) colWidths.get(effCol)).getValue(context);
+            if (colWidths.get(i) != null) {
+                xoffset += colWidths.get(i).getValue(context);
             }
         }
         return xoffset;
@@ -289,7 +300,7 @@
                 effCol = colWidths.size() - 1;
             }
             if (colWidths.get(effCol) != null) {
-                xoffset += ((Length) colWidths.get(effCol)).getValue(context);
+                xoffset += colWidths.get(effCol).getValue(context);
             }
         }
         return xoffset;
@@ -308,10 +319,182 @@
                 effIndex = colWidths.size() - 1;
             }
             if (colWidths.get(effIndex) != null) {
-                sum += ((Length) colWidths.get(effIndex)).getValue(context);
+                sum += colWidths.get(effIndex).getValue(context);
             }
         }
         return sum;
+    }
+
+    /**
+     * Computes for each of the table's columns the optimal width and adjusts each column if necessary.
+     * This method relies on the fact, that a column's OPT value is initialized equal to its MAX value.
+     *
+     * @param tLM   the TableLayoutManager
+     *
+     * @return int maximum width to be propagated to containing layout manager or -1
+     */
+    public int computeOptimalColumnWidthsForAutoLayout(TableLayoutManager tLM, LayoutContext context) {
+        int maxSumCols = 0; // collects OPT values of the individual columns
+        int minSumCols = 0;
+        int contentAreaIPD = tLM.getContentAreaIPD();
+
+        for (TableColumn tcol : columns) {
+            if (tcol != null) {
+                if (tcol.isAutoLayout()) {
+                    MinOptMax possibleWidth = tLM.getPossibleWidths(tcol, context);
+                    if (possibleWidth == null) {
+                        // this column does not have a PrimaryGridUnit by itself
+                        // Just assume that no space is required for such an 'empty' column
+                        // TODO: validate this assumption (looks good after rendering it!)
+                    } else {
+                        maxSumCols += possibleWidth.getOpt();
+                        minSumCols += possibleWidth.getMin();
+                    }
+                } else {
+                    int staticWidth = tcol.getColumnWidth().getValue(tLM);
+                    maxSumCols += staticWidth;
+                    minSumCols += staticWidth;
+                }
+            }
+        }
+
+        /*
+         * distribute the remaining space over the accumulated factors (if any)
+         */
+        // TODO: DO NOT DO THIS IN CASE WE ARE IN AN AUTOMATIC LAYOUT PARENT WHICH NEEDS
+        // AUTHENTIC MIN/MAX VALUES TO DETERMINE ITS OWN WIDTH REQUIREMENTS
+        if (context.isChildOfAutoLayoutElement() && context.isInAutoLayoutDeterminationMode()) {
+            return maxSumCols;
+        } else {
+            if (maxSumCols >  contentAreaIPD) {
+                if (minSumCols < contentAreaIPD) {
+                    // redistribute by setting OPT values
+                    if (log.isDebugEnabled()) {
+                        log.debug("Sum (" + maxSumCols + ") > Available Area (" + contentAreaIPD + "): Redistributing");
+                    }
+
+                    // create a second list from which we can remove individual items after we are done with them
+                    List<TableColumn> columnsToProcess = new ArrayList<TableColumn>();
+                    columnsToProcess.addAll(columns);
+                    redistribute(tLM, contentAreaIPD, maxSumCols, columnsToProcess, context);
+                } else {
+                    // set all OPTs to the respective MINIMUM of each column
+                    if (minSumCols != contentAreaIPD) {
+                        // communicate this case as a warning to the user
+                        Table table = tLM.getTable();
+                        BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get(
+                                table.getUserAgent().getEventBroadcaster());
+                        eventProducer.columnsInAutoTableTooWide(this, minSumCols,
+                                contentAreaIPD, table.getLocator());
+                    }
+                    for (TableColumn tcol : columns) {
+                        if (tcol.isAutoLayout()) {
+                            MinOptMax possibleWidth = tLM.getPossibleWidths(tcol, context);
+                            if (possibleWidth == null) {
+                                // ignore columns which do not contain PGUs -> their width is zero
+                            } else {
+                                int min = possibleWidth.getMin();
+                                int max = possibleWidth.getMax();
+                                MinOptMax minWidth = MinOptMax.getInstance(min, min, max);
+                                tLM.setPossibleWidths(tcol, minWidth);
+                            }
+                        } else {
+                            // DO NOT CHANGE THE OPT-VALUE OF A COLUMN WITH STATIC WIDTH - IT IS
+                            // ALREADY THE STATIC VALUE WE MUST USE (AS DEFINED IN THE FO-FILE)
+                        }
+                    }
+                }
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * This method redistributes the remaining width of the table recursively.
+     * At first, all static columns are excluded (i.e., the redistribution is invoked
+     * for all but these columns), since we cannot shrink them.
+     * Afterwards, we try to proportionally shrink each remaining column by a factor of
+     *     factor = remainingArea / sum of max width of remaining columns
+     * After applying this factor to a column's MAX width, we check if the result is less
+     * than the column's minimal width - if so, this minimal width is used instead and we
+     * invoke the method again with
+     * <ul>
+     *  <li> the remaining columns without the column we just changed</li>
+     *  <li> the remaining area - the minimal width of the column we just changed</li>
+     *  <li> an updated factor (based on the remaining area and the remaining columns)</li>
+     * </ul>
+     * @param tLM the TableLayoutManager which is used to store the dimensions of all columns
+     * @param remainingArea the remaining width which we may still distribute among the columnsToProcess
+     * @param columnsToProcess
+     * @param context
+     * @return boolean The return value indicates whether the layout changed due to the redistribution.
+     */
+    private boolean redistribute(TableLayoutManager tLM, int remainingArea, int maxSumCols, List<TableColumn> columnsToProcess, LayoutContext context) {
+        double factor = (double) remainingArea / maxSumCols;
+
+        // step 1: check if applying the current factor leads to a value below the minimum of a column
+        for (TableColumn tcol :  columnsToProcess) {
+            // ignore columns which have a static width since we must use their assigned value
+            // ignoring them = excluding them from the columns we want to shrink
+            if (!tcol.isAutoLayout()) {
+                int staticWidth = tcol.getColumnWidth().getValue(tLM);
+                remainingArea -= staticWidth;
+                maxSumCols -= staticWidth;
+                columnsToProcess.remove(tcol);
+                if (log.isDebugEnabled()) {
+                    log.debug("| Col " + tcol.getColumnNumber() + " -> STATIC(" + staticWidth + ") |");
+                }
+                return redistribute(tLM, remainingArea, maxSumCols, columnsToProcess, context);
+            } else {
+                MinOptMax possibleWidth = tLM.getPossibleWidths(tcol, context);
+                if (possibleWidth == null) {
+                    // no PrimaryGridUnits in this column
+                    columnsToProcess.remove(tcol);
+                    if (log.isDebugEnabled()) {
+                        log.debug("| Col " + tcol.getColumnNumber() + " -> EMPTY (0) |");
+                    }
+                    return redistribute(tLM, remainingArea, maxSumCols, columnsToProcess, context);
+                }
+                int max = possibleWidth.getMax();
+                int min = possibleWidth.getMin();
+
+                if ((max * factor) < min) {
+                    // for this column: opt = min
+                    MinOptMax newWidths = MinOptMax.getInstance(min, min, max);
+                    tLM.setPossibleWidths(tcol, newWidths);
+                    // remove this column from the list, decrease the remaining area (-min), and recalculate the factor
+                    remainingArea -= min;
+                    maxSumCols -= max;
+                    // continue with all other columns which may still be shrinked
+                    columnsToProcess.remove(tcol);
+                    if (log.isDebugEnabled()) {
+                        log.debug("| Col " + tcol.getColumnNumber() + " -> MIN(" + min + ") |");
+                    }
+                    return redistribute(tLM, remainingArea, maxSumCols, columnsToProcess, context);
+                } else {
+                    // current column could be shrunk using the current factor
+                    // however, subsequent columns might not be -> wait until such columns are sorted out
+                }
+            }
+        }
+
+        // step 2: now we know that all remaining columns can be shrunk by the factor
+        for (TableColumn tcol :  columnsToProcess) {
+            MinOptMax possibleWidth = tLM.getPossibleWidths(tcol, context);
+            int max = possibleWidth.getMax();
+            int min = possibleWidth.getMin();
+            int newOpt = (int) (max * factor);
+            if (log.isDebugEnabled()) {
+                log.debug("| Col " + tcol.getColumnNumber() + " -> OPT(" + newOpt + ") |");
+            }
+            MinOptMax newWidths = MinOptMax.getInstance(min, newOpt, max);
+            // ASSIGN to column
+            tLM.setPossibleWidths(tcol, newWidths);
+        }
+        if (log.isDebugEnabled()) {
+            log.debug("Redistribution finished");
+        }
+        return true;
     }
 
 }
Index: src/java/org/apache/fop/render/rtf/RTFHandler.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/apache/fop/render/rtf/RTFHandler.java	(revision 1686091)
+++ src/java/org/apache/fop/render/rtf/RTFHandler.java	(revision )
@@ -1526,7 +1526,7 @@
         ColumnSetup columnSetup = new ColumnSetup(tab);
         //int sumOfColumns = columnSetup.getSumOfColumnWidths(percentManager);
         float tableWidth = percentManager.getBaseLength(LengthBase.CONTAINING_BLOCK_WIDTH, tab);
-        float tableUnit = columnSetup.computeTableUnit(percentManager, Math.round(tableWidth));
+        float tableUnit = columnSetup.computeTableUnit(percentManager, Math.round(tableWidth), null);
         percentManager.setTableUnit(tab, Math.round(tableUnit));
 
     }
Index: test/layoutengine/standard-testcases/table-layout_auto_spanned-columns_1.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- test/layoutengine/standard-testcases/table-layout_auto_spanned-columns_1.xml	(revision )
+++ test/layoutengine/standard-testcases/table-layout_auto_spanned-columns_1.xml	(revision )
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You 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.
+-->
+<!-- $Id$ -->
+<testcase>
+  <info>
+    <p>
+    </p>
+  </info>
+  <fo>
+    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+      <fo:layout-master-set>
+        <fo:simple-page-master master-name="first"
+                              page-height="29.7cm"
+                              page-width="21cm"
+                              margin-top="1cm"
+                              margin-bottom="2cm"
+                              margin-left="2.5cm"
+                              margin-right="2.5cm">
+          <fo:region-body margin-top="3cm"/>
+          <fo:region-before extent="3cm"/>
+          <fo:region-after extent="1.5cm"/>
+        </fo:simple-page-master>
+      </fo:layout-master-set>
+      
+      <fo:page-sequence master-reference="first">
+        
+        <fo:flow flow-name="xsl-region-body">
+          <fo:block>
+            In this table, cell E spans over columns 2 and 3, but requires more width than these two provide.
+            Therefore, both columns are widened proportionally so that the required width can be provided.
+          </fo:block>
+          
+          <fo:table table-layout="auto" width="100%" border-collapse="separate">
+            <fo:table-body>
+              
+              <fo:table-row>
+                <fo:table-cell padding="2pt" number-rows-spanned="1" border-right="0.5pt dotted black" border="0.5pt dotted black">
+                <fo:block>A</fo:block>
+                </fo:table-cell>
+                <fo:table-cell padding="2pt" number-rows-spanned="1" border-right="0.5pt dotted black" border="0.5pt dotted black">
+                  <fo:block>B</fo:block>
+                </fo:table-cell>
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black" border="0.5pt dotted black">
+                  <fo:block>C</fo:block>
+                </fo:table-cell>
+                            
+              </fo:table-row>
+              
+              <fo:table-row>
+                <fo:table-cell padding="2pt" number-rows-spanned="1" border-right="0.5pt dotted black" border="0.5pt dotted black">
+                <fo:block>D</fo:block>
+                </fo:table-cell>
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black" border="0.5pt dotted black" number-columns-spanned="2">
+                  <fo:block>This cell needs more width than width('B') + width('C')</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+            </fo:table-body>
+          </fo:table>          
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <!-- TODO -->
+  </checks>
+</testcase>
Index: test/layoutengine/standard-testcases/table-layout_auto_nested_1.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- test/layoutengine/standard-testcases/table-layout_auto_nested_1.xml	(revision )
+++ test/layoutengine/standard-testcases/table-layout_auto_nested_1.xml	(revision )
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You 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.
+-->
+<!-- $Id$ -->
+<testcase>
+  <info>
+    <p>
+    </p>
+  </info>
+  <fo>
+    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+      <fo:layout-master-set>
+        <fo:simple-page-master master-name="first"
+                              page-height="29.7cm"
+                              page-width="21cm"
+                              margin-top="1cm"
+                              margin-bottom="2cm"
+                              margin-left="2.5cm"
+                              margin-right="2.5cm">
+          <fo:region-body margin-top="3cm"/>
+          <fo:region-before extent="3cm"/>
+          <fo:region-after extent="1.5cm"/>
+        </fo:simple-page-master>
+      </fo:layout-master-set>
+      
+      <fo:page-sequence master-reference="first">
+        
+        <fo:flow flow-name="xsl-region-body">
+          <fo:table border="0.5pt solid black"
+                    border-spacing="3pt"
+                    width="100%"
+                    inline-progression-dimension="100%"
+                    id="outer-one">
+            <fo:table-body>
+              <fo:table-row background-color="#ffffff">
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black">
+                  <fo:block>A: layout="auto" and a lot of additional text to enforce a linebreak</fo:block>
+                </fo:table-cell>
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black">
+                  <fo:block>B with fixed table</fo:block>
+                  <fo:block>
+                    <fo:table border="0.5pt solid black" border-spacing="3pt" width="100%"
+                               inline-progression-dimension="100%" table-layout="fixed"
+                               id="inner-one">
+                      <fo:table-body>
+                        <fo:table-row background-color="#ffffff">
+                          <fo:table-cell padding="2pt" border-right="0.5pt dotted black">
+                            <fo:block>B1: layout="fixed" AndNoCutoff 1234567890123456789</fo:block>
+                          </fo:table-cell>
+                          <fo:table-cell padding="2pt">
+                            <fo:block>B2</fo:block>
+                          </fo:table-cell>
+                        </fo:table-row>
+                        <fo:table-row background-color="#f0f0f0">
+                          <fo:table-cell padding="2pt" border-right="0.5pt dotted black">
+                            <fo:block>B3</fo:block>
+                          </fo:table-cell>
+                          <fo:table-cell padding="2pt">
+                            <fo:block>
+                              B4 with auto table
+                              <fo:table border="0.5pt solid black" border-spacing="3pt" width="100%"
+                                        inline-progression-dimension="100%"
+                                        id="inner-two">
+                                <fo:table-body>
+                                  <fo:table-row background-color="#ffffff">
+                                    <fo:table-cell padding="2pt" border-right="0.5pt dotted black">
+                                      <fo:block>B4A: layout="auto"</fo:block>
+                                    </fo:table-cell>
+                                    <fo:table-cell padding="2pt">
+                                      <fo:block>B4B</fo:block>
+                                    </fo:table-cell>
+                                  </fo:table-row>
+                                  <fo:table-row background-color="#f0f0f0">
+                                    <fo:table-cell padding="2pt" border-right="0.5pt dotted black">
+                                      <fo:block>B4C with more text</fo:block>
+                                    </fo:table-cell>
+                                    <fo:table-cell padding="2pt">
+                                      <fo:block>B4D only</fo:block>
+                                    </fo:table-cell>
+                                  </fo:table-row>
+                                </fo:table-body>
+                              </fo:table>
+                            </fo:block>
+                          </fo:table-cell>
+                        </fo:table-row>
+                      </fo:table-body>
+                    </fo:table>
+                  </fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+              <fo:table-row background-color="#f0f0f0">
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black">
+                  <fo:block>C</fo:block>
+                </fo:table-cell>
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black">
+                  <fo:block>D</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+            </fo:table-body>
+          </fo:table>          
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <!-- TODO -->
+  </checks>
+</testcase>
Index: test/layoutengine/standard-testcases/table-layout_auto_static-columns_1.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- test/layoutengine/standard-testcases/table-layout_auto_static-columns_1.xml	(revision )
+++ test/layoutengine/standard-testcases/table-layout_auto_static-columns_1.xml	(revision )
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You 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.
+-->
+<!-- $Id$ -->
+<testcase>
+  <info>
+    <p>
+    </p>
+  </info>
+  <fo>
+    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+      <fo:layout-master-set>
+        <fo:simple-page-master master-name="first"
+                              page-height="29.7cm"
+                              page-width="21cm"
+                              margin-top="1cm"
+                              margin-bottom="2cm"
+                              margin-left="2.5cm"
+                              margin-right="2.5cm">
+          <fo:region-body margin-top="3cm"/>
+          <fo:region-before extent="3cm"/>
+          <fo:region-after extent="1.5cm"/>
+        </fo:simple-page-master>
+      </fo:layout-master-set>
+      
+      <fo:page-sequence master-reference="first">
+        
+        <fo:flow flow-name="xsl-region-body">
+          <fo:block>Columns 2 and 4 have a static width of '1cm' and, thus, are not widened to fit the content of the col-spanning cell 'G' - only column 3 may be widened</fo:block>
+          <fo:table table-layout="auto" width="100%" border-collapse="separate">
+            <fo:table-column column-number="2" column-width="1cm"/>
+            <fo:table-column column-number="4" column-width="1cm"/>
+            <fo:table-column column-number="5" />
+            <fo:table-body>
+              
+              <fo:table-row>
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black" border="0.5pt dotted black">
+                <fo:block>A</fo:block>
+                </fo:table-cell>
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black" border="0.5pt dotted black">
+                  <fo:block>BB</fo:block>
+                </fo:table-cell>
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black" border="0.5pt dotted black">
+                  <fo:block>CC</fo:block>
+                </fo:table-cell>
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black" border="0.5pt dotted black">
+                  <fo:block>DD</fo:block>
+                </fo:table-cell>
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black" border="0.5pt dotted black">
+                  <fo:block>EEEEEEEEEEE EEEEEEEEEEEEEEEEEEEE EEEEEEEEEEEEEEEEEEEEEEEE EEEEEEEEEEEEE</fo:block>
+                </fo:table-cell>               
+              </fo:table-row>
+              
+              <fo:table-row>
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black" border="0.5pt dotted black">
+                <fo:block>F</fo:block>
+                </fo:table-cell>
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black" border="0.5pt dotted black" number-columns-spanned="3">
+                  <fo:block>GGGGGGGGGGGGGGGGGG</fo:block>
+                </fo:table-cell>
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black" border="0.5pt dotted black">
+                  <fo:block>H</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+            </fo:table-body>
+          </fo:table>          
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <!-- TODO -->
+  </checks>
+</testcase>
Index: src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java	(revision 1686091)
+++ src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java	(revision )
@@ -170,7 +170,7 @@
 
     private LineLayoutPossibilities lineLayouts;
     private LineLayoutPossibilities[] lineLayoutsList;
-    private int ipd;
+    private MinOptMax ipd = null;
     /**
      * When layout must be re-started due to a change of IPD, there is no need
      * to perform hyphenation on the remaining Knuth sequence once again.
@@ -228,10 +228,15 @@
             if (textAlignment == EN_CENTER) {
                 lineFiller = MinOptMax.getInstance(lastLineEndIndent);
             } else {
+                if (layoutManager.ipd.getOpt() < lastLineEndIndent) {
+                    lineFiller = MinOptMax.getInstance(lastLineEndIndent);
+                } else {
-                lineFiller = MinOptMax.getInstance(lastLineEndIndent, lastLineEndIndent,
+                    lineFiller = MinOptMax.getInstance(lastLineEndIndent, lastLineEndIndent,
-                        layoutManager.ipd);
+                        layoutManager.ipd.getOpt());
-            }
+                }
 
+            }
+
             // add auxiliary elements at the beginning of the paragraph
             if (textAlignment == EN_CENTER && textAlignmentLast != EN_JUSTIFY) {
                 this.add(new KnuthGlue(0, 3 * DEFAULT_SPACE_WIDTH, 0,
@@ -443,7 +448,7 @@
             // true if this line contains only zero-height, auxiliary boxes
             // and the actual line width is 0; in this case, the line "collapses"
             // i.e. the line area will have bpd = 0
-            boolean isZeroHeightLine = (difference == ipd);
+            boolean isZeroHeightLine = (difference == ipd.getOpt());
 
             // if line-stacking-strategy is "font-height", the line height
             // is not affected by its content
@@ -499,7 +504,7 @@
                                              firstElementIndex, lastElementIndex,
                                              availableShrink, availableStretch,
                                              difference, ratio, 0, startIndent, endIndent,
-                                             0, ipd, 0, 0, 0);
+                                             0, ipd.getOpt(), 0, 0, 0);
             } else {
                 return new LineBreakPosition(thisLLM,
                                              knuthParagraphs.indexOf(par),
@@ -507,7 +512,7 @@
                                              availableShrink, availableStretch,
                                              difference, ratio, 0, startIndent, endIndent,
                                              lineLead + lineFollow,
-                                             ipd, spaceBefore, spaceAfter,
+                                             ipd.getOpt(), spaceBefore, spaceAfter,
                                              lineLead);
             }
         }
@@ -618,7 +623,7 @@
                     context.getWritingMode());
         }
         context.setAlignmentContext(alignmentContext);
-        ipd = context.getRefIPD();
+        ipd = MinOptMax.getInstance(context.getRefIPD());
 
         //PHASE 1: Create Knuth elements
         if (knuthParagraphs == null) {
@@ -675,7 +680,7 @@
             return null;
         }
 
-        ipd = context.getRefIPD();
+        ipd = MinOptMax.getInstance(context.getRefIPD());
         //PHASE 2: Create line breaks
         return createLineBreaks(context.getBPAlignment(), context);
     }
@@ -695,6 +700,8 @@
 
         Paragraph lastPar = null;
 
+        int minimumIPD = 0;
+        int maxSumIPD = 0;
         InlineLevelLayoutManager curLM;
         while ((curLM = (InlineLevelLayoutManager) getChildLM()) != null) {
             List inlineElements = curLM.getNextKnuthElements(inlineLC, effectiveAlignment);
@@ -734,6 +741,22 @@
             ListIterator iter = inlineElements.listIterator();
             while (iter.hasNext()) {
                 KnuthSequence sequence = (KnuthSequence) iter.next();
+
+                // get to know the width of the contained elements
+                if (context.isInAutoLayoutDeterminationMode()) {
+                    final ListIterator i = sequence.listIterator();
+
+                    while (i.hasNext()) {
+                        final KnuthElement element = (KnuthElement) i.next();
+                        // retrieve minimum width for this lineLM along the way
+                        if (element instanceof KnuthBox) {
+                            // TODO: this is already calculated during the collection of the childLM's elements
+                            minimumIPD = Math.max(minimumIPD, element.getWidth());
+                        }
+                        maxSumIPD += element.getWidth();
+                    }
+//                    log.debug("Line with minIPD:=" + minimumIPD);
+                }
                 // the sequence contains inline Knuth elements
                 if (sequence.isInlineSequence()) {
                     // look at the last element
@@ -775,7 +798,7 @@
                         if (!lastPar.containsBox()) {
                             //only a forced linefeed on this line
                             //-> compensate with an auxiliary glue
-                            lastPar.add(new KnuthGlue(ipd, 0, ipd, null, true));
+                            lastPar.add(new KnuthGlue(ipd.getOpt(), 0, ipd.getOpt(), null, true));
                         }
                         lastPar.endParagraph();
                         ElementListObserver.observe(lastPar, "line", null);
@@ -802,6 +825,22 @@
                 trace.append(" ]");
             }
         }
+
+        /**
+         * at this point, localIPD represents the maximum value for how wide the line should be.
+         */
+        if (ipd.getMax() < maxSumIPD && context.isInAutoLayoutDeterminationMode()) {
+            ipd = MinOptMax.getInstance(minimumIPD, maxSumIPD, maxSumIPD);
+
+            final MinOptMax stackLimitBP = context.getStackLimitBP();
+            int max = stackLimitBP.getMax();
+            if (max < maxSumIPD) {
+                max = maxSumIPD;
+            }
+            MinOptMax newStackLimitBP = MinOptMax.getInstance(stackLimitBP.getMin(), maxSumIPD, max);
+            context.setStackLimitBP(newStackLimitBP);
+            context.setRefIPD(ipd.getOpt());
+        }
         log.trace(trace);
     }
 
@@ -855,7 +894,7 @@
                                         hyphenationLadderCount.getEnum() == EN_NO_LIMIT
                                             ? 0 : hyphenationLadderCount.getValue(),
                                         this);
-        alg.setConstantLineWidth(ipd);
+        alg.setConstantLineWidth(ipd.getOpt());
         boolean canWrap = (wrapOption != EN_NO_WRAP);
         boolean canHyphenate = (canWrap && hyphenationProperties.hyphenate.getEnum() == EN_TRUE);
 
@@ -1511,7 +1550,7 @@
             lineArea.addTrait(Trait.START_INDENT, lbp.startIndent);
         }
         if (lbp.endIndent != 0) {
-            lineArea.addTrait(Trait.END_INDENT, new Integer(lbp.endIndent));
+            lineArea.addTrait(Trait.END_INDENT, lbp.endIndent);
         }
         lineArea.setBPD(lbp.lineHeight);
         lineArea.setIPD(lbp.lineWidth);
Index: src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java	(revision 1686091)
+++ src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java	(revision )
@@ -37,6 +37,7 @@
 import org.apache.fop.fo.properties.KeepProperty;
 import org.apache.fop.fo.properties.SpaceProperty;
 import org.apache.fop.layoutmgr.inline.InlineContainerLayoutManager;
+import org.apache.fop.layoutmgr.inline.LineLayoutManager;
 import org.apache.fop.layoutmgr.inline.InlineLayoutManager;
 import org.apache.fop.traits.MinOptMax;
 import org.apache.fop.util.ListUtil;
@@ -195,10 +196,10 @@
      *
      * @return the resulting content area IPD
      */
-    protected int updateContentAreaIPDwithOverconstrainedAdjust() {
+    protected int updateContentAreaIPDwithOverconstrainedAdjust(LayoutContext context) {
         int ipd = referenceIPD - (startIndent + endIndent);
-        if (ipd < 0) {
-            //5.3.4, XSL 1.0, Overconstrained Geometry
+        if (ipd < 0 && !context.isChildOfAutoLayoutElement()) {
+            //5.3.4, XSL 1.1, Overconstrained Geometry
             log.debug("Adjusting end-indent based on overconstrained geometry rules for " + fobj);
             BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get(
                     getFObj().getUserAgent().getEventBroadcaster());
@@ -221,7 +222,7 @@
     protected int updateContentAreaIPDwithOverconstrainedAdjust(int contentIPD) {
         int ipd = referenceIPD - (contentIPD + (startIndent + endIndent));
         if (ipd < 0) {
-            //5.3.4, XSL 1.0, Overconstrained Geometry
+            //5.3.4, XSL 1.1, Overconstrained Geometry
             log.debug("Adjusting end-indent based on overconstrained geometry rules for " + fobj);
             BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get(
                     getFObj().getUserAgent().getEventBroadcaster());
@@ -243,8 +244,9 @@
     @Override
     public List getNextKnuthElements(LayoutContext context, int alignment,
             Stack lmStack, Position restartPosition, LayoutManager restartAtLM) {
+
         referenceIPD = context.getRefIPD();
-        updateContentAreaIPDwithOverconstrainedAdjust();
+        updateContentAreaIPDwithOverconstrainedAdjust(context);
 
         boolean isRestart = (lmStack != null);
         boolean emptyStack = (!isRestart || lmStack.isEmpty());
@@ -296,6 +298,17 @@
                 emptyStack = true;
             }
 
+            final int ipd = childLC.getRefIPD();
+            if (getContentAreaIPD() < ipd && context.isChildOfAutoLayoutElement()) {
+                if (currentChildLM instanceof LineLayoutManager) {
+                    referenceIPD = startIndent + ipd + endIndent;
+                } else {
+                    referenceIPD = ipd;
+                }
+                updateContentAreaIPDwithOverconstrainedAdjust(context);
+                context.setRefIPD(this.referenceIPD);
+            }
+
             if (contentList.isEmpty()) {
                 // propagate keep-with-previous up from the first child
                 context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending());
@@ -384,7 +397,7 @@
      * @return a new child layout context
      */
     protected LayoutContext makeChildLayoutContext(LayoutContext context) {
-        LayoutContext childLC = LayoutContext.newInstance();
+        LayoutContext childLC = LayoutContext.offspringOf(context);
         childLC.copyPendingMarksFrom(context);
         childLC.setStackLimitBP(context.getStackLimitBP());
         childLC.setRefIPD(referenceIPD);
Index: src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java	(revision 1686091)
+++ src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java	(revision )
@@ -137,18 +137,21 @@
             //Handled already by the parent (break collapsing, see above)
         }
 
+        List<ListElement> childElements;
+
         if (lmStack == null) {
-            return childLM.getNextKnuthElements(childLC, alignment);
+            childElements = childLM.getNextKnuthElements(childLC, alignment);
         } else {
             if (childLM instanceof LineLayoutManager) {
                 assert (restartPosition instanceof LeafPosition);
-                return ((LineLayoutManager) childLM).getNextKnuthElements(childLC, alignment,
+                childElements = ((LineLayoutManager) childLM).getNextKnuthElements(childLC, alignment,
                         (LeafPosition) restartPosition);
             } else {
-                return childLM.getNextKnuthElements(childLC, alignment,
+                childElements = childLM.getNextKnuthElements(childLC, alignment,
                         lmStack, restartPosition, restartAtLM);
             }
         }
+        return childElements;
     }
 
     private void resetSpaces() {
Index: src/java/org/apache/fop/fo/flow/table/EffRow.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/apache/fop/fo/flow/table/EffRow.java	(revision 1686091)
+++ src/java/org/apache/fop/fo/flow/table/EffRow.java	(revision )
@@ -39,7 +39,7 @@
     /** Indicates that the row is the last in a table-body */
     public static final int LAST_IN_PART = GridUnit.LAST_IN_PART;
 
-    private List gridUnits = new java.util.ArrayList();
+    private List<GridUnit> gridUnits = new java.util.ArrayList<GridUnit>();
     private int index;
     /** One of HEADER, FOOTER, BODY */
     private int bodyType;
@@ -57,8 +57,7 @@
         this.bodyType = bodyType;
         this.gridUnits = gridUnits;
         // TODO this is ugly, but we may eventually be able to do without that index
-        for (Iterator guIter = gridUnits.iterator(); guIter.hasNext();) {
-            Object gu = guIter.next();
+        for (GridUnit gu : this.gridUnits) {
             if (gu instanceof PrimaryGridUnit) {
                 ((PrimaryGridUnit) gu).setRowIndex(index);
             }
@@ -118,7 +117,7 @@
     }
 
     /** @return the list of GridUnits for this EffRow */
-    public List getGridUnits() {
+    public List<GridUnit> getGridUnits() {
         return gridUnits;
     }
 
@@ -128,7 +127,7 @@
      * @return the requested grid unit.
      */
     public GridUnit getGridUnit(int column) {
-        return (GridUnit)gridUnits.get(column);
+        return gridUnits.get(column);
     }
 
     /**
@@ -140,7 +139,7 @@
      */
     public GridUnit safelyGetGridUnit(int column) {
         if (column < gridUnits.size()) {
-            return (GridUnit)gridUnits.get(column);
+            return gridUnits.get(column);
         } else {
             return null;
         }
@@ -175,8 +174,7 @@
         if (row != null) {
             keep = Keep.getKeep(row.getKeepWithPrevious());
         }
-        for (Iterator iter = gridUnits.iterator(); iter.hasNext();) {
-            GridUnit gu = (GridUnit) iter.next();
+        for (GridUnit gu : gridUnits) {
             if (gu.isPrimary()) {
                 keep = keep.compare(gu.getPrimary().getKeepWithPrevious());
             }
@@ -196,8 +194,7 @@
         if (row != null) {
             keep = Keep.getKeep(row.getKeepWithNext());
         }
-        for (Iterator iter = gridUnits.iterator(); iter.hasNext();) {
-            GridUnit gu = (GridUnit) iter.next();
+        for (GridUnit gu : gridUnits) {
             if (!gu.isEmpty() && gu.getColSpanIndex() == 0 && gu.isLastGridUnitRowSpan()) {
                 keep = keep.compare(gu.getPrimary().getKeepWithNext());
             }
@@ -233,8 +230,7 @@
      */
     public int getBreakBefore() {
         int breakBefore = Constants.EN_AUTO;
-        for (Iterator iter = gridUnits.iterator(); iter.hasNext();) {
-            GridUnit gu = (GridUnit) iter.next();
+        for (GridUnit gu : gridUnits) {
             if (gu.isPrimary()) {
                 breakBefore = BreakUtil.compareBreakClasses(breakBefore,
                         gu.getPrimary().getBreakBefore());
@@ -257,8 +253,7 @@
      */
     public int getBreakAfter() {
         int breakAfter = Constants.EN_AUTO;
-        for (Iterator iter = gridUnits.iterator(); iter.hasNext();) {
-            GridUnit gu = (GridUnit) iter.next();
+        for (GridUnit gu : gridUnits) {
             if (!gu.isEmpty() && gu.getColSpanIndex() == 0 && gu.isLastGridUnitRowSpan()) {
                 breakAfter = BreakUtil.compareBreakClasses(breakAfter,
                         gu.getPrimary().getBreakAfter());
@@ -269,7 +264,7 @@
 
     /** {@inheritDoc} */
     public String toString() {
-        StringBuffer sb = new StringBuffer("EffRow {");
+        StringBuilder sb = new StringBuilder("EffRow {");
         sb.append(index);
         if (getBodyType() == TableRowIterator.BODY) {
             sb.append(" in body");
Index: src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java	(revision 1686091)
+++ src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java	(revision )
@@ -341,7 +341,7 @@
 
         referenceIPD = context.getRefIPD();
         if (width.getEnum() == EN_AUTO) {
-            updateContentAreaIPDwithOverconstrainedAdjust();
+            updateContentAreaIPDwithOverconstrainedAdjust(context);
         } else {
             int contentWidth = width.getValue(this);
             updateContentAreaIPDwithOverconstrainedAdjust(contentWidth);
Index: src/java/org/apache/fop/fo/flow/table/TableColumn.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/apache/fop/fo/flow/table/TableColumn.java	(revision 1686091)
+++ src/java/org/apache/fop/fo/flow/table/TableColumn.java	(revision )
@@ -275,4 +275,7 @@
         return isHeader;
     }
 
+    public final boolean isAutoLayout() {
+        return getColumnWidth() instanceof TableColLength;
+    }
 }
Index: src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java	(revision 1686091)
+++ src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java	(revision )
@@ -19,6 +19,8 @@
 
 package org.apache.fop.layoutmgr.table;
 
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
@@ -33,9 +35,11 @@
 import org.apache.fop.fo.FObj;
 import org.apache.fop.fo.flow.Marker;
 import org.apache.fop.fo.flow.table.EffRow;
+import org.apache.fop.fo.flow.table.GridUnit;
 import org.apache.fop.fo.flow.table.PrimaryGridUnit;
 import org.apache.fop.fo.flow.table.Table;
 import org.apache.fop.fo.flow.table.TableBody;
+import org.apache.fop.fo.flow.table.TableColumn;
 import org.apache.fop.fo.flow.table.TablePart;
 import org.apache.fop.layoutmgr.BreakElement;
 import org.apache.fop.layoutmgr.ElementListUtils;
@@ -53,6 +57,7 @@
 import org.apache.fop.layoutmgr.Position;
 import org.apache.fop.layoutmgr.PositionIterator;
 import org.apache.fop.layoutmgr.SpaceResolver.SpaceHandlingBreakPosition;
+import org.apache.fop.traits.MinOptMax;
 import org.apache.fop.util.BreakUtil;
 
 /**
@@ -77,6 +82,8 @@
 
     private TableStepper stepper;
 
+    private final Map<TableColumn, MinOptMax> baseLength = new HashMap<TableColumn, MinOptMax>();
+
     private boolean headerIsBeingRepeated;
     private boolean  atLeastOnce;
 
@@ -137,6 +144,267 @@
     }
 
     /**
+     * assigns a {@link MinOptMax} object to a specific {@link TableColumn}
+     * @param key a {@link TableColumn}
+     * @param mom a {@link MinOptMax} representing the width requirements of the <code>key</code>
+     */
+    public void setBaseLength(TableColumn key, MinOptMax mom) {
+        this.baseLength.put(key, mom);
+    }
+
+    /**
+     * returns the {@link MinOptMax} assigned to a table's {@link TableColumn}.
+     * @param key a {@link TableColumn}
+     * @return {@link MinOptMax} object representing the minimal, optimal and maximum width required for the
+     * <code>key</code>
+     */
+    public final MinOptMax getBaseLength(final FObj key) {
+        return this.baseLength.get(key);
+    }
+
+    /**
+     * Compute and set a set of {@link MinOptMax} widths for a {@link PrimaryGridUnit} (PGU).
+     * Now also covers PGUs spanning multiple columns. However, if such a PGU is encountered
+     * in the first row already, the table requires a second determination run.
+     * @param primary
+     * @return
+     */
+    private boolean setBaseLength(final PrimaryGridUnit primary, LayoutContext context) {
+        final Table table = this.tableLM.getTable();
+        final int index = primary.getColIndex();
+        final int n = index + primary.getCell().getNumberColumnsSpanned();
+        final TableColumn key = table.getColumn(index);
+
+        int availableSpanWidth = 0;
+        int minSpanWidth = 0;
+
+        int min;
+        int span;
+
+        // calculate width (min and opt) of all columns spanned by primary
+        for (int i = index; i < n; i++) {
+            final TableColumn column = table.getColumn(i);
+            span = column.getColumnWidth().getValue(this.tableLM);
+            availableSpanWidth += span;
+
+            min = span;
+            if (column.isAutoLayout()) {
+                final MinOptMax length = getBaseLength(column);
+                if (length != null) {
+                    min = length.getMin();
+                }
+            }
+            minSpanWidth += min;
+        }
+
+        // retrieve the maximum width of the cell's content - problematic if col-span >1 for a static first column?
+        int ipd = primary.getCellLM().getRefIPD();
+
+        // retrieve the minimum width of the cell's content - also works for cells spanning columns
+        int minIPD = primary.getCellLM().getMinimumIPD();
+
+        final MinOptMax length = getBaseLength(key);
+        if ((availableSpanWidth == 0) || (length == null)) {
+            // TODO: remove the following IF as soon as the computation of minIPD is corrected
+            if (minIPD > ipd) {    // happens e.g. for cells containing a space: ipd=0, minIPD=len(" ")
+                ipd = minIPD;
+            }
+            // |_____c1_____|   <- width for both:    minSpanWidth <= optimal <= availableSpanWidth
+            // |__c2__||___c3___| <- width for spanning cell: minIPD <= optimal <= ipd
+            MinOptMax initialMinOptMax = MinOptMax.getInstance(minIPD, ipd, ipd);
+            this.baseLength.put(key, initialMinOptMax);
+        } else {
+            if (index == n - 1) {    // a primary without col-span > 1
+                if ((availableSpanWidth < ipd) || (length.getMin() < minIPD)) { // cell needs more space
+                    MinOptMax possibleWidths =
+                        MinOptMax.getInstance(
+                                Math.max(length.getMin(), minIPD),
+                                Math.max(length.getOpt(), ipd),
+                                Math.max(length.getMax(), ipd)
+                        );
+                    return length == this.baseLength.put(key, possibleWidths);
+                }
+            } else {
+                // this primary spans multiple columns which may have to be resized!
+                // |__c1__||__c2__|   <- width for both:    minSpanWidth <= optimal <= availableSpanWidth
+                // |__c3 (span=2)___| <- width for spanning cell: minIPD <= optimal <= ipd
+                // thus, if any of the following booleans are true, the spanned columns need to be widened!
+                boolean isNotSufficientForMinIPD = minSpanWidth < minIPD;    // overflow even after linebreaks
+                boolean isNotSufficientForIPD = availableSpanWidth < ipd;    // overflow because of more content
+
+                if (isNotSufficientForMinIPD || isNotSufficientForIPD) {
+                    // columns spanned by the primary do not offer enough width and, thus, need to
+                    // be widened.
+
+                    // first step: ignore static columns which cannot be resized
+                    // this includes removing their width from the widths to process
+                    List<TableColumn> columnsToWiden = new ArrayList<TableColumn>();
+                    for (Iterator iter = table.getColumns().subList(index, n).iterator(); iter.hasNext();) {
+                        TableColumn column = (TableColumn)iter.next();
+                        if (column.isAutoLayout()) {    // column can be resized
+                            int width = column.getColumnWidth().getValue(this.tableLM);
+
+                            if (tableLM.getPossibleWidths(column, context) == null) {
+                                // ignore columns without PrimaryGridUnits
+                            } else {
+                                columnsToWiden.add(column);
+                            }
+                        } else {    // column is static and cannot be resized
+                            int width = column.getColumnWidth().getValue(this.tableLM);
+                            availableSpanWidth -= width;
+                            minSpanWidth -= width;
+                            ipd -= width;
+                            minIPD -= width;
+                        }
+                    }
+
+                    // true if only static columns are spanned -> no columns left to resize!
+                    if (columnsToWiden.isEmpty()) {
+                        LOG.warn("No columns to resize to fit a table-cell spanning these columns, expect overflows");
+                        return false;
+                    }
+
+                    // minimal width reserved by the spanned columns insufficient -> resize
+                    if (minSpanWidth < minIPD) {
+                        if (LOG.isDebugEnabled()) {
+                            LOG.warn("Cell (" + primary.getColIndex() + "," + primary.getRowIndex() + ") spanning "
+                                    + primary.getCell().getNumberColumnsSpanned() + " columns requires at least "
+                                    + minIPD + " -> widening MIN/OPT/MAX its spanned columns: " + columnsToWiden);
+                        }
+
+                        int totalIncrease = increaseMinimumWidthOfSpannedColumns(columnsToWiden, minSpanWidth, minIPD, context);
+                        // resizing the columns led to additional space being reserved by these columns!
+                        availableSpanWidth += totalIncrease;
+                    }
+
+                    // maximum width reserved by the spanned columns insufficient -> resize
+                    if (availableSpanWidth < ipd) {
+                        if (LOG.isDebugEnabled()) {
+                            LOG.warn("Cell (" + primary.getColIndex() + "," + primary.getRowIndex() + ") spanning "
+                                    + primary.getCell().getNumberColumnsSpanned() + " columns requires up to "
+                                    + ipd + " -> widening OPT/MAX of its spanned columns: " + columnsToWiden);
+                        }
+                        increaseOptimalWidthOfSpannedColumns(columnsToWiden, availableSpanWidth, ipd);
+                    }
+                }
+
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Takes a set of columns (minSpanWidthOfSpannedCells = sum of their minIPDs) which are spanned
+     * by the cell we are currently processing. Since this current cell requires a wider minIPD than
+     * all spanned columns combined, this method increases the min. width of these columns proportionally
+     * in such a way that the sum of their min. widths is >= the minIPD of the current cell.<br>
+     * Please note that for each column, all three values of its {@link MinOptMax} are increased accordingly.
+     * After all columns were processed and widened, the sum of additional space reserved by these columns
+     * is returned.
+     * @param columnsToWiden set of non-static columns which can be resized
+     * @param minSpanWidthOfSpannedCells sum of the minIPDs of the columns in columnsToWiden
+     * @param minIPD minimal width required by the current cell
+     * @param context
+     * @return the total amount of width which was added to the columns in columnsToWiden
+     */
+    private int increaseMinimumWidthOfSpannedColumns(List columnsToWiden, int minSpanWidthOfSpannedCells, int minIPD, LayoutContext context) {
+        int totalIncrease = 0;
+
+        for (Iterator iter = columnsToWiden.iterator(); iter.hasNext();) {
+            final TableColumn column = (TableColumn) iter.next();
+            MinOptMax length = tableLM.getPossibleWidths(column, context);
+
+            // calculate factor for increase of width
+            double factor = (double)length.getMin() / minSpanWidthOfSpannedCells;
+
+            // how much more space is required to display the spanning cell
+            int totalMissingMinSpace = minIPD - minSpanWidthOfSpannedCells;
+
+            int increaseForMinimum = (int) Math.ceil(factor * totalMissingMinSpace);
+
+            MinOptMax newMom =
+                    MinOptMax.getInstance(
+                            length.getMin() + increaseForMinimum,
+                            length.getOpt() + increaseForMinimum,
+                            length.getMax() + increaseForMinimum
+                    );
+            setBaseLength(column, newMom);
+            totalIncrease += increaseForMinimum;
+        }
+        return totalIncrease;
+    }
+
+    /**
+     * takes a set of columns (<b>columnsToWiden</b>) spanned by one cell (represented via a
+     * {@link PrimaryGridUnit}) and increases their minimum width value (in case the spanning cell's
+     * minIPD is bigger than the sum of
+     * goes through a subset of the columns
+     * @param columnsToWiden
+     * @param availableWidth
+     * @param requiredWidth
+     * @return
+     */
+    private boolean increaseOptimalWidthOfSpannedColumns(List columnsToWiden, int availableWidth, int requiredWidth) {
+        for (Iterator iter = columnsToWiden.iterator(); iter.hasNext();) {
+                final TableColumn column = (TableColumn) iter.next();
+                MinOptMax length = getBaseLength(column);
+
+                // calculate factor for increase of width
+                double factor = (double) length.getOpt() / availableWidth;
+
+                // how much more space is required to display the spanning cell
+                int totalMissingMaxSpace = requiredWidth - availableWidth;
+
+                // ensure the content will fit by getting the ceiling of the product
+                int increase = (int) Math.ceil(factor * totalMissingMaxSpace);
+                MinOptMax newMom =
+                    MinOptMax.getInstance(
+                            length.getMin(),
+                            length.getOpt() + increase,
+                            length.getMax() + increase
+                    );
+                setBaseLength(column, newMom);
+            }
+        return false;
+    }
+
+    private boolean setBaseLength(final TableContentPosition position, LayoutContext context) {
+        boolean done = false;
+        final EffRow row = position.getRow();
+        final Iterator grid = row.getGridUnits().iterator();
+
+        while (grid.hasNext()) {
+            final GridUnit unit = (GridUnit) grid.next();
+
+            if (unit instanceof PrimaryGridUnit) {
+                done = setBaseLength((PrimaryGridUnit) unit, context) || done;
+            }
+        }
+
+        return done;
+    }
+
+    private boolean setBaseLength(final Iterator content,LayoutContext context) {
+        boolean done = false;
+
+        while (content.hasNext()) {
+            final ListElement element = (ListElement) content.next();
+            final Position position = element.getPosition();
+
+            if (position instanceof TableContentPosition) {
+                done = setBaseLength((TableContentPosition) position, context) || done;
+            }
+        }
+
+        return done;
+    }
+
+    public boolean setBaseLength(final List content, LayoutContext context) {
+        final Table table = this.tableLM.getTable();
+        return table.isAutoLayout() && setBaseLength(content.iterator(), context);
+    }
+
+    /**
      * Get a sequence of KnuthElements representing the content
      * of the node assigned to the LM.
      *
@@ -157,6 +425,14 @@
         if (headerIter != null && headerList == null) {
             this.headerList = getKnuthElementsForRowIterator(
                     headerIter, context, alignment, TableRowIterator.HEADER);
+
+            if (setBaseLength(this.headerList, context)) {
+                final Table table = this.tableLM.getTable();
+                this.headerIter = new TableRowIterator(table, TableRowIterator.HEADER);
+                this.headerList = null;
+                return getNextKnuthElements(context, alignment);
+            }
+
             this.headerNetHeight
                     = ElementListUtils.calcContentLength(this.headerList);
             if (LOG.isDebugEnabled()) {
@@ -189,6 +465,20 @@
         if (footerIter != null && footerList == null) {
             this.footerList = getKnuthElementsForRowIterator(
                     footerIter, context, alignment, TableRowIterator.FOOTER);
+
+            if (setBaseLength(this.footerList, context)) {
+                final Table table = this.tableLM.getTable();
+
+                if (this.headerIter != null) {
+                    this.headerIter = new TableRowIterator(table, TableRowIterator.HEADER);
+                    this.headerList = null;
+                }
+
+                this.footerIter = new TableRowIterator(table, TableRowIterator.FOOTER);
+                this.footerList = null;
+                return getNextKnuthElements(context, alignment);
+            }
+
             this.footerNetHeight
                     = ElementListUtils.calcContentLength(this.footerList);
             if (LOG.isDebugEnabled()) {
@@ -211,6 +501,24 @@
         }
         returnList.addAll(getKnuthElementsForRowIterator(
                 bodyIter, context, alignment, TableRowIterator.BODY));
+
+        if (setBaseLength(returnList, context)) {
+            final Table table = this.tableLM.getTable();
+
+            if (this.headerIter != null) {
+                this.headerIter = new TableRowIterator(table, TableRowIterator.HEADER);
+                this.headerList = null;
+            }
+
+            if (this.footerIter != null) {
+                this.footerIter = new TableRowIterator(table, TableRowIterator.FOOTER);
+                this.footerList = null;
+            }
+
+            this.bodyIter = new TableRowIterator(table, TableRowIterator.BODY);
+            return getNextKnuthElements(context, alignment);
+        }
+
         if (headerAsFirst != null) {
             int insertionPoint = 0;
             if (returnList.size() > 0 && ((ListElement)returnList.getFirst()).isForcedBreak()) {
@@ -512,7 +820,7 @@
              * TableStepper haven't been removed yet.
              */
             if (pos instanceof TableContentPosition) {
-                lst.add((TableContentPosition) pos);
+                lst.add(pos);
             }
         }
         addTablePartAreas(lst, painter, part, true, true, true, lastOnPage);
@@ -531,7 +839,7 @@
     private void addBodyAreas(Iterator iterator, RowPainter painter,
             boolean lastOnPage) {
         painter.startBody();
-        List lst = new java.util.ArrayList();
+        List<TableContentPosition> lst = new java.util.ArrayList<TableContentPosition>();
         TableContentPosition pos = (TableContentPosition) iterator.next();
         boolean isFirstPos = pos.getFlag(TableContentPosition.FIRST_IN_ROWGROUP)
                 && pos.getRow().getFlag(EffRow.FIRST_IN_PART);
@@ -597,6 +905,120 @@
      */
     public int getBaseLength(int lengthBase, FObj fobj) {
         return tableLM.getBaseLength(lengthBase, fobj);
+    }
+
+    /**
+     * essentially, do the same things as {@link TableContentLayoutManager#getNextKnuthElements(LayoutContext, int)},
+     * but only do the bare minimum required to get the {@link MinOptMax} values for each column of the
+     * table with automatic layout. Thus, this computation must not have any side effects on the/any
+     * subsequent call to {@link TableContentLayoutManager#getNextKnuthElements(LayoutContext, int)}.
+     * @param childLC
+     * @param alignment
+     */
+    public void determineAutoLayoutWidths(LayoutContext context, int alignment) {
+        Table table = getTableLM().getTable();
+
+        TableRowIterator tempbodyIter = new TableRowIterator(table, TableRowIterator.BODY);
+        TableRowIterator tempheaderIter = null;
+        TableRowIterator tempfooterIter = null;
+
+        if (table.getTableHeader() != null) {
+            tempheaderIter = new TableRowIterator(table, TableRowIterator.HEADER);
+            iterateOverTableRows(tempheaderIter, context, alignment, TableRowIterator.HEADER);
+        }
+
+        iterateOverTableRows(tempbodyIter, context, alignment, TableRowIterator.BODY);
+
+        if (table.getTableFooter() != null) {
+            tempfooterIter = new TableRowIterator(table, TableRowIterator.FOOTER);
+            iterateOverTableRows(tempfooterIter, context, alignment, TableRowIterator.FOOTER);
+        }
+    }
+
+    /**
+     * To be used only during the preprocessing run which determines the dimensions of Tables with table-layout="auto".
+     * Iterates over all rows of the provided iterator (either for the header, footer or body of a table depending
+     * on the parameter <code>bodyType</code>). For each row, the contained {@link PrimaryGridUnit}s are taken to
+     * determine their widths based on their content. These widths are then propagated to the individual
+     * {@link TableColumn}s via {@link #setBaseLength(PrimaryGridUnit)}. Afterwards, the {@link PrimaryGridUnit}'s
+     * elements reset so that they are properly processed during the rendering run (this is necessary since the
+     * dimensions obtained for a column are still subject to changes). <br>
+     * Based on
+     * {@link TableContentLayoutManager#getKnuthElementsForRowIterator(TableRowIterator, LayoutContext, int, int)}
+     * However, since we are only interested in the widths of the contained PGUs, most of the original method was
+     * removed.
+     * @param iter Iterator providing access to rows which belong either to the table's body, header or footer
+     * @param context layout context
+     * @param alignment
+     * @param bodyType indicates which part of a table is processed (actually not required)
+     */
+    private void iterateOverTableRows(TableRowIterator iter,    // returns indiv. rows
+            LayoutContext context, int alignment, int bodyType) {
+        EffRow[] rowGroup;
+        List<PrimaryGridUnit> colspanningPGUs = new LinkedList<PrimaryGridUnit>();
+        while ((rowGroup = iter.getNextRowGroup()) != null) {
+            //RowGroupLayoutManager rowGroupLM = new RowGroupLayoutManager(getTableLM(), rowGroup,
+            //        null);    // the actual tablestepper might lead to undesired side effects!
+            /**
+             * based on RowGroupLayoutManager#createElementsForRowGroup
+             * initializes the PGUs of one row at a time
+             */
+            for (EffRow row : rowGroup) {
+                for (GridUnit gu : row.getGridUnits()) {
+                    if (gu.isPrimary()) {
+                        PrimaryGridUnit primary = gu.getPrimary();
+
+                        // during this iteration, the width of PGUs in the first row which span multiple columns
+                        // cannot be determined and, thus, have to be finished after all other rows are done.
+                        if ((primary.getRowIndex() == 0) && (primary.getCell().getNumberColumnsSpanned() > 1)) {
+                            LOG.debug("Will revisit first row");
+                            colspanningPGUs.add(primary);
+                        }
+                        determineWidthOfPrimary(primary, context, alignment);
+                    }
+                }
+            }
+        }
+        for (PrimaryGridUnit primary : colspanningPGUs) {
+            determineWidthOfPrimary(primary, context, alignment);
+        }
+
+    }
+
+	private void determineWidthOfPrimary(PrimaryGridUnit primary, LayoutContext context, int alignment) {
+        // recursively retrieve (and thereby calculate the dimensions of)
+        // all KnuthElements of all contained LayoutManagers for the given cell
+        primary.createCellLM();
+        TableCellLayoutManager cellLM = primary.getCellLM();
+        cellLM.setParent(tableLM);
+        //Calculate width of cell
+        int spanWidth = 0;
+        @SuppressWarnings("unchecked")
+        Iterator<TableColumn> colIter = tableLM.getTable().getColumns().listIterator(
+                primary.getColIndex());
+        for (int i = 0, c = primary.getCell().getNumberColumnsSpanned(); i < c; i++) {
+            spanWidth += colIter.next().getColumnWidth().getValue(tableLM);
+        }
+
+        LayoutContext childLC = LayoutContext.offspringOf(context);
+        childLC.setStackLimitBP(context.getStackLimitBP());
+
+        // TODO: ugly workaround to deal with one-column tables which would be rendered broken otherwise
+        if (tableLM.getTable().getColumns().size() == 1) {
+            childLC.setRefIPD(context.getRefIPD());
+        } else {
+            childLC.setRefIPD(spanWidth);
+        }
+
+        //Get the element list for the cell contents
+        List elems = cellLM.getNextKnuthElements(childLC, alignment);
+        // temporarily assign these KnuthElements to the PGU to calculate its dimensions
+        primary.setElements(elems);
+        setBaseLength(primary, context);
+
+        // reset the PGU (and thereby reset (even destroy?) all contained LayoutManagers)
+        // the dimensions, however, are still present in form of a MinOptMax!
+        primary.setElements(null);
-    }
+	}
 
 }
Index: test/layoutengine/standard-testcases/table-layout_auto_static-columns_2.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- test/layoutengine/standard-testcases/table-layout_auto_static-columns_2.xml	(revision )
+++ test/layoutengine/standard-testcases/table-layout_auto_static-columns_2.xml	(revision )
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You 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.
+-->
+<!-- $Id$ -->
+<testcase>
+  <info>
+    <p>
+    </p>
+  </info>
+  <fo>
+    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+      <fo:layout-master-set>
+        <fo:simple-page-master master-name="first"
+                              page-height="29.7cm"
+                              page-width="21cm"
+                              margin-top="1cm"
+                              margin-bottom="2cm"
+                              margin-left="2.5cm"
+                              margin-right="2.5cm">
+          <fo:region-body margin-top="3cm"/>
+          <fo:region-before extent="3cm"/>
+          <fo:region-after extent="1.5cm"/>
+        </fo:simple-page-master>
+      </fo:layout-master-set>
+      
+      <fo:page-sequence master-reference="first">
+        
+        <fo:flow flow-name="xsl-region-body">
+          <fo:block>
+            In this table, columns 2,3, and 4 have a static width of '1cm' and cannot be widened.
+            The col-spanning PGU in cell G requires more space, than these three columns provide (3 * '1cm' + table cell indentations &lt; minIPD of G).
+            With no columns to expand, the content of column G overflows into cell H.
+          </fo:block>
+          
+          <fo:table table-layout="auto" width="100%" border-collapse="separate">
+            <fo:table-column column-number="2" column-width="1cm"/>
+            <fo:table-column column-number="3" column-width="1cm"/>
+            <fo:table-column column-number="4" column-width="1cm"/>
+            <fo:table-column column-number="5" />
+            <fo:table-body>
+              
+              <fo:table-row>
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black" border="0.5pt dotted black">
+                <fo:block>A</fo:block>
+                </fo:table-cell>
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black" border="0.5pt dotted black">
+                  <fo:block>1cm</fo:block>
+                </fo:table-cell>
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black" border="0.5pt dotted black">
+                  <fo:block>1cm</fo:block>
+                </fo:table-cell>
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black" border="0.5pt dotted black">
+                  <fo:block>1cm</fo:block>
+                </fo:table-cell>
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black" border="0.5pt dotted black">
+                  <fo:block>EEEEEEEEEEE EEEEEEEEEEEEEEEEEEEE EEEEEEEEEEEEEEEEEEEEEEEE EEEEEEEEEEEEE</fo:block>
+                </fo:table-cell>               
+              </fo:table-row>
+              
+              <fo:table-row>
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black" border="0.5pt dotted black">
+                <fo:block>F</fo:block>
+                </fo:table-cell>
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black" border="0.5pt dotted black" number-columns-spanned="3">
+                  <fo:block>overflowing_cell (minIPD>3cm)</fo:block>
+                </fo:table-cell>
+                <fo:table-cell padding="2pt" border-right="0.5pt dotted black" border="0.5pt dotted black">
+                  <fo:block>H</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+            </fo:table-body>
+          </fo:table>
+          
+          <fo:block>Expected warning1: 'No columns to resize to fit a table-cell spanning these columns, expect overflows'</fo:block>
+          <fo:block>Expected warning2: 'The contents of fo:block line 1 exceed the available area in the inline-progression direction by 5318 millipoints. (See position 56:26)'</fo:block>
+                    
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <!-- TODO -->
+  </checks>
+</testcase>
Index: src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java	(revision 1686091)
+++ src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java	(revision )
@@ -280,4 +280,15 @@
     public void recreateChildrenLMs() {
 
     }
+
+    /** {@inheritDoc} */
+    public int getMinimumIPD() {
+        int minimumIPD = -1;
+        for (LayoutManager childLM : getChildLMs()) {
+            int curMinIPD = childLM.getMinimumIPD();
+            minimumIPD = Math.max(minimumIPD, curMinIPD);
+        }
+        return minimumIPD;
+    }
+
 }
Index: src/java/org/apache/fop/layoutmgr/BlockLevelEventProducer.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/apache/fop/layoutmgr/BlockLevelEventProducer.xml	(revision 1686091)
+++ src/java/org/apache/fop/layoutmgr/BlockLevelEventProducer.xml	(revision )
@@ -6,9 +6,9 @@
     The ASF licenses this file to You 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.
@@ -31,4 +31,5 @@
   <message key="missingSubsequencesInPageSequenceMaster">No subsequences in page-sequence-master "{pageSequenceMasterName}".{{locator}}</message>
   <message key="noMatchingPageMaster">No simple-page-master matching "{pageMasterName}" in page-sequence-master "{pageSequenceMasterName}".{{locator}}</message>
   <message key="nonRestartableContentFlowingToNarrowerPage">Content that cannot handle IPD changes is flowing to a narrower page. Part of it may be clipped by the page border.</message>
+  <message key="columnsInAutoTableTooWide">The minimal width required for the auto-layout of a table's columns is bigger than the available space ({effIPD}mpt &gt; {maxIPD}mpt). Part of it may overflow the page border. {{locator}}</message>
 </catalogue>
Index: src/java/org/apache/fop/layoutmgr/LayoutContext.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/apache/fop/layoutmgr/LayoutContext.java	(revision 1686091)
+++ src/java/org/apache/fop/layoutmgr/LayoutContext.java	(revision )
@@ -52,6 +52,23 @@
 
     private static final int TREAT_AS_ARTIFACT = 0x20;
 
+    /**
+     * Flags related to "auto" table layout
+     */
+    private static final int IN_AUTO_LAYOUT_DETERMINATION_MODE = 0x40;
+
+    private static final int IS_CHILD_OF_AUTO_LAYOUT_ELEMENT = 0x80;
+
+    /**
+     * Flag related to "fox:disable-column-balancing"
+     */
+    private static final int DISABLE_COLUMN_BALANCING = 0x100;
+
+    private static final int PROPAGATED_FLAGS =
+            TREAT_AS_ARTIFACT
+            | IN_AUTO_LAYOUT_DETERMINATION_MODE
+            | IS_CHILD_OF_AUTO_LAYOUT_ELEMENT;
+
     private int flags; // Contains some set of flags defined above
 
     /**
@@ -85,13 +102,13 @@
      * A list of pending marks (border and padding) on the after edge when a page break occurs.
      * May be null.
      */
-    private List pendingAfterMarks;
+    private List<ListElement> pendingAfterMarks;
 
     /**
      * A list of pending marks (border and padding) on the before edge when a page break occurs.
      * May be null.
      */
-    private List pendingBeforeMarks;
+    private List<ListElement> pendingBeforeMarks;
 
     /** Current hyphenation context. May be null. */
     private HyphContext hyphContext;
@@ -136,12 +153,12 @@
     /**
      * Returns a descendant of the given layout context. The new context is the same as
      * what would have been created by {@link #newInstance()}, except for inheritable
-     * properties that are passed on by the parent. At the moment, the only inheritable
-     * property is the value returned by {@link #treatAsArtifact()}.
+     * properties that are passed on by the parent.
+     * At the moment, the only inheritable properties are all propagated flags.
      */
     public static LayoutContext offspringOf(LayoutContext parent) {
         LayoutContext offspring = new LayoutContext(0);
-        offspring.setTreatAsArtifact(parent.treatAsArtifact());
+        offspring.propagateFlagsFrom(parent);
         return offspring;
     }
 
@@ -169,18 +186,18 @@
     private LayoutContext(int flags) {
         this.flags = flags;
         this.refIPD = 0;
-        stackLimitBP = MinOptMax.ZERO;
-        leadingSpace = null;
-        trailingSpace = null;
+        this.stackLimitBP = MinOptMax.ZERO;
+        this.leadingSpace = null;
+        this.trailingSpace = null;
     }
 
     /** @param source from which pending marks are copied */
     public void copyPendingMarksFrom(LayoutContext source) {
         if (source.pendingAfterMarks != null) {
-            this.pendingAfterMarks = new java.util.ArrayList(source.pendingAfterMarks);
+            this.pendingAfterMarks = new java.util.ArrayList<ListElement>(source.pendingAfterMarks);
         }
         if (source.pendingBeforeMarks != null) {
-            this.pendingBeforeMarks = new java.util.ArrayList(source.pendingBeforeMarks);
+            this.pendingBeforeMarks = new java.util.ArrayList<ListElement>(source.pendingBeforeMarks);
         }
     }
 
@@ -206,6 +223,15 @@
         setFlags(flags, false);
     }
 
+    /**
+     * Propagate flags from the given parent context
+     *
+     * @param parentLC  the parent context
+     */
+    public void propagateFlagsFrom(LayoutContext parentLC) {
+        this.flags = (parentLC.flags & PROPAGATED_FLAGS);
+    }
+
     /** @return true if new area is set */
     public boolean isStart() {
         return ((this.flags & NEW_AREA) != 0);
@@ -231,7 +257,75 @@
         return ((this.flags & SUPPRESS_BREAK_BEFORE) != 0);
     }
 
+    /** @return true if "treat as artifact" is set */
+    public boolean treatAsArtifact() {
+        return (flags & TREAT_AS_ARTIFACT) != 0;
+    }
+
     /**
+     * Sets the "treat as artifact" flag
+     * @param treatAsArtifact   the flag boolean value
+     */
+    public void setTreatAsArtifact(boolean treatAsArtifact) {
+        setFlags(TREAT_AS_ARTIFACT, treatAsArtifact);
+    }
+
+
+    /** @return whether the column balancer should be disabled before a spanning block. */
+    public boolean isColumnBalancingDisabled() {
+        return (flags & DISABLE_COLUMN_BALANCING) != 0;
+    }
+
+    /**
+     * Disables column balancing before a spanning block
+     *
+     * @see #isColumnBalancingDisabled()
+     */
+    public void disableColumnBalancing() {
+        setFlags(DISABLE_COLUMN_BALANCING, true);
+    }
+
+    /**
+     * Enables column balancing before a spanning block
+     *
+     * @see #isColumnBalancingDisabled()
+     */
+    public void enableColumnBalancing() {
+        unsetFlags(DISABLE_COLUMN_BALANCING);
+    }
+
+    /**
+     * @param b
+     */
+    public void setChildOfAutoLayoutElement(boolean b) {
+        setFlags(IS_CHILD_OF_AUTO_LAYOUT_ELEMENT, b);
+    }
+
+    /**
+     *
+     * @return
+     */
+    public boolean isChildOfAutoLayoutElement() {
+        return (flags & IS_CHILD_OF_AUTO_LAYOUT_ELEMENT) != 0;
+    }
+
+    /**
+     *
+     * @return
+     */
+    public boolean isInAutoLayoutDeterminationMode() {
+        return (flags & IN_AUTO_LAYOUT_DETERMINATION_MODE) != 0;
+    }
+
+    /**
+     *
+     * @param b
+     */
+    public void setInAutoLayoutDeterminationMode(boolean b) {
+        setFlags(IN_AUTO_LAYOUT_DETERMINATION_MODE, b);
+    }
+
+    /**
      * Returns the strength of a keep-with-next currently pending.
      * @return the keep-with-next strength
      */
@@ -334,7 +428,7 @@
      */
     public void addPendingAfterMark(UnresolvedListElementWithLength element) {
         if (this.pendingAfterMarks == null) {
-            this.pendingAfterMarks = new java.util.ArrayList();
+            this.pendingAfterMarks = new java.util.ArrayList<ListElement>();
         }
         this.pendingAfterMarks.add(element);
     }
@@ -343,7 +437,7 @@
      * @return the pending border and padding elements at the after edge
      * @see #addPendingAfterMark(UnresolvedListElementWithLength)
      */
-    public List getPendingAfterMarks() {
+    public List<ListElement> getPendingAfterMarks() {
         if (this.pendingAfterMarks != null) {
             return Collections.unmodifiableList(this.pendingAfterMarks);
         } else {
@@ -367,7 +461,7 @@
      */
     public void addPendingBeforeMark(UnresolvedListElementWithLength element) {
         if (this.pendingBeforeMarks == null) {
-            this.pendingBeforeMarks = new java.util.ArrayList();
+            this.pendingBeforeMarks = new java.util.ArrayList<ListElement>();
         }
         this.pendingBeforeMarks.add(element);
     }
@@ -376,7 +470,7 @@
      * @return the pending border and padding elements at the before edge
      * @see #addPendingBeforeMark(UnresolvedListElementWithLength)
      */
-    public List getPendingBeforeMarks() {
+    public List<ListElement> getPendingBeforeMarks() {
         if (this.pendingBeforeMarks != null) {
             return Collections.unmodifiableList(this.pendingBeforeMarks);
         } else {
@@ -686,12 +780,5 @@
         this.disableColumnBalancing = disableColumnBalancing;
     }
 
-    public boolean treatAsArtifact() {
-        return (flags & TREAT_AS_ARTIFACT) != 0;
-    }
-
-    public void setTreatAsArtifact(boolean treatAsArtifact) {
-        setFlags(TREAT_AS_ARTIFACT, treatAsArtifact);
-    }
 }
 
Index: src/java/org/apache/fop/fo/flow/table/PrimaryGridUnit.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/apache/fop/fo/flow/table/PrimaryGridUnit.java	(revision 1686451)
+++ src/java/org/apache/fop/fo/flow/table/PrimaryGridUnit.java	(revision )
@@ -239,11 +239,9 @@
         return getAfterBorderWidth(getCell().getNumberRowsSpanned() - 1, which);
     }
 
-    /** @return the length of the cell content */
+    /** @return the length of the cell content, auto-layout disallows caching */
     public int getContentLength() {
-        if (contentLength < 0) {
-            contentLength = ElementListUtils.calcContentLength(elements);
+        contentLength = ElementListUtils.calcContentLength(elements);
-        }
         return contentLength;
     }
 
Index: src/java/org/apache/fop/layoutmgr/BlockLevelEventProducer.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/apache/fop/layoutmgr/BlockLevelEventProducer.java	(revision 1686091)
+++ src/java/org/apache/fop/layoutmgr/BlockLevelEventProducer.java	(revision )
@@ -59,6 +59,18 @@
     void rowTooTall(Object source, int row, int effCellBPD, int maxCellBPD, Locator loc);
 
     /**
+     * The minimal width required for the auto-layout of a table's columns is bigger than the available space.
+     * Alternatively: even using the minimal width required for the auto-layout table, its content overflows the
+     * available area by (effIPD - maxIPD) millipoints 
+     * @param source the event source
+     * @param effIPD the effective extent in inline-progression direction of the table contents
+     * @param maxIPD the maximum extent in inline-progression direction available
+     * @param loc the location of the error or null
+     * @event.severity WARN
+     */
+    void columnsInAutoTableTooWide(Object source, int effIPD, int maxIPD, Locator loc);
+    
+    /**
      * Auto-table layout is not supported, yet.
      * @param source the event source
      * @param loc the location of the error or null
