Index: src/java/org/apache/fop/layoutmgr/LayoutManager.java
===================================================================
--- src/java/org/apache/fop/layoutmgr/LayoutManager.java	(revision 440714)
+++ src/java/org/apache/fop/layoutmgr/LayoutManager.java	(working copy)
@@ -26,6 +26,9 @@
 import org.apache.fop.datatypes.PercentBaseContext;
 import org.apache.fop.fo.FObj;
 
+import org.apache.fop.traits.MinOptMax;
+
+
 /**
  * The interface for all LayoutManagers.
  */
@@ -227,4 +230,10 @@
      * @return the same Position but with a position index
      */
     Position notifyPos(Position pos);
+
+    /**
+     * Returns the min and max text withs
+     * @return the min and max text withs
+     */
+    MinOptMax minMaxTextWidths() ;
 }
Index: src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
===================================================================
--- src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java	(revision 440714)
+++ src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java	(working copy)
@@ -25,6 +25,7 @@
 import org.apache.fop.area.PageViewport;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.flow.RetrieveMarker;
+import org.apache.fop.traits.MinOptMax;
 
 import java.util.LinkedList;
 import java.util.List;
@@ -382,4 +383,12 @@
         Map atts = getFObj().getForeignAttributes();
         targetArea.setForeignAttributes(atts);
     }
+
+    /**
+     * Returns the min and max text withs
+     * @return the min and max text withs
+     */
+    public MinOptMax minMaxTextWidths() {
+        return new MinOptMax();
+    }
 }
Index: src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
===================================================================
--- src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java	(revision 440714)
+++ src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java	(working copy)
@@ -322,6 +322,10 @@
         return parentLM.getPSLM();
     }
 
+    public MinOptMax minMaxTextWidths() {
+        return new MinOptMax();
+    }
+
     // --------- Property Resolution related functions --------- //
     
     /**
Index: src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
===================================================================
--- src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java	(revision 440714)
+++ src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java	(working copy)
@@ -47,6 +47,7 @@
 import org.apache.fop.layoutmgr.Position;
 import org.apache.fop.layoutmgr.PositionIterator;
 import org.apache.fop.layoutmgr.SpaceSpecifier;
+import org.apache.fop.traits.MinOptMax;
 import org.apache.fop.area.Area;
 import org.apache.fop.area.LineArea;
 import org.apache.fop.area.inline.InlineArea;
@@ -76,6 +77,7 @@
 
     private Block fobj;
     private boolean isFirstInBlock;
+    private MinOptMax minMaxW;
     
     /** @see org.apache.fop.layoutmgr.LayoutManager#initialize() */
     public void initialize() {
@@ -558,6 +560,16 @@
         follow = f;
     }
 
+    public MinOptMax minMaxTextWidths() {
+      if (this.minMaxW==null) {
+        return new MinOptMax();
+      }
+      else {
+        return this.minMaxW;
+      }
+    }
+    
+
     /** @see org.apache.fop.layoutmgr.LayoutManager */
     public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
         Font fs = fobj.getCommonFont().getFontState(fobj.getFOEventHandler().getFontInfo(), this);
@@ -682,6 +694,9 @@
                 }
             }
             
+            int sum = 0;
+            int max = 0;
+
             // loop over the KnuthSequences (and single KnuthElements) in returnedList
             ListIterator iter = returnedList.listIterator();
             while (iter.hasNext()) {
@@ -697,6 +712,24 @@
                     }
                     bPrevWasKnuthBox = lastElement.isBox() && ((KnuthElement) lastElement).getW() != 0;
                     
+
+                    //compute the full width of the element list
+                    ListElement elem;
+                    for (int i=0; i < sequence.size(); i++) {
+                      elem = sequence.getElement(i);
+                      //System.out.println("width of element #" + i + ": " + ((KnuthElement) elem).getW());
+                      sum += ((KnuthElement) elem).getW();
+                      //System.out.println(elem);
+                      if (max < (((KnuthElement) elem).getW())) max = ((KnuthElement) elem).getW();
+                    }
+                    
+                    //System.out.println("full width of element list: " + sum);
+                    //System.out.println("minimum width: " + max);
+                    //System.out.println("=======================================");
+
+                    //TableHelper tclm = new TableHelper(sum, max);
+                    this.minMaxW = new MinOptMax(max, max, sum);
+
                     // if last paragraph is open, add the new elements to the paragraph
                     // else this is the last paragraph
                     if (lastPar == null) { 
Index: src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java
===================================================================
--- src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java	(revision 440714)
+++ src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java	(working copy)
@@ -56,6 +56,8 @@
 import org.apache.fop.layoutmgr.SpaceResolver.SpaceHandlingBreakPosition;
 import org.apache.fop.traits.MinOptMax;
 
+import org.apache.fop.fo.properties.FixedLength;
+
 /**
  * Layout manager for table contents, particularly managing the creation of combined element lists.
  */
@@ -468,11 +470,17 @@
                         }
                         LayoutContext childLC = new LayoutContext(0);
                         childLC.setStackLimit(context.getStackLimit()); //necessary?
+                        if (spanWidth == 0) spanWidth = 2147000000;
                         childLC.setRefIPD(spanWidth);
                         
                         //Get the element list for the cell contents
                         LinkedList elems = primary.getCellLM().getNextKnuthElements(
-                                                childLC, alignment);
+                                childLC, alignment);
+
+                        if (getTableLM().getTable().isAutoLayout() && getTableLM().calculateMode) {
+                          this.determineAutoColumnWidths(primary);
+                        }
+
                         //Temporary? Multiple calls in case of break conditions.
                         //TODO Revisit when table layout is restartable
                         while (!primary.getCellLM().isFinished()) {
@@ -1219,7 +1227,24 @@
             return sb.toString();
         }
     }
-    
+ 
+    private void determineAutoColumnWidths(PrimaryGridUnit primary) {
+        MinOptMax minMaxW = primary.getCellLM().minMaxTextWidths();
+      
+        // if we found new optimal width for the column
+        if (getTableLM().getColumns2().getColumn(primary.getStartCol()+1)
+                    .getColumnWidth().getValue(getTableLM()) < minMaxW.max) {
+          getTableLM().getColumns2().getColumn(primary.getStartCol()+1)
+                    .setColumnWidth(new FixedLength(minMaxW.max));
+          
+        }
+      
+        // if we found a new minimal width for the column
+        if (getTableLM().getMin2(primary.getStartCol()) > minMaxW.min) {
+          getTableLM().setMin2(primary.getStartCol(), minMaxW.min);
+        }
+    }
+
     // --------- Property Resolution related functions --------- //
     
     /**
Index: src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java
===================================================================
--- src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java	(revision 440714)
+++ src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java	(working copy)
@@ -184,6 +184,8 @@
         float factors = 0;
         double unit = 0;
         
+        if (!table.isAutoLayout()) {
+
         /* calculate the total width (specified absolute/percentages), 
          * and work out the total number of factors to use to distribute
          * the remaining space (if any)
@@ -198,7 +200,8 @@
                 }
             }
         }
-        
+ }        
+
         /* distribute the remaining space over the accumulated 
          * factors (if any) 
          */
@@ -220,11 +223,17 @@
      */
     public int getXOffset(int col, PercentBaseContext context) {
         int xoffset = 0;
-        for (int i = col; --i >= 0;) {
+        /*for (int i = col; --i >= 0;) {
             if (colWidths.get(i) != null) {
                 xoffset += ((Length) colWidths.get(i)).getValue(context);
             }
+        }*/
+        for (int i = 1; i < col; i++) {
+            if (getColumn(i) != null) {
+             xoffset += getColumn(i).getColumnWidth().getValue(context);
+          }
         }
+
         return xoffset;
     }
 
Index: src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
===================================================================
--- src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java	(revision 440714)
+++ src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java	(working copy)
@@ -41,11 +41,14 @@
 import org.apache.fop.traits.SpaceVal;
 
 import java.util.Iterator;
+import java.util.ArrayList;
 import java.util.LinkedList;
 import org.apache.fop.datatypes.LengthBase;
 import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.FObj;
 
+import org.apache.fop.fo.properties.FixedLength;
+
 /**
  * LayoutManager for a table FO.
  * A table consists of oldColumns, table header, table footer and multiple
@@ -58,8 +61,8 @@
                 implements ConditionalElementListener {
     
     private TableContentLayoutManager contentLM; 
+    private TableContentLayoutManager contentLM2; 
     private ColumnSetup columns = null;
-
     private Block curBlockArea;
 
     private double tableUnit;
@@ -74,7 +77,13 @@
     
     private int halfBorderSeparationBPD;
     private int halfBorderSeparationIPD;
-    
+
+    private ArrayList columnsMins;
+
+    private ColumnSetup columns2  = null;
+    private ArrayList columnsMins2;
+    public  boolean calculateMode;
+
     /**
      * Create a new table layout manager.
      * @param node the table FO
@@ -82,6 +91,8 @@
     public TableLayoutManager(Table node) {
         super(node);
         this.columns = new ColumnSetup(node);
+        this.columns2 = new ColumnSetup(node);
+        this.columnsMins = new ArrayList(this.columns.getColumnCount());
     }
 
     /** @return the table FO */
@@ -95,6 +106,27 @@
     public ColumnSetup getColumns() {
         return this.columns;
     }
+
+    public ColumnSetup getColumns2() {
+        return this.columns2;
+    }
+
+    public int getMin(int index) {
+        return ((Integer)(this.columnsMins.get(index))).intValue();
+    }
+
+    public void setMin(int index, int value) {
+        this.columnsMins.set(index, (Object)(new Integer(value)));
+    }
+
+    public int getMin2(int index) {
+        return ((Integer)(this.columnsMins2.get(index))).intValue();
+    }
+
+    public void setMin2(int index, int value) {
+        this.columnsMins2.set(index, (Object)(new Integer(value)));
+    }
+
     
     /** @see org.apache.fop.layoutmgr.LayoutManager#initialize() */
     public void initialize() {
@@ -183,8 +215,10 @@
         /* initialize unit to determine computed values
          * for proportional-column-width()
          */
-        if (tableUnit == 0.0) {
-            this.tableUnit = columns.computeTableUnit(this);
+        if(!getTable().isAutoLayout()) {
+          if (tableUnit == 0.0) {
+              this.tableUnit = columns.computeTableUnit(this);
+          }
         }
 
         if (!firstVisibleMarkServed) {
@@ -199,6 +233,13 @@
         //Spaces, border and padding to be repeated at each break
         addPendingMarks(context);
 
+        /* Start auto table layout */
+        if (getTable().isAutoLayout()) {
+          this.determineAutoColumWidths(context,alignment);            
+        }
+
+        /* End auto table layout */
+
         LinkedList returnedList = null;
         LinkedList contentList = new LinkedList();
         //Position returnPosition = new NonLeafPosition(this, null);
@@ -526,4 +567,117 @@
         }
     }
 
+
+    private void determineAutoColumWidths(LayoutContext context, int alignment) {
+        //System.out.println("table-layout=\"auto\" has been detected");
+        
+        //this.columns2 = new ColumnSetup(node);
+        this.columnsMins2 = new ArrayList(this.columns2.getColumnCount());
+  
+    
+        // initialize lists
+        for (int i=0 ; i<this.columns.getColumnCount() ; i++) {
+          this.columnsMins.add(new Integer(5000000));
+          this.columnsMins2.add(new Integer(5000000));
+        }
+  
+        //int w = getTable().getInlineProgressionDimension().getOptimum(this).getLength().getValue(this);
+        int w = getContentAreaIPD(); 
+  
+        LinkedList returnedList2 = null;
+        LinkedList contentList2 = new LinkedList();
+  
+  
+        LayoutContext childLC2 = new LayoutContext(0);
+        
+        childLC2.setRefIPD(context.getRefIPD());
+        childLC2.copyPendingMarksFrom(context);
+  
+        if (contentLM2 == null) {
+            contentLM2 = new TableContentLayoutManager(this);
+            TableHelper th = new TableHelper();
+        }
+  
+        for (Iterator i = columns2.iterator(); i.hasNext();) {
+            TableColumn column2 = (TableColumn) i.next();
+            if (column2 != null) {
+                column2.setColumnWidth(new FixedLength(0));
+            }
+        }
+                
+        this.calculateMode = true;
+
+        int alignment2 = alignment;
+        returnedList2 = contentLM2.getNextKnuthElements(childLC2, alignment2);
+  
+        // we don't want to calculate optimal column width anymore
+        this.calculateMode = false;
+
+        // copy column setup
+        for (Iterator i = columns.iterator(), i2 = columns2.iterator(); i.hasNext();) {
+            TableColumn column = (TableColumn) i.next();
+            TableColumn column2 = (TableColumn) i2.next();
+            if (column != null) {
+                column.setColumnWidth(new FixedLength(column2.getColumnWidth().getValue(this)));
+            }
+        }
+  
+        int sumOpt = 0;
+        int sumMin = 0;
+        
+        // calculate optimal width of table
+        for (Iterator i = columns2.iterator(); i.hasNext();) {
+            TableColumn column2 = (TableColumn) i.next();
+            if (column2 != null) {
+                sumOpt += column2.getColumnWidth().getValue(this);
+                //sumMin += column2.getColumnMinWidth().getValue(this);
+            }
+        }
+  
+        // calculate minimum width of table            
+        for (Iterator i = columnsMins2.iterator(); i.hasNext();) {
+            Integer column2 = (Integer) i.next();
+            if (column2 != null) {
+                sumMin += column2.intValue();
+            }
+        }
+        
+        int add = w - sumOpt;
+        int sub = w - sumMin;          
+  
+        // cannot fit
+        if (sub < 0) {
+          System.out.println("WARNING: cannot fit");
+        }
+  
+        if (add < 0) { //we have to shrink the columns
+          int t = add;
+          while (t < 0 ) {
+            Iterator i2 = columnsMins2.iterator();
+            for (Iterator i = columns.iterator(); i.hasNext();) {
+                TableColumn column = (TableColumn) i.next();
+                Integer column2 = (Integer) i2.next();
+                if (column != null) {
+                    if (column2.intValue() < column.getColumnWidth().getValue(this)) {
+                      column.setColumnWidth(new FixedLength(column.getColumnWidth().getValue(this) - 1));
+                      t++;
+                    }
+                  }
+            }
+          }
+        } else {
+          // otherwise add extra space
+          if (getTable().getInlineProgressionDimension().getOptimum(this).getEnum() != EN_AUTO) {
+            add /= columns.getColumnCount();
+            Iterator i2 = columns2.iterator();
+            for (Iterator i = columns.iterator(); i.hasNext();) {
+                TableColumn column = (TableColumn) i.next();
+                TableColumn column2 = (TableColumn) i2.next();
+                if (column != null) {
+                    column.setColumnWidth(new FixedLength(column2.getColumnWidth().getValue(this) + add));
+                }
+            }
+          }
+        }
+      }
 }
\ No newline at end of file
Index: src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
===================================================================
--- src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java	(revision 440714)
+++ src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java	(working copy)
@@ -65,6 +65,8 @@
     private int borderAndPaddingBPD;
     private boolean emptyCell = true;
 
+    private MinOptMax minMaxW;
+
     /**
      * Create a new Cell layout manager.
      * @param node table-cell FO for which to create the LM
@@ -128,7 +130,16 @@
         iIndents += getTableCell().getCommonBorderPaddingBackground().getPaddingEnd(false, this);
         return iIndents;
     }
-    
+
+    public MinOptMax minMaxTextWidths() {
+      if (this.minMaxW==null) {
+        return new MinOptMax();
+      }
+      else {
+        return this.minMaxW;
+      }
+    }
+
     /**
      * @see org.apache.fop.layoutmgr.LayoutManager
      */
@@ -159,6 +170,9 @@
 
             // get elements from curLM
             returnedList = curLM.getNextKnuthElements(childLC, alignment);
+
+            this.minMaxW = curLM.minMaxTextWidths();
+
             if (childLC.isKeepWithNextPending()) {
                 log.debug("child LM signals pending keep with next");
             }
Index: src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
===================================================================
--- src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java	(revision 440714)
+++ src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java	(working copy)
@@ -81,6 +81,8 @@
     private Position auxiliaryPosition;
 
     private int contentAreaIPD = 0;
+
+    private MinOptMax minMaxW;
     
     /**
      * @param node the fo this LM deals with
@@ -215,6 +217,15 @@
         return contentIPD;
     }
     
+    public MinOptMax minMaxTextWidths() {
+      if (this.minMaxW==null) {
+        return new MinOptMax();
+      }
+      else {
+        return this.minMaxW;
+      }
+    }
+
     /**
      * @see LayoutManager#getNextKnuthElements(LayoutContext, int)
      */
@@ -274,6 +285,10 @@
 
             // get elements from curLM
             returnedList = curLM.getNextKnuthElements(childLC, alignment);
+
+            this.minMaxW = curLM.minMaxTextWidths();
+            //System.out.println(this.minMaxW);
+
             if (contentList.size() == 0 && childLC.isKeepWithPreviousPending()) {
                 context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
                 childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false);
