     {
         super();
     }
-    
+
+    /**
+     *  @private
+     *  Used by updateDisplayList() to prevent looping.
+     */
+    private var invalidationCount:int = 0;
+    
+    
+    /**
+     *  @private
+     */
     private function getScroller():Scroller
     {
         var g:Skin = target as Skin;

        var scroller:Scroller = getScroller();
        if (!scroller) 
            return;
        var viewport:IViewport = scroller.viewport;
        var hsb:ScrollBar = scroller.horizontalScrollBar;
        var vsb:ScrollBar = scroller.verticalScrollBar;
        var minViewportInset:Number = scroller.minViewportInset;
        
        var vsbW:Number = (vsb) ? vsb.getPreferredBoundsWidth() : 0;
        var hsbH:Number = (hsb) ? hsb.getPreferredBoundsHeight() : 0;
        
        var contentW:Number = 0;
        var contentH:Number = 0;
        if (viewport)

            contentH = contentSize.y;
        }
    
        // If the viewport's size has been explicitly set (not typical) then use it 
        var viewportUIC:IUIComponent = viewport as IUIComponent;
        var explicitViewportW:Number = viewportUIC ? viewportUIC.explicitWidth : NaN;
        var explicitViewportH:Number = viewportUIC ? viewportUIC.explicitHeight : NaN;
        
        var oldShowHSB:Boolean = hsbVisible;
        var oldShowVSB:Boolean = vsbVisible;
        
        // Decide which scrollbars will be visible based on the viewport's content size
        // and the scroller's scroll policies.

        var hAuto:Boolean = false; 
        switch(scroller.getStyle("horizontalScrollPolicy")) 
        {
            case ScrollPolicy.ON: 
                hsbVisible = true;
                break;

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

            default:
                hsbVisible = false;
        } 

        var vAuto:Boolean = false;
        switch(scroller.getStyle("verticalScrollPolicy")) 
        {
           case ScrollPolicy.ON: 
                vsbVisible = true; 
                break;

            case ScrollPolicy.AUTO: 
                if (vsb && viewport)
                { 
                    vAuto = true;
                    var viewportH:Number = 
                        isNaN(explicitViewportH) ? (h - (minViewportInset * 2)) : explicitViewportH;
                    vsbVisible = (contentH > viewportH);
                }                        
                break;

            default:
                vsbVisible = false;
        }

        // Shrink the viewport's width,height for the visible scrollbars
        
        viewportH = h - minViewportInset;
        if (hsbVisible)
            viewportH -= Math.max(minViewportInset, hsb.getPreferredBoundsHeight());
            
        viewportW = w - minViewportInset;
        if (vsbVisible)
            viewportW -= Math.max(minViewportInset, vsb.getPreferredBoundsWidth());
        
        // 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 (vsbVisible && !hsbVisible && hAuto && (contentW > viewportW))
        {
            hsbVisible = true;
            viewportH -= Math.max(minViewportInset, hsb.getPreferredBoundsHeight());
        }
        else if (!vsbVisible && hsbVisible && vAuto && (contentH > viewportH))
        {
            vsbVisible = true;
            viewportW -= Math.max(minViewportInset, vsb.getPreferredBoundsWidth());
        }

        // Factor in scrollBar-side viewportInsets where there aren't scrollbars

        if (!hsbVisible) 
            viewportH -= minViewportInset;

        if (!vsbVisible) 
            viewportW -= minViewportInset;
        
        // If the HSB doesn't fit, hide it and give the space back.   Likewise for VSB.

        if (hsbVisible && !hsbFits(w, h))
        {
            viewportH += Math.max(minViewportInset, hsb.getPreferredBoundsHeight());
            hsbVisible = false;
        }

        if (vsbVisible && !vsbFits(w, h))
        {
            viewportW += Math.max(minViewportInset, vsb.getPreferredBoundsWidth());
            vsbVisible = false;
        }
        
        // Special case: viewport's size is explicitly set

        if (!isNaN(explicitViewportW)) 
            viewportW = explicitViewportW;

        if (!isNaN(explicitViewportH)) 
            viewportH = explicitViewportH;
        
        // Layout the viewport scrollbars.

        if (viewport)
        {
            viewport.setLayoutBoundsSize(viewportW, viewportH);
            viewport.setLayoutBoundsPosition(minViewportInset, minViewportInset);
        }
        
        if (hsbVisible)
        {
            var hsbW:Number = (vsbVisible) ? w - vsb.getPreferredBoundsWidth() : w;
            var hsbH:Number = hsb.getPreferredBoundsHeight();
            hsb.setLayoutBoundsSize(Math.max(hsb.getMinBoundsWidth(), hsbW), hsbH);
            hsb.setLayoutBoundsPosition(0, h - hsbH);
        }

        if (vsbVisible)
        {
            var vsbW:Number = vsb.getPreferredBoundsWidth(); 
            var vsbH:Number = (hsbVisible) ? h - hsb.getPreferredBoundsHeight() : h;
            vsb.setLayoutBoundsSize(vsbW, Math.max(vsb.getMinBoundsHeight(), vsbH));
            vsb.setLayoutBoundsPosition(w - vsbW, 0);
        }

        // 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) && (((vsbVisible != oldShowVSB) && vAuto) || ((hsbVisible != oldShowHSB) && hAuto)))
        {
            target.invalidateSize(); 
            invalidationCount += 1; 
