                 if (vsb && viewport)
                 { 
                     vAuto = true;
-                    var contentHeight:Number = viewport.contentHeight;
-                    if (isNaN(explicitViewportH))
-                        showVSB = contentHeight > (h - (minViewportInset * 2));
-                    else
-                        showVSB = contentHeight >  explicitViewportH;
+                    var viewportH:Number = 
+                        isNaN(explicitViewportH) ? (h - (minViewportInset * 2)) : explicitViewportH;
+                    showVSB = (contentH > viewportH) && (h >= vsb.minHeight);
                 }                        
                 break;
         }
         
         // Shrink the viewport's width,height for the visible scrollbars
-        var viewportH:Number = h - minViewportInset;
-        var hsbH:Number = 0;
-        if (showHSB) 
-        {
-            hsbH = hsb.getPreferredBoundsHeight();
-            viewportH -= Math.max(minViewportInset, hsbH);
-        }
-        var viewportW:Number = w - minViewportInset;
-        var vsbW:Number = 0;
-        if (showVSB) 
-        {
-            vsbW = vsb.getPreferredBoundsWidth();
-            viewportW -= Math.max(minViewportInset, vsbW);
-        }
+        
+        viewportH = h - minViewportInset;
+        if (showHSB) viewportH -= Math.max(minViewportInset, hsbH);
+            
+        viewportW = w - minViewportInset;
+        if (showVSB) viewportW -= Math.max(minViewportInset, vsbW);
         
         // If the scrollBarPolicy is auto, and we're only showing one scrollbar, 
         // the viewport may have shrunk enough to require showing the other one.
-        if (showVSB && !showHSB && hAuto && (viewport.contentWidth > viewportW))
-        {
-            showHSB = true;
-            hsbH = hsb.getPreferredBoundsHeight();                
+        // We only show the other scrollbar, if there's enough space for it.
+        if (showVSB && !showHSB && hAuto && (contentW > viewportW))
+        {
             viewportH -= Math.max(minViewportInset, hsbH);
-        }
-        else if (!showVSB && showHSB && vAuto && (viewport.contentHeight > viewportH))
-        {
-            showVSB = true;
-            vsbW = vsb.getPreferredBoundsWidth();                
+            showHSB = w >= (hsb.minWidth + vsb.minWidth); 
+        }
+        else if (!showVSB && showHSB && vAuto && (contentH > viewportH))
+        {
             viewportW -= Math.max(minViewportInset, vsbW);
+            showVSB = h >= (hsb.minHeight + vsb.minHeight);
         }
         
         // Factor in scrollBar-side viewportInsets where there aren't scrollbars
-        if (!showHSB)
-            viewportH -= minViewportInset;
-        if (!showVSB)
-            viewportW -= minViewportInset;
+        if (!showHSB) viewportH -= minViewportInset;
+        if (!showVSB) viewportW -= minViewportInset;
             
         // Special case: viewport's size is explicitly set
-        if (!isNaN(explicitViewportW))
-            viewportW = explicitViewportW;
-        if (!isNaN(explicitViewportH))
-            viewportH = explicitViewportH;
+        if (!isNaN(explicitViewportW)) viewportW = explicitViewportW;
+        if (!isNaN(explicitViewportH)) viewportH = explicitViewportH;
         
         // layout the viewport
         if (viewport)
         {
-            var viewportElt:ILayoutElement = ILayoutElement(viewport);
-            viewportElt.setLayoutBoundsSize(viewportW, viewportH);
-            viewportElt.setLayoutBoundsPosition(minViewportInset, minViewportInset);
+            viewport.setLayoutBoundsSize(viewportW, viewportH);
+            viewport.setLayoutBoundsPosition(minViewportInset, minViewportInset);
         }
         
         // layout the scrollbars
-        if (hsb) hsb.visible = showHSB;
+
+        if (hsb) hsb.includeInLayout = hsb.visible = showHSB;
         if (showHSB)
         {
-            hsb.setLayoutBoundsSize(Math.max(hsb.getMinBoundsWidth(), w - vsbW), hsbH);
+            var hsbW:Number = (showVSB) ? w - vsbW : w;
+            hsb.setLayoutBoundsSize(Math.max(hsb.getMinBoundsWidth(), hsbW), hsbH);
             hsb.setLayoutBoundsPosition(0, h - hsbH);
         }
-        if (vsb) vsb.visible = showVSB;
+        
+        if (vsb) vsb.includeInLayout = vsb.visible = showVSB;
         if (showVSB)
         {
-            vsb.setLayoutBoundsSize(vsbW, Math.max(vsb.getMinBoundsHeight(), h - hsbH));
+            var vsbH:Number = (showHSB) ? h - hsbH : h;
+            vsb.setLayoutBoundsSize(vsbW, Math.max(vsb.getMinBoundsHeight(), vsbH));
             vsb.setLayoutBoundsPosition(w - vsbW, 0);
         }
         
-        // If the scroller's size isn't explicit and we've added a scrollbar, then
-        // the measured size is likely to have been wrong.  
-        if ((isNaN(target.explicitWidth) || isNaN(target.explicitHeight)) && 
-            ((showVSB != oldShowVSB) || (showHSB != oldShowHSB)))
-            target.invalidateSize();
+        // If we've added an auto scrollbar, then the measured size is likely to have been wrong.
+        // There's a risk of looping here, so we count.  
+        if ((invalidationCount < 2) && (((showVSB != oldShowVSB) && vAuto) || ((showHSB != oldShowHSB) && hAuto)))
+        {
+            target.invalidateSize(); 
+            invalidationCount += 1; 
+        }
+        else
+            invalidationCount = 0;
              
         target.setContentSize(w, h);
     }

        var explicitViewportH:Number = viewportUIC ? viewportUIC.explicitHeight : NaN;
        
        // Decide which scrollbars will be visible based on the viewport's content size
        var showHSB:Boolean = false;
        var hAuto:Boolean = false; 
        switch(scroller.horizontalScrollPolicy) {

                if (hsb && viewport)
                {
                    hAuto = true;
                    var viewportW:Number = 
                        isNaN(explicitViewportW) ? (w - (minViewportInset * 2)) : explicitViewportW;
                    showHSB = (contentW > viewportW) && (w >= hsb.minWidth);
                } 
                break;
        } 

        var showVSB:Boolean = false;
        var vAuto:Boolean = false;
        switch(scroller.verticalScrollPolicy) {
