         // updated yet.  Making the maximum==vsp here avoids trouble later
         // when Range constrains value
         var cHeight:Number = viewport.contentHeight;
-        maximum = (cHeight == 0) ? vsp : cHeight - viewportHeight;
+        
+        if (getStyle("interactionMode") == InteractionMode.TOUCH)
+        {
+            // For mobile, we allow the min/max to extend a little beyond the ends so
+            // we can support bounce/pull kinetic effects.
+            minimum = -viewportHeight;
+            maximum = (cHeight == 0) ? vsp + viewportHeight : cHeight;
+        }
+        else
+        {
+            minimum = 0;
+            maximum = (cHeight == 0) ? vsp : cHeight - viewportHeight;
+        }
+        
         pageSize = viewportHeight;
     }
     

            }
            
            // calculate new thumb position.
            thumbPosTrackY = (pendingValue - minimum) * ((trackSize - thumbSize) / range);
        }

        if (getStyle("fixedThumbSize") === false)
            thumb.setLayoutBoundsSize(NaN, thumbSize);
        if (getStyle("autoThumbVisibility") === true)
            thumb.visible = thumbSize < trackSize;

    override mx_internal function viewportContentHeightChangeHandler(event:PropertyChangeEvent):void
    {
        if (viewport)
            updateMaximumAndPageSize();
    }
    
    /**
     *  @private 
     */
    override public function styleChanged(styleName:String):void
    {
        super.styleChanged(styleName);
        
        var allStyles:Boolean = !styleName || styleName == "styleName";
        
        if (allStyles || styleName == "interactionMode")
        {
            if (viewport)
                updateMaximumAndPageSize();
        }
    }
    
    
    /**
     *  @private
     *  Scroll vertically by event.delta "steps".  This listener is added to both the scrollbar 
