////////////////////////////////////////////////////////////////////////////////
//
//  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.
//
////////////////////////////////////////////////////////////////////////////////


package spark.components
{
import flash.display.DisplayObject;
import flash.events.Event;
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.events.SoftKeyboardEvent;
import flash.events.TimerEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.system.Capabilities;
import flash.text.TextField;
import flash.ui.Keyboard;
import flash.utils.Timer;

import mx.core.EventPriority;
import mx.core.FlexGlobals;
import mx.core.IFactory;
import mx.core.IInvalidating;
import mx.core.IVisualElement;
import mx.core.IVisualElementContainer;
import mx.core.InteractionMode;
import mx.core.LayoutDirection;
import mx.core.UIComponent;
import mx.core.mx_internal;
import mx.events.EffectEvent;
import mx.events.FlexEvent;
import mx.events.FlexMouseEvent;
import mx.events.PropertyChangeEvent;
import mx.events.TouchInteractionEvent;
import mx.managers.IFocusManager;
import mx.managers.IFocusManagerComponent;
import mx.styles.IStyleClient;

import spark.components.supportClasses.GroupBase;
import spark.components.supportClasses.ScrollerLayout;
import spark.components.supportClasses.SkinnableComponent;
import spark.components.supportClasses.TouchScrollHelper;
import spark.core.IGraphicElement;
import spark.core.IViewport;
import spark.core.NavigationUnit;
import spark.effects.Animate;
import spark.effects.ThrowEffect;
import spark.effects.animation.MotionPath;
import spark.effects.animation.SimpleMotionPath;
import spark.events.CaretBoundsChangeEvent;
import spark.layouts.supportClasses.LayoutBase;
import spark.utils.MouseEventUtil;

use namespace mx_internal;

include "../styles/metadata/BasicInheritingTextStyles.as"
include "../styles/metadata/AdvancedInheritingTextStyles.as"
include "../styles/metadata/SelectionFormatTextStyles.as"

//--------------------------------------
//  Events
//--------------------------------------

/**
 *  Dispatched when the scroll position is going to change due to a 
 *  <code>mouseWheel</code> event.
 *  
 *  <p>If there is a visible verticalScrollBar, then by default
 *  the viewport is scrolled vertically by <code>event.delta</code> "steps".
 *  The height of the step is determined by the viewport's 
 *  <code>getVerticalScrollPositionDelta</code> method using 
 *  either <code>UP</code> or <code>DOWN</code>, depending on the scroll 
 *  direction.</p>
 *
 *  <p>Otherwise, if there is a visible horizontalScrollBar, then by default
 *  the viewport is scrolled horizontally by <code>event.delta</code> "steps".
 *  The width of the step is determined by the viewport's 
 *  <code>getHorizontalScrollPositionDelta</code> method using 
 *  either <code>LEFT</code> or <code>RIGHT</code>, depending on the scroll 
 *  direction.</p>
 *
 *  <p>Calling the <code>preventDefault()</code> method
 *  on the event prevents the scroll position from changing.
 *  Otherwise if you modify the <code>delta</code> property of the event,
 *  that value will be used as the number of "steps".</p>
 *
 *  @eventType mx.events.FlexMouseEvent.MOUSE_WHEEL_CHANGING
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 2.5
 *  @productversion Flex 4.5
 */
[Event(name="mouseWheelChanging", type="mx.events.FlexMouseEvent")]

//--------------------------------------
//  Styles
//--------------------------------------

/**
 *  @copy spark.components.supportClasses.GroupBase#style:alternatingItemColors
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
[Style(name="alternatingItemColors", type="Array", arrayType="uint", format="Color", inherit="yes", theme="spark, mobile")]

/**
 *  The alpha of the content background for this component.
 * 
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
[Style(name="contentBackgroundAlpha", type="Number", inherit="yes", theme="spark, mobile")]

/**
 *  @copy spark.components.supportClasses.GroupBase#style:contentBackgroundColor
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */ 
[Style(name="contentBackgroundColor", type="uint", format="Color", inherit="yes", theme="spark, mobile")]

/**
 *  @copy spark.components.supportClasses.GroupBase#style:downColor
 *   
 *  @langversion 3.0
 *  @playerversion Flash 10.1
 *  @playerversion AIR 2.5
 *  @productversion Flex 4.5
 */
[Style(name="downColor", type="uint", format="Color", inherit="yes", theme="mobile")]

/**
 *  @copy spark.components.supportClasses.GroupBase#style:focusColor
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */ 
[Style(name="focusColor", type="uint", format="Color", inherit="yes", theme="spark, mobile")]

/**
 *  Indicates under what conditions the horizontal scroll bar is displayed.
 * 
 *  <ul>
 *  <li>
 *  <code>ScrollPolicy.ON</code> ("on") - the scroll bar is always displayed.
 *  </li> 
 *  <li>
 *  <code>ScrollPolicy.OFF</code> ("off") - the scroll bar is never displayed.
 *  The viewport can still be scrolled programmatically, by setting its
 *  horizontalScrollPosition property.
 *  </li>
 *  <li>
 *  <code>ScrollPolicy.AUTO</code> ("auto") - the scroll bar is displayed when 
 *  the viewport's contentWidth is larger than its width.
 *  </li>
 *  </ul>
 * 
 *  <p>
 *  The scroll policy affects the measured size of the Scroller component.
 *  </p>
 * 
 *  @default ScrollPolicy.AUTO
 *
 *  @see mx.core.ScrollPolicy
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */ 
[Style(name="horizontalScrollPolicy", type="String", inherit="no", enumeration="off,on,auto")]

/**
 *  A proxy for the <code>liveDragging</code> style of the scrollbars 
 *  used by the Scroller component.   
 * 
 *  <p>If this style is set to <code>true</code>, then the 
 *  <code>liveDragging</code> styles are set to <code>true</code> (the default).
 *  That means dragging a scrollbar thumb immediately updates the viewport's scroll position.
 *  If this style is set to <code>false</code>, then the <code>liveDragging</code> styles 
 *  are set to <code>false</code>.
 *  That means when a scrollbar thumb is dragged the viewport's scroll position is only updated 
 *  then the mouse button is released.</p>
 * 
 *  <p>Setting this style to <code>false</code> can be helpful 
 *  when updating the viewport's display is so 
 *  expensive that "liveDragging" performs poorly.</p> 
 *  
 *  <p>By default this style is <code>undefined</code>, which means that 
 *  the <code>liveDragging</code> styles are not modified.</p>
 * 
 *  @default undefined
 * 
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
[Style(name="liveScrolling", type="Boolean", inherit="no")]

/**
 *  @copy spark.components.supportClasses.GroupBase#style:rollOverColor
 *   
 *  @default 0xCEDBEF
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
[Style(name="rollOverColor", type="uint", format="Color", inherit="yes", theme="spark")]

/**
 *  @copy spark.components.supportClasses.GroupBase#style:symbolColor
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */ 
[Style(name="symbolColor", type="uint", format="Color", inherit="yes", theme="spark, mobile")]

/**
 *  @copy spark.components.supportClasses.GroupBase#style:touchDelay
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10.1
 *  @playerversion AIR 2.5
 *  @productversion Flex 4.5
 */
[Style(name="touchDelay", type="Number", format="Time", inherit="yes", minValue="0.0")]

/**
 *  Indicates under what conditions the vertical scroll bar is displayed.
 * 
 *  <ul>
 *  <li>
 *  <code>ScrollPolicy.ON</code> ("on") - the scroll bar is always displayed.
 *  </li> 
 *  <li>
 *  <code>ScrollPolicy.OFF</code> ("off") - the scroll bar is never displayed.
 *  The viewport can still be scrolled programmatically, by setting its
 *  verticalScrollPosition property.
 *  </li>
 *  <li>
 *  <code>ScrollPolicy.AUTO</code> ("auto") - the scroll bar is displayed when 
 *  the viewport's contentHeight is larger than its height.
 *  </li>
 *  </ul>
 * 
 *  <p>
 *  The scroll policy affects the measured size of the Scroller component.
 *  </p>
 * 
 *  @default ScrollPolicy.AUTO
 *
 *  @see mx.core.ScrollPolicy
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
     */ 
[Style(name="verticalScrollPolicy", type="String", inherit="no", enumeration="off,on,auto")]


//--------------------------------------
//  Other metadata
//--------------------------------------

[ResourceBundle("components")]
    
[DefaultProperty("viewport")]

[IconFile("Scroller.png")]

/**
 *  The Scroller component displays a single scrollable component, 
 *  called a viewport, and horizontal and vertical scroll bars. 
 *  The viewport must implement the IViewport interface.  Its skin
 *  must be a derivative of the Group class.
 *
 *  <p>The Spark Group, DataGroup, and RichEditableText components implement 
 *  the IViewport interface and can be used as the children of the Scroller control,
 *  as the following example shows:</p>
 * 
 *  <pre>
 *  &lt;s:Scroller width="100" height="100"&gt;
 *       &lt;s:Group&gt; 
 *          &lt;mx:Image width="300" height="400" 
 *               source="&#64;Embed(source='assets/logo.jpg')"/&gt; 
 *       &lt;/s:Group&gt;        
 *  &lt;/s:Scroller&gt;</pre>     
 *
 *  <p>The size of the Image control is set larger than that of its parent Group container. 
 *  By default, the child extends past the boundaries of the parent container. 
 *  Rather than allow the child to extend past the boundaries of the parent container, 
 *  the Scroller specifies to clip the child to the boundaries and display scroll bars.</p>
 *
 *  <p>Not all Spark containers implement the IViewPort interface. 
 *  Therefore, those containers, such as the BorderContainer and SkinnableContainer containers, 
 *  cannot be used as the direct child of the Scroller component.
 *  However, all Spark containers can have a Scroller component as a child component. 
 *  For example, to use scroll bars on a child of the Spark BorderContainer, 
 *  wrap the child in a Scroller component. </p>
 *
 *  <p>To make the entire BorderContainer scrollable, wrap it in a Group container. 
 *  Then, make the Group container the child of the Scroller component,
 *  For skinnable Spark containers that do not implement the IViewport interface, 
 *  you can also create a custom skin for the container that 
 *  includes the Scroller component. </p>
 * 
 *  <p>The IViewport interface defines a viewport for the components that implement it.
 *  A viewport is a rectangular subset of the area of a container that you want to display, 
 *  rather than displaying the entire container.
 *  The scroll bars control the viewport's <code>horizontalScrollPosition</code> and
 *  <code>verticalScrollPosition</code> properties.
 *  scroll bars make it possible to view the area defined by the viewport's 
 *  <code>contentWidth</code> and <code>contentHeight</code> properties.</p>
 *
 *  <p>You can directly set properties on the component wrapped by the Scroller by 
 *  using the <code>Scroller.viewport</code> property. 
 *  For example, you can modify the viewport's <code>horizontalScrollPosition</code> and
 *  <code>verticalScrollPosition</code> properties.</p>
 *
 *  <p>To directly access the scroll bar instances, either HScrollBar or VScrollBar, 
 *  created by the Scroller, use the <code>Scroller.horizontalScrollBar</code> and
 *  <code>Scroller.verticalScrollBar</code> properties.</p>
 *
 *  <p>You can combine scroll bars with explicit settings for the container's viewport. 
 *  The viewport settings determine the initial position of the viewport, 
 *  and then you can use the scroll bars to move it, as the following example shows: </p>
 *  
 *  <pre>
 *  &lt;s:Scroller width="100" height="100"&gt;
 *      &lt;s:Group
 *          horizontalScrollPosition="50" verticalScrollPosition="50"&gt; 
 *          &lt;mx:Image width="300" height="400" 
 *              source="&#64;Embed(source='assets/logo.jpg')"/&gt; 
 *      &lt;/s:Group&gt;                 
 *  &lt;/s:Scroller&gt;</pre>
 * 
 *  <p>The scroll bars are displayed according to the vertical and horizontal scroll bar
 *  policy, which can be <code>auto</code>, <code>on</code>, or <code>off</code>.
 *  The <code>auto</code> policy means that the scroll bar will be visible and included
 *  in the layout when the viewport's content is larger than the viewport itself.</p>
 * 
 *  <p>The Scroller skin layout cannot be changed. It is unconditionally set to a 
 *  private layout implementation that handles the scroll policies.  Scroller skins
 *  can only provide replacement scroll bars.  To gain more control over the layout
 *  of a viewport and its scroll bars, instead of using Scroller, just add them 
 *  to a <code>Group</code> and use the scroll bar <code>viewport</code> property 
 *  to link them together.</p>
 *
 *  <p>The Scroller control has the following default characteristics:</p>
 *     <table class="innertable">
 *        <tr>
 *           <th>Characteristic</th>
 *           <th>Description</th>
 *        </tr>
 *        <tr>
 *           <td>Default size</td>
 *           <td>0</td>
 *        </tr>
 *        <tr>
 *           <td>Minimum size</td>
 *           <td>0</td>
 *        </tr>
 *        <tr>
 *           <td>Maximum size</td>
 *           <td>10000 pixels wide and 10000 pixels high</td>
 *        </tr>
 *        <tr>
 *           <td>Default skin class</td>
 *           <td>spark.skins.spark.ScrollerSkin</td>
 *        </tr>
 *     </table>
 *
 *  @mxml
 *
 *  <p>The <code>&lt;s:Scroller&gt;</code> tag inherits all of the tag 
 *  attributes of its superclass and adds the following tag attributes:</p>
 *
 *  <pre>
 *  &lt;s:Scroller
 *   <strong>Properties</strong>
 *    measuredSizeIncludesScrollBars="true"
 *    minViewportInset="0"
 *    pageScrollingEnabled="false"
 *    scrollSnappingMode="none"
 *    viewport="null"
 *  
 *    <strong>Styles</strong>
 *    alignmentBaseline="use_dominant_baseline"
 *    alternatingItemColors=""
 *    baselineShift="0.0"
 *    blockProgression="TB"
 *    breakOpportunity="auto"
 *    cffHinting="horizontal_stem"
 *    clearFloats="none"
 *    color="0"
 *    contentBackgroundAlpha=""
 *    contentBackgroundColor=""
 *    digitCase="default"
 *    digitWidth="default"
 *    direction="LTR"
 *    dominantBaseline="auto"
 *    downColor=""
 *    firstBaselineOffset="auto"
 *    focusColor=""
 *    focusedTextSelectionColor=""
 *    fontFamily="Arial"
 *    fontLookup="device"
 *    fontSize="12"
 *    fontStyle="normal"
 *    fontWeight="normal"
 *    horizontalScrollPolicy="auto"
 *    inactiveTextSelection=""
 *    justificationRule="auto"
 *    justificationStyle="auto"
 *    kerning="auto"
 *    leadingModel="auto"
 *    ligatureLevel="common"
 *    lineHeight="120%"
 *    lineThrough="false"
 *    listAutoPadding="40"
 *    listStylePosition="outside"
 *    listStyleType="disc"
 *    locale="en"
 *    paragraphEndIndent="0"
 *    paragraphSpaceAfter="0"
 *    paragraphSpaceBefore="0"
 *    paragraphStartIndent="0"
 *    renderingMode="CFF"
 *    rollOverColor=""
 *    symbolColor=""
 *    tabStops="null"
 *    textAlign="start"
 *    textAlignLast="start"
 *    textAlpha="1"
 *    textDecoration="none"
 *    textIndent="0"
 *    textJustify="inter_word"
 *    textRotation="auto"
 *    trackingLeft="0"
 *    trackingRight="0"
 *    typographicCase="default"
 *    unfocusedTextSelectionColor=""
 *    verticalScrollPolicy="auto"
 *    whiteSpaceCollapse="collapse"
 *    wordSpacing="100%,50%,150%"
 *  /&gt;
 *  </pre>
 *  
 *  @see spark.core.IViewport
 *  @see spark.components.DataGroup
 *  @see spark.components.Group
 *  @see spark.components.RichEditableText
 *  @see spark.skins.spark.ScrollerSkin
 *
 *  @includeExample examples/ScrollerExample.mxml
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */

public class Scroller extends SkinnableComponent 
       implements IFocusManagerComponent, IVisualElementContainer
{
    include "../core/Version.as";
    
    //--------------------------------------------------------------------------
    //
    //  Class constants
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     *  The ratio that determines how far the list scrolls when pulled past its end.
     */
    private static const PULL_TENSION_RATIO:Number = 0.5;
    
    /**
     *  @private
     *  Used so we don't have to keep allocating Point(0,0) to do coordinate conversions
     *  while draggingg
     */
    private static const ZERO_POINT:Point = new Point(0,0); 
    
    /**
     *  @private
     *  The name of the viewport's horizontal scroll position property
     */
    private static const HORIZONTAL_SCROLL_POSITION:String = "horizontalScrollPosition";
    
    /**
     *  @private
     *  The name of the viewport's vertical scroll position property
     */
    private static const VERTICAL_SCROLL_POSITION:String = "verticalScrollPosition";

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------
    
    /**
     *  Constructor.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function Scroller()
    {
        super();
        hasFocusableChildren = true;
        focusEnabled = false;

        addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
        addEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);
    }
    
    //--------------------------------------------------------------------------
    //
    //  Variables: Touch Scrolling
    //
    //--------------------------------------------------------------------------    
    
    /**
     *  @private
     *  Threshold for screen distance they must move to count as a scroll
     *  Based on 20 pixels on a 252ppi device.
     */
    mx_internal var minSlopInches:Number = 0.079365; // 20.0/252.0
    
    /**
     *  @private
     *  The amount of deceleration to apply to the velocity for each effect period
     *  For a faster deceleration, you can switch this to 0.990.
     */
    mx_internal var throwEffectDecelFactor:Number = 0.998;
    
    /**
     *  @private
     *  When pageScrollingEnabled is true, this var specifies the minimum distance 
     *  (as a percentage of the viewport size) that the content needs to be dragged 
     *  in order to switch to an adjacent page. 
     */
    mx_internal var pageDragDistanceThreshold:Number = 0.5;
    
    /**
     *  @private
     *  When pageScrollingEnabled is true, this var specifies the minimum velocity 
     *  (in inches/second) that a throw needs in order to switch to an adjacent page. 
     */
    mx_internal var pageThrowVelocityThreshold:Number = 0.8;  
    
    /**
     *  @private
     */
    private var scrollRangesChanged:Boolean = false;
    
    /**
     *  @private
     */
    private var pageScrollingChanged:Boolean = false;
    
    /**
     *  @private
     */
    private var snappingModeChanged:Boolean = false;

    /**
     *  @private
     */
    private var _pullEnabled:Boolean = true;

    /**
     *  @private
     */
    mx_internal function get pullEnabled():Boolean
    {
        return _pullEnabled;    
    }
    
    /**
     *  @private
     */
    mx_internal function set pullEnabled(value:Boolean):void
    {
		if (_pullEnabled == value)
			return;
		
        _pullEnabled = value;
        scrollRangesChanged = true;
        invalidateProperties();
    }

    /**
     *  @private
     */
    private var _bounceEnabled:Boolean = true;

    /**
     *  @private
     */
    mx_internal function get bounceEnabled():Boolean
    {
        return _bounceEnabled;    
    }
    
    /**
     *  @private
     */
    mx_internal function set bounceEnabled(value:Boolean):void
    {
		if (_bounceEnabled == value)
			return;
		
        _bounceEnabled = value;
        scrollRangesChanged = true;
        invalidateProperties();
    }
    
    
    /**
     *  @private
     *  Touch Scroll Helper -- used to help figure out 
     *  scrolling velocity and other information
     */
    private var touchScrollHelper:TouchScrollHelper;
    
    /**
     *  @private
     *  Keeps track of the horizontal scroll position
     *  before scrolling started, so we can figure out 
     *  how to related it to the dragX that are 
     *  associated with the touchScrollDrag events.
     */
    private var hspBeforeTouchScroll:Number;
    
    /**
     *  @private
     *  Keeps track of the vertical scroll position
     *  before scrolling started, so we can figure out 
     *  how to related it to the dragY that are 
     *  associated with the touchScrollDrag events.
     */
    private var vspBeforeTouchScroll:Number;
    
    /**
     *  @private
     *  Effect used for touch scroll throwing
     */
    mx_internal var throwEffect:ThrowEffect;
    
    /**
     *  @private
     *  The final position in the throw effect's vertical motion path
     */
    private var throwFinalVSP:Number;
    
    /**
     *  @private
     *  The final position in the throw effect's horizontal motion path
     */
    private var throwFinalHSP:Number;

    /**
     *  @private
     *  Indicates whether the previous throw reached one of the maximum
     *  scroll positions (vsp or hsp) that was in effect at the time. 
     */
    private var throwReachedMaximumScrollPosition:Boolean;
    
    /**
     *  @private
     *  Used to keep track of whether the throw animation 
     *  was stopped pre-emptively.  We stop propogation of 
     *  the mouse event, but in the throwEffect.EFFECT_END
     *  event handler, we need to tell it not to exit the
     *  scrolling state.
     */
    private var stoppedPreemptively:Boolean = false;
    
    /**
     *  @private
     *  Used to keep track of whether we should capture the next 
     *  click event that we receive or whether we should let it dispatch 
     *  normally.  We capture the click event if a scroll happened.  We 
     *  set this property in mouseDown and touchScrollStart.
     */
    private var captureNextClick:Boolean = false;
    
    /**
     *  @private
     *  Used to keep track of whether we should capture the next 
     *  mousedown event that we receive or whether we should let it dispatch 
     *  normally.  We capture the mousedown event if a scroll-throw is 
     *  currently happening.  We set this property in mouseDown, touchInteractionStart, 
     *  and touchInteractionEnd.
     */
    private var captureNextMouseDown:Boolean = false;
    
    /**
     *  @private
     *  Animation to fade the scrollbars out when we are done
     *  throwing or dragging
     */
    private var hideScrollBarAnimation:Animate;
    
    /**
     *  @private
     *  Use to figure out whether the animation ended naturally and finished or 
     *  whether we called stop() on it.  Unfortunately, we get an EFFECT_END in 
     *  both cases, so we must keep track of it ourselves.
     */
    private var hideScrollBarAnimationPrematurelyStopped:Boolean;
    
    /**
     *  @private
     *  Keeps track of whether a touch interaction is in progress. 
     */
    mx_internal var inTouchInteraction:Boolean = false;
    
    
    /**
     *  @private
     *  These are the minimum and maximum scroll possitions allowed
     *  for both axes.  They determine the points at which bounce and
     *  pull occur.
     */
    private var minVerticalScrollPosition:Number = 0;
    private var maxVerticalScrollPosition:Number = 0;
    private var minHorizontalScrollPosition:Number = 0;
    private var maxHorizontalScrollPosition:Number = 0;
    
    /**
     *  @private
     *  The animation used by the snapElement function.
     */
    private var snapElementAnimation:Animate;

    /**
     *  @private
     *  When pageScrollingEnabled is true, this contains the 
     *  scroll position of the current page.
     */
    private var currentPageScrollPosition:Number;
    

    /**
     *  @private
     *  Keeps track of the most recently snapped item, or -1 if none.
     *  This value is set as a side-effect of calling getSnappedPosition. 
     */
    private var lastSnappedElement:int = -1;

    /**
     *  @private
     *  Remembers which part of the content is snapped at the
     *  time an orientation change begins.  For paging without
     *  item snapping, this value is a page number.  For item
     *  snapping, the value is an element number. 
     */
    private var orientationChangeSnapElement:int = -1;
    
    /**
     *  @private
     *  Remembers the number of pages right before an orientation
     *  change occurs.
     */
    private var previousOrientationPageCount:int = 0;

    

    //--------------------------------------------------------------------------
    //
    //  Variables: SoftKeyboard Support
    //
    //--------------------------------------------------------------------------  
    
    /**
     *  @private
     * 
     *  Some devices do not support a hardware keyboard. 
     *  Instead, these devices use a keyboard that opens on 
     *  the screen when necessary. 
     *  A value of <code>true</code> means that when a component in 
     *  the container wrapped by the scroller receives focus, 
     *  the Scroller scrolls that component into view if the keyboard is 
     *  opening
     */    
    mx_internal var ensureElementIsVisibleForSoftKeyboard:Boolean = true;
    
    /**
     *  @private 
     */ 
    private var lastFocusedElement:IVisualElement;
    
    /**
     *  @private 
     *  Used to detect when the device orientation (landscape/portrait) has changed
     */
    private var aspectRatio:String;
    
    /**
     *  @private 
     */
    private var oldSoftKeyboardHeight:Number = NaN;
    
    /**
     *  @private 
     */
    private var oldSoftKeyboardWidth:Number = NaN;
    
    /**
     *  @private 
     */
    mx_internal var preventThrows:Boolean = false;
    
    /**
     *  @private 
     */
    private var lastFocusedElementCaretBounds:Rectangle;
    
    /**
     *  @private 
     */
    private var captureNextCaretBoundsChange:Boolean = false;
    
    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------
    
    //----------------------------------
    //  horizontalScrollBar
    //---------------------------------- 
    
    [SkinPart(required="false")]
    [Bindable]    

    /**
     *  A skin part that defines the horizontal scroll bar.
     * 
     *  This property should be considered read-only. It is only
     *  set by the Scroller's skin.
     * 
     *  This property is Bindable.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public var horizontalScrollBar:HScrollBar;
    
    //----------------------------------
    //  horizontalScrollBarFactory
    //---------------------------------- 
    
    [SkinPart(required="false", type="spark.components.HScrollBar")]
    
    /**
     *  A skin part that defines the horizontal scroll bar component.
     * 
     *  The <code>horizontalScrollBar</code> skin part takes precedence over this
     *  skin part.
     * 
     *  When Scroller creates an instance of this part, it will set the
     *  <code>horizontalScrollBar</code> skin part to that instance.
     * 
     *  This property should be considered read-only. It is only
     *  set by the Scroller's skin.
     *  To access the HScrollBar instance, use <code>horizontalScrollBar</code>.
     */
    public var horizontalScrollBarFactory:IFactory;
    
    /**
     *  Creates the horizontalScrollBar part from the horizontalScrollBarFactory part. 
     */
    private function ensureDeferredHScrollBarCreated():void
    {
        if (!horizontalScrollBar && horizontalScrollBarFactory)
        {
            horizontalScrollBar = HScrollBar(createDynamicPartInstance("horizontalScrollBarFactory"));
            Group(this.skin).addElement(horizontalScrollBar);
            partAdded("horizontalScrollBar", horizontalScrollBar);
        }
    }
    
    //----------------------------------
    //  horizontalScrollInProgress
    //---------------------------------- 

    /**
     *  Storage for the horizontalScrollInProgress property  
     */
    private var _horizontalScrollInProgress:Boolean = false;
    
    /**
     *  @private
     *  Property used to communicate with ScrollerLayout to let it 
     *  know when a horizontal scroll is in progress or not (and when 
     *  the horizontal scroll bar should be hidden or not)
     */
    mx_internal function get horizontalScrollInProgress():Boolean
    {
        return _horizontalScrollInProgress;
    }
    
    /**
     *  @private 
     */
    mx_internal function set horizontalScrollInProgress(value:Boolean):void
    {
        _horizontalScrollInProgress = value;
        if (value && getStyle("interactionMode") == InteractionMode.TOUCH)
            ensureDeferredHScrollBarCreated();
    }

    //----------------------------------
    //  verticalScrollBar
    //---------------------------------- 
    
    [SkinPart(required="false")]
    [Bindable]
    
    /**
     *  A skin part that defines the vertical scroll bar.
     * 
     *  This property should be considered read-only. It is only
     *  set by the Scroller's skin.
     * 
     *  This property is Bindable.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public var verticalScrollBar:VScrollBar;

    //----------------------------------
    //  verticalScrollBarFactory
    //---------------------------------- 
    
    [SkinPart(required="false", type="spark.components.VScrollBar")]
    
    /**
     *  A skin part that defines the vertical scroll bar.
     * 
     *  The <code>verticalScrollBar</code> skin part takes precedence over this
     *  skin part.
     * 
     *  When Scroller creates an instance of this part, it will set the
     *  <code>verticalScrollBar</code> skin part to that instance.
     *
     *  This property should be considered read-only. It is only
     *  set by the Scroller's skin. 
     *  To access the VScrollBar instance, use <code>verticalScrollBar</code>.
     */
    public var verticalScrollBarFactory:IFactory;
    
    /**
     *  Creates the verticalScrollBar part from the verticalScrollBarFactory part. 
     */
    private function ensureDeferredVScrollBarCreated():void
    {
        if (!verticalScrollBar && verticalScrollBarFactory)
        {
            verticalScrollBar = VScrollBar(createDynamicPartInstance("verticalScrollBarFactory"));
            Group(this.skin).addElement(verticalScrollBar);
            partAdded("verticalScrollBar", verticalScrollBar);
        }
    }
    
    //----------------------------------
    //  verticalScrollInProgress
    //---------------------------------- 
    
    /**
     *  Storage for the verticalScrollInProgress property  
     */
    private var _verticalScrollInProgress:Boolean = false;
    
    /**
     *  @private
     *  Property used to communicate with ScrollerLayout to let it 
     *  know when a vertical scroll is in progress or not (and when 
     *  the vertical scroll bar should be hidden or not)
     */
    mx_internal function get verticalScrollInProgress():Boolean
    {
        return _verticalScrollInProgress;
    }
    
    /**
     *  @private 
     */
    mx_internal function set verticalScrollInProgress(value:Boolean):void
    {
        _verticalScrollInProgress = value;
        if (value && getStyle("interactionMode") == InteractionMode.TOUCH)
            ensureDeferredVScrollBarCreated();
    }

    //----------------------------------
    //  viewport - default property
    //----------------------------------    
    
    private var _viewport:IViewport;
    
    [Bindable(event="viewportChanged")]
    
    /**
     *  The viewport component to be scrolled.
     * 
     *  <p>
     *  The viewport is added to the Scroller component's skin, 
     *  which lays out both the viewport and scroll bars.
     * 
     *  When the <code>viewport</code> property is set, the viewport's 
     *  <code>clipAndEnableScrolling</code> property is 
     *  set to true to enable scrolling.
     * 
     *  The Scroller does not support rotating the viewport directly.  The viewport's
     *  contents can be transformed arbitrarily, but the viewport itself cannot.
     * </p>
     * 
     *  This property is Bindable.
     * 
     *  @default null
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get viewport():IViewport
    {       
        return _viewport;
    }
    
    /**
     *  @private
     */
    public function set viewport(value:IViewport):void
    {
        if (value == _viewport)
            return;
        
        uninstallViewport();
        _viewport = value;
        installViewport();
        dispatchEvent(new Event("viewportChanged"));
    }
    
    /**
     *  @private
     *  This is used to disable thinning for automated testing.
     */
    mx_internal static var dragEventThinning:Boolean = true;
    
    private function installViewport():void
    {
        if (skin && viewport)
        {
            viewport.clipAndEnableScrolling = true;
            Group(skin).addElementAt(viewport, 0);
            viewport.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, viewport_propertyChangeHandler);
            viewport.addEventListener(Event.RESIZE, viewport_resizeHandler);
        }
        if (verticalScrollBar)
            verticalScrollBar.viewport = viewport;
        if (horizontalScrollBar)
            horizontalScrollBar.viewport = viewport;
    }
    
    private function uninstallViewport():void
    {
        if (horizontalScrollBar)
            horizontalScrollBar.viewport = null;
        if (verticalScrollBar)
            verticalScrollBar.viewport = null;        
        if (skin && viewport)
        {
            viewport.clipAndEnableScrolling = false;
            Group(skin).removeElement(viewport);
            viewport.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE, viewport_propertyChangeHandler);
            viewport.removeEventListener(Event.RESIZE, viewport_resizeHandler);
        }
    }
    
    
    //----------------------------------
    //  minViewportInset
    //----------------------------------

    private var _minViewportInset:Number = 0;
    
    [Inspectable(category="General", defaultValue="0")]

    /**
     *  The minimum space between the viewport and the edges of the Scroller.  
     * 
     *  If neither of the scroll bars is visible, then the viewport is inset by 
     *  <code>minViewportInset</code> on all four sides.
     * 
     *  If a scroll bar is visible then the viewport is inset by <code>minViewportInset</code>
     *  or by the scroll bar's size, whichever is larger.
     * 
     *  ScrollBars are laid out flush with the edges of the Scroller.   
     * 
     *  @default 0 
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function get minViewportInset():Number
    {
        return _minViewportInset;
    }

    /**
     *  @private
     */
    public function set minViewportInset(value:Number):void
    {
        if (value == _minViewportInset)
            return;
            
        _minViewportInset = value;
        invalidateSkin();
    }

    //----------------------------------
    //  measuredSizeIncludesScrollBars
    //----------------------------------
    
    private var _measuredSizeIncludesScrollBars:Boolean = true;
    
    [Inspectable(category="General", defaultValue="true")]
    
    /**
     *  If <code>true</code>, the Scroller's measured size includes the space required for
     *  the visible scroll bars, otherwise the Scroller's measured size depends
     *  only on its viewport.
     * 
     *  <p>Components like TextArea, which "reflow" their contents to fit the
     *  available width or height may use this property to stabilize their
     *  measured size.  By default a TextArea's is defined by its <code>widthInChars</code>
     *  and <code>heightInChars</code> properties and in many applications it's preferable
     *  for the measured size to remain constant, event when scroll bars are displayed
     *  by the TextArea skin's Scroller.</p>
     * 
     *  <p>In components where the content does not reflow, like a typical List's
     *  items, the default behavior is preferable because it makes it less
     *  likely that the component's content will be obscured by a scroll bar.</p>
     * 
     *  @default true
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function get measuredSizeIncludesScrollBars():Boolean
    {
        return _measuredSizeIncludesScrollBars;
    }
    
    /**
     *  @private 
     */
    public function set measuredSizeIncludesScrollBars(value:Boolean):void
    {
        if (value == _measuredSizeIncludesScrollBars)
            return;

        _measuredSizeIncludesScrollBars = value;
        invalidateSkin();
    }

    //----------------------------------
    //  pageScrollingEnabled
    //----------------------------------

    private var _pageScrollingEnabled:Boolean = false;
    
    [Inspectable(category="General", defaultValue="false")]
    
    /**
     *  By default, for mobile applications, scrolling is pixel based. 
     *  The final scroll location is any pixel location based on 
     *  the drag and throw gesture.
     *  Set <code>pageScrollingEnabled</code> to <code>true</code> to 
     *  enable page scrolling.
     *
     *  <p><b>Note: </b>This property is only valid when the <code>interactionMode</code> style 
     *  is set to <code>touch</code>, indicating a mobile application.</p>
     *
     *  <p>The size of the page is determined by the size of the viewport 
     *  of the scrollable component. 
     *  You can only scroll a single page at a time, regardless of the scroll gesture.</p>
     *
     *  <p>You must scroll at least 50% of the visible area of the component 
     *  to cause the page to change. 
     *  If you scroll less than 50%, the component remains on the current page. 
     *  Alternatively, if the velocity of the scroll is high enough, the next page display. 
     *  If the velocity is not high enough, the component remains on the current page.</p>
     *
     *  @default false
     *
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    public function get pageScrollingEnabled():Boolean
    {
        return _pageScrollingEnabled;
    }

    /**
     *  @private 
     */
    public function set pageScrollingEnabled(value:Boolean):void
    {
        if (value == _pageScrollingEnabled)
            return;
        
        _pageScrollingEnabled = value;
        if (getStyle("interactionMode") == InteractionMode.TOUCH)
        {
            if (canScrollHorizontally && canScrollVertically)
                throw new Error(resourceManager.getString("components", "operationSupportedForOneAxisOnly"));
            
            scrollRangesChanged = true;
            pageScrollingChanged = true;
            invalidateProperties();
        }
    }
 
    //----------------------------------
    //  scrollSnappingMode
    //----------------------------------
    
    private var _scrollSnappingMode:String = ScrollSnappingMode.NONE; 

    [Inspectable(category="General", enumeration="none,leadingEdge,center,trailingEdge", defaultValue="none")]

    /**
     *  By default, for mobile applications, scrolling is pixel based. 
     *  The final scroll location is any pixel location based on 
     *  the drag and throw gesture.
     *  Set <code>scrollSnappingMode</code> to other than <code>none</code> to 
     *  enable scroll snapping.
     *  With scroll snapping enabled, 
	 *  the content snaps to a final position based on the value of <code>scrollSnappingMode</code>.
     *
     *  <p><b>Note: </b>This property is only valid when the <code>interactionMode</code> style 
     *  is set to <code>touch</code>, indicating a mobile application.</p>
     *
     *  <p>For example, you scroll a List vertically with <code>scrollSnappingMode</code> 
     *  set to a value of <code>leadingEdge</code>. 
     *  The List control snaps to a final scroll position where the top list element 
     *  is aligned to the top of the list.</p>
     *
     *  <p>Changing this property to anything other than <code>none</code> can
     *  result in an immediate change in scroll position to ensure
     *  an element is correctly snapped into position.  
     *  This change in scroll position is not animated</p>
     *
     *  <p>in MXML, the possible values are <code>"leadingEdge"</code>, <code>"center"</code>, 
     *  <code>"trailingEdge"</code>, and <code>"none"</code>.
     *  ActionScript values are defined by spark.components.ScrollSnappingMode. </p>
     *
     *  @see spark.components.ScrollSnappingMode
     *
     *  @default "none"
     *
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    public function get scrollSnappingMode():String
    {
        return _scrollSnappingMode;
    }

    /**
     *  @private 
     */
    public function set scrollSnappingMode(value:String):void    
    {
        if (value == _scrollSnappingMode)
            return;
        
        _scrollSnappingMode = value;
        if (getStyle("interactionMode") == InteractionMode.TOUCH)
        {
            if (canScrollHorizontally && canScrollVertically)
                throw new Error(resourceManager.getString("components", "operationSupportedForOneAxisOnly"));
            
            scrollRangesChanged = true;
            snappingModeChanged = true;
            invalidateProperties();
        }
    }
    
	//----------------------------------
	//  maxDragRate
	//----------------------------------
	
	private static var _maxDragRate:Number = 30;
	
	[Inspectable(category="General", defaultValue="30")]
	
	/**
	 *
	 *  Maximum number of times per second the scroll position
	 *  and the display will be updated while dragging.
	 *
	 *  @default 30
	 *
	 *  @langversion 3.0
	 *  @playerversion Flash 10
	 *  @playerversion AIR 2.5
	 *  @productversion Flex 4.5
	 */
	
	public static function get maxDragRate():Number
	{
		return _maxDragRate;
	}
	
	public static function set maxDragRate(value:Number):void
	{
		_maxDragRate = value;
	}
	
	
	
    //--------------------------------------------------------------------------
    // 
    // Methods
    //
    //--------------------------------------------------------------------------
    
    /**
     *  Scrolls the viewport so the specified element is visible.
     * 
     *  @param element A child element of the container, 
     *  or of a nested container, wrapped by the Scroller.  
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */ 
    public function ensureElementIsVisible(element:IVisualElement):void
    {   
        ensureElementPositionIsVisible(element);
    }
    
    /**
     *  @private
     *  
     *  @param elementLocalBounds ensure that these bounds of the element are 
     *  visible. The bounds are in the coordinate system of the element
     *  @param doValidateNow if true, call validateNow() at the end of the 
     *  function 
     */  
    private function ensureElementPositionIsVisible(element:IVisualElement, 
                                                    elementLocalBounds:Rectangle = null,
                                                    entireElementVisible:Boolean = true,
                                                    doValidateNow:Boolean = true):void
    {
        // First check that the element is a descendant
        // If we are a GraphicElement, use the element's parent
        var possibleDescendant:DisplayObject = element as DisplayObject;
        
        if (element is IGraphicElement)
            possibleDescendant = IGraphicElement(element).parent as DisplayObject;
        
        if (!possibleDescendant || !contains(possibleDescendant))
            return;
        
        var layout:LayoutBase = viewportLayout;
        
        if (layout)
        {
            // Before we change the scroll position, make sure there is
            // no throw effect playing.
            if (throwEffect && throwEffect.isPlaying)
            {
                throwEffect.stop();
                snapContentScrollPosition();
            }
            
            // Scroll the element into view
            var delta:Point = layout.getScrollPositionDeltaToAnyElement(element, 
                elementLocalBounds, entireElementVisible);
            
            // Compute new delta if element is visible in the viewport bounds but is
            // clipped/obscured by the soft keyboard
            var topLevelApp:Application = FlexGlobals.topLevelApplication as Application;
            var eltBounds:Rectangle;
            var adjustForSoftKeyboard:Boolean = topLevelApp && 
                                                (!topLevelApp.resizeForSoftKeyboard) &&
                                                (stage && stage.softKeyboardRect.height > 0);
            
            if (adjustForSoftKeyboard)
            {
                eltBounds = layout.getChildElementBounds(element);
                
                // Get keyboard y-position in the scroller's coordinates
                var keyboardTopLocal:Number = this.globalToLocal(stage.softKeyboardRect.topLeft).y;
                var scrollerHeight:Number = this.getLayoutBoundsHeight();
                
                // Does the keyboard clip the scroller?
                // Is the bottom of the element clipped or outside the visible
                // scroller height?
                if ((keyboardTopLocal >= 0) &&
                    (keyboardTopLocal < scrollerHeight) && 
                    ((eltBounds.bottom - viewport.verticalScrollPosition) > keyboardTopLocal))
                {
                    // Compute a new delta to accomodate the soft keyboard
                    var dy:Number = 0;
                    
                    if (eltBounds.height > keyboardTopLocal)
                    {
                        // Top justify if the element is taller than the 
                        // scroller's visible height
                        dy = eltBounds.top;
                    }
                    else
                    {
                        // Bottom justify the element
                        dy = eltBounds.bottom - keyboardTopLocal;
                    }
                    
                    var dx:Number = (delta) ? delta.x : 0;
                    
                    // account for current verticalScrollPosition
                    delta = new Point(dx, dy - viewport.verticalScrollPosition);
                }
            }
            
            if (delta)
            {
                viewport.horizontalScrollPosition += delta.x; 
                viewport.verticalScrollPosition += delta.y;
                
                // We only care about focusThickness if we are positioning the whole element 
                if (!elementLocalBounds)
                {
                    if (!eltBounds)
                        eltBounds = layout.getChildElementBounds(element);
                    
                    var focusThickness:Number = 0;
                
                    if (element is IStyleClient)
                        focusThickness = IStyleClient(element).getStyle("focusThickness");
                    
                    // Make sure that the focus ring is visible. Top and left sides have priority
                    if (focusThickness)
                    {
                        if (viewport.verticalScrollPosition > eltBounds.top - focusThickness)
                            viewport.verticalScrollPosition = eltBounds.top - focusThickness;
                        else if (viewport.verticalScrollPosition + height < eltBounds.bottom + focusThickness)
                            viewport.verticalScrollPosition = eltBounds.bottom + focusThickness - height;
                        
                        if (viewport.horizontalScrollPosition > eltBounds.left - focusThickness)
                            viewport.horizontalScrollPosition = eltBounds.left - focusThickness;
                        else if (viewport.horizontalScrollPosition + width < eltBounds.right + focusThickness)
                            viewport.horizontalScrollPosition = eltBounds.right + focusThickness - width;
                    }
                }
                
                if (doValidateNow && viewport is UIComponent)
                    UIComponent(viewport).validateNow();
            }
        }
    }
    
    /**
     *  @private
     *  Internal API for programmatically snapping to a particular element.
     *  Can optionally animate the position change.
     */
    mx_internal function snapElement(elementIndex:int,animate:Boolean):Animate
    {
        var layout:LayoutBase = viewportLayout;
        if (!layout)
            throw new Error(resourceManager.getString("components", "operationRequiresViewportLayout"));

        var elementBounds:Rectangle = layout.getElementBounds(elementIndex);
        var snapScrollPosition:Number;
        
        // Find the scroll position that puts the specified element into 
        // the appropriate snapped position.
        switch (scrollSnappingMode)
        {
            case ScrollSnappingMode.NONE:
            {
                throw new Error(resourceManager.getString("components", "operationRequiresSnappingMode"));
            }
                
            case ScrollSnappingMode.LEADING_EDGE:
            {
                if (canScrollHorizontally)
                    snapScrollPosition = elementBounds.left;
                    
                else if (canScrollVertically)
                    snapScrollPosition = elementBounds.top;
                break;        
            }
            case ScrollSnappingMode.CENTER:
            {
                if (canScrollHorizontally)
                    snapScrollPosition = elementBounds.left + elementBounds.width/2 - viewport.width/2;
                else if (canScrollVertically)
                    snapScrollPosition = elementBounds.top + elementBounds.height/2 - viewport.height/2;
                break;        
            }
            case ScrollSnappingMode.TRAILING_EDGE:                
            {
                if (canScrollHorizontally)
                    snapScrollPosition = elementBounds.right - viewport.width;
                else if (canScrollVertically)
                    snapScrollPosition = elementBounds.bottom - viewport.height;
                break;
            }
        }
        
        var scrollProperty:String;
        if (canScrollHorizontally)
            scrollProperty = HORIZONTAL_SCROLL_POSITION;
        else if (canScrollVertically)
            scrollProperty = VERTICAL_SCROLL_POSITION;
        
        // If there's an animation playing, we need 	 
        // to stop it before we snap the element into 	 
        // position. 	 
        stopAnimations(); 	 
        
        if (animate)
        {
            if (!snapElementAnimation)
            {
                snapElementAnimation = new Animate();
                snapElementAnimation.duration = 300;
                snapElementAnimation.target = viewport;
            }
            var snapMotionPath:Vector.<MotionPath> = Vector.<MotionPath>([new SimpleMotionPath(scrollProperty, null, snapScrollPosition)]);
            snapElementAnimation.motionPaths = snapMotionPath;
            snapElementAnimation.play();

            // If paging is enabled, make sure the destination snap position
            // also becomes the current page.
            if (pageScrollingEnabled)
                currentPageScrollPosition = snapScrollPosition; 			

            return snapElementAnimation;
        }
        else
        {
			if (scrollProperty)
           		viewport[scrollProperty] = snapScrollPosition;
			
			return null;
        }
    }
    
    /** 	 
     *  @private 	 
     */ 	 
    mx_internal function stopAnimations():void 	 
    { 	 
        if (throwEffect && throwEffect.isPlaying) 	 
            throwEffect.stop(); 	 
        if (snapElementAnimation && snapElementAnimation.isPlaying) 	 
            snapElementAnimation.stop(); 	 
    } 	 
    
    //--------------------------------------------------------------------------
    // 
    // Event Handlers
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private 
     */
    private function getCurrentPageCount():int
    {
        var viewportWidth:Number = isNaN(viewport.width) ? 0 : viewport.width;
        var viewportHeight:Number = isNaN(viewport.height) ? 0 : viewport.height;
        
        var pageCount:int = 0;
        
        if (canScrollHorizontally && viewportWidth != 0)
        {
            pageCount = Math.ceil(viewport.contentWidth / viewportWidth);
        }
        else if (canScrollVertically && viewportHeight != 0)
        {
            pageCount = Math.ceil(viewport.contentHeight/ viewportHeight);
        }
        
        return pageCount;
    }
    
    /**
     *  @private 
     */
    private function checkScrollPosition():void
    {
        // TODO (eday): This function is a mess.  It needs to be refactored and simplified.
        // It does too many things and has too many subtle behaviors.  But as I'm 
        // writing this we're too late in the release (4.6) schedule to make any
        // changes of that size.  This should be revisited during 5.0 development.
        
        // If the content size has changed, we may need to recalculate
        // the minimum and maximum scroll positions.
        determineScrollRanges();
        
        // Determine whether there's been a device orientation change
        // Note:  the first time this code runs it may falsely appear as though an orientation 
        // change has occurred (aspectRatio is null).  This is okay since there will be no 
        // throw animation playing, so orientationChange will not be acted upon.
        var orientationChange:Boolean = aspectRatio != FlexGlobals.topLevelApplication.aspectRatio;
        aspectRatio = FlexGlobals.topLevelApplication.aspectRatio;
        
        // See whether we possibly need to re-throw because of changed max positions.
        var needRethrow:Boolean = false;
        
        // Here we check to see whether the current throw has maybe not gone far enough
        // given the new content size. 
        // We don't rethrow for this reason in paging mode, as we don't want to go any further
        // than to the adjacent page.
        if (!pageScrollingEnabled)
        {
            if (throwReachedMaximumScrollPosition && (throwFinalVSP < maxVerticalScrollPosition || throwFinalHSP < maxHorizontalScrollPosition))
                needRethrow = true;                
            
            if (throwFinalVSP > maxVerticalScrollPosition || throwFinalHSP > maxHorizontalScrollPosition)
                needRethrow = true;
        }

        // See whether we possibly need to re-throw because the final snapped position is
        // no longer snapped.  This can occur when the snapped position was estimated due to virtual
        // layout, and the actual snapped position (i.e. once the relevent elements have been measured)
        // turns out to be different.
        // We also do this when pageScrolling is enabled to make sure we snap to a valid page position
        // after an orientation change - since an orientation change necessarily moves all the page
        // boundaries.
        if (scrollSnappingMode != ScrollSnappingMode.NONE || pageScrollingEnabled)
        {
            // NOTE: a lighter-weight way of doing this would be to retain the element
            // at the end of the throw and see whether its bounds have changed.
            if (canScrollHorizontally)
                if (getSnappedPosition(throwFinalHSP, HORIZONTAL_SCROLL_POSITION) != throwFinalHSP)
                    needRethrow = true;
            
            if (canScrollVertically)
                if (getSnappedPosition(throwFinalVSP, VERTICAL_SCROLL_POSITION) != throwFinalVSP)
                    needRethrow = true;
        }
        
        if (throwEffect && throwEffect.isPlaying && needRethrow)
        {
            // There's currently a throw animation playing, and it's throwing to a 
            // now-incorrect position.
            if (orientationChange)
            {
                // The throw end position became invalid because the device
                // orientation changed.  In this case, we just want to stop
                // the throw animation and snap to valid positions.  We don't
                // want to animate to the final position because this may
                // require changing directions relative to the current throw,
                // which looks strange.
                throwEffect.stop();
                snapContentScrollPosition();
            }
            else
            {
                // The size of the content may have changed during the throw.
                // In this case, we'll stop the current animation and start
                // a new one that gets us to the correct position.
                
                // Get the effect's current velocity
                var velocity:Point = throwEffect.getCurrentVelocity();
                
                // Stop the existing throw animation now that we've determined its current velocities.
                stoppedPreemptively = true;
                throwEffect.stop();
                stoppedPreemptively = false;
                
                // Now perform a new throw to get us to the right position.
                if (setUpThrowEffect(-velocity.x, -velocity.y))
                    throwEffect.play();
            }
        }
        else if (!inTouchInteraction)
        {
            // No touch interaction is in effect, but the content may be sitting at
            // a scroll position that is now invalid.  If so, snap the content to
            // a valid position.  The most likely reason we get here is that the
            // device orientation changed while the content is stationary (i.e. not
            // in an animated throw)
            
            // If the orientation changed and orientationChangeSnapElement is set to a 
            // valid value, then we will attempt to snap to the same item/page that
            // was snapped prior to the orientation change.
            if (orientationChange && orientationChangeSnapElement != -1)
            {
                if (scrollSnappingMode == ScrollSnappingMode.NONE && pageScrollingEnabled)
                {
                    // Paging without item snapping.  We want to snap to the same page, as
                    // long as the number of pages is the same.
                    // The number of pages being different indicates that the relationship
                    // between pages and content is unknown, and it makes no sense to try and 
                    // retain the same page.
                    if (previousOrientationPageCount == getCurrentPageCount())
                    {
                        var viewportWidth:Number = isNaN(viewport.width) ? 0 : viewport.width;
                        var viewportHeight:Number = isNaN(viewport.height) ? 0 : viewport.height;
                        
                        if (canScrollHorizontally)
                        {
                            viewport.horizontalScrollPosition = orientationChangeSnapElement * viewportWidth; 
                            currentPageScrollPosition = viewport.horizontalScrollPosition;  
                        }

                        else if (canScrollVertically)
                        {
                            viewport.verticalScrollPosition = orientationChangeSnapElement * viewportHeight; 
                            currentPageScrollPosition = viewport.verticalScrollPosition;  
                        }
                    }
                }
                else
                {
                    // Snap directly to the item that was snapped before the orientation changed.
                    // If this results in an invalid scroll position for the new orientation, the
                    // call to snapContentScrollPosition below will fix this. 
                    snapElement(orientationChangeSnapElement,false);
                }
                orientationChangeSnapElement = -1;
            }
            snapContentScrollPosition();
        }
    }
    
    
    /**
     *  @private 
     */
    private function handleSizeChange():void
    {
        // The content size has changed, so the current scroll
        // position and/or any in-progress throw may need to be adjusted.
        checkScrollPosition();

        // See whether the current page scroll position still needs to be initialized.
        if (pageScrollingEnabled && isNaN(currentPageScrollPosition))
            determineCurrentPageScrollPosition();
    }
        
    /**
     *  @private 
     *  Determines the minimum/maximum allowed scroll positions 
     *  when in leading-edge snapping mode
     */
    private function determineLeadingEdgeSnappingScrollRanges():void
    {
        var layout:LayoutBase = viewportLayout;
        var maxPositionItemIndex:int;
        var maxPositionItemBounds:Rectangle;
        
        // Locate the element nearest the leading edge: top for vertical scrolling, left for horizontal.
        var firstItemIndex:int = layout.getElementNearestScrollPosition(new Point(0, 0), "topLeft");
        var firstItemBounds:Rectangle = layout.getElementBounds(firstItemIndex);
        if (canScrollHorizontally)
        {
            // The minimum scroll position aligns the first element's leading (left) edge
            // with the left edge of the viewport.
            minHorizontalScrollPosition = firstItemBounds.left;
            
            // The maximum scroll position is one which aligns an element's leading edge 
            // with the leading edge of the viewport, but also leaves the last element
            // fully visible.
            var viewportWidth:Number = isNaN(viewport.width) ? 0 : viewport.width;
            maxPositionItemIndex = layout.getElementNearestScrollPosition(new Point(viewport.contentWidth-viewportWidth, 0), "topLeft");
            do
            {
                maxPositionItemBounds = layout.getElementBounds(maxPositionItemIndex);
                if ((viewport.contentWidth - maxPositionItemBounds.left) <= viewportWidth)
                    break;
            }
            while (++maxPositionItemIndex < layout.target.numElements); 
            maxHorizontalScrollPosition = maxPositionItemBounds.left;
        }
        else if (canScrollVertically)
        {
            // The minimum scroll position aligns the first element's leading (left) edge
            // with the left edge of the viewport.
            minVerticalScrollPosition = firstItemBounds.top; 
            
            // The maximum scroll position is one which aligns an element's leading edge 
            // with the leading edge of the viewport, but also leaves the last element
            // fully visible.
            var viewportHeight:Number = isNaN(viewport.height) ? 0 : viewport.height;
            maxPositionItemIndex = layout.getElementNearestScrollPosition(new Point(0, viewport.contentHeight-viewportHeight), "topLeft");
            do
            {
                maxPositionItemBounds = layout.getElementBounds(maxPositionItemIndex);
                if ((viewport.contentHeight - maxPositionItemBounds.top) <= viewportHeight)
                    break;
            }
            while (++maxPositionItemIndex < layout.target.numElements); 
            maxVerticalScrollPosition = maxPositionItemBounds.top; 
        }
    }

    /**
     *  @private
     *  Determines the minimum/maximum allowed scroll positions 
     *  when in center snapping mode
     */
    private function determineCenterSnappingScrollRanges():void
    {
        var layout:LayoutBase = viewportLayout;
        var leadingItemIndex:int;
        var leadingItemBounds:Rectangle;
        var trailingItemIndex:int;
        var trailingItemBounds:Rectangle;
        
        // For center snapping mode, the min/max positions must be set such that
        // any element in the layout can be scrolled into the center position.
        
        // Find the element nearest the zero point.
        leadingItemIndex = layout.getElementNearestScrollPosition(new Point(0, 0), "center");
        leadingItemBounds = layout.getElementBounds(leadingItemIndex);
        
        if (canScrollHorizontally)
        {
            var viewportWidth:Number = isNaN(viewport.width) ? 0 : viewport.width;
            trailingItemIndex = layout.getElementNearestScrollPosition(new Point(viewport.contentWidth, 0), "center");
            trailingItemBounds = layout.getElementBounds(trailingItemIndex);
            minVerticalScrollPosition = maxVerticalScrollPosition = 0;

            // Calculate the scroll position that puts the first element into the center.
            minHorizontalScrollPosition = leadingItemBounds.left + (leadingItemBounds.width/2) - (viewportWidth/2);
            
            // Calculate the scroll position that puts the last element into the center.
            maxHorizontalScrollPosition = trailingItemBounds.left + (trailingItemBounds.width/2) - (viewportWidth/2);
        }
        else if (canScrollVertically)
        {
            var viewportHeight:Number = isNaN(viewport.height) ? 0 : viewport.height;
            trailingItemIndex = layout.getElementNearestScrollPosition(new Point(0, viewport.contentHeight), "center");
            trailingItemBounds = layout.getElementBounds(trailingItemIndex);
            minHorizontalScrollPosition = maxHorizontalScrollPosition = 0;
            
            // Calculate the scroll position that puts the first element into the center.
            minVerticalScrollPosition = leadingItemBounds.top + (leadingItemBounds.height/2) - (viewportHeight/2);
            
            // Calculate the scroll position that puts the last element into the center.
            maxVerticalScrollPosition = trailingItemBounds.top + (trailingItemBounds.height/2) - (viewportHeight/2);
        }
    }
                
    /**
     *  @private
     *  Determines the minimum/maximum allowed scroll positions 
     *  when in trailing-edge snapping mode
     */
    private function determineTrailingEdgeSnappingScrollRanges():void
    {
        var layout:LayoutBase = viewportLayout;
        var snappedItemIndex:int;
        var snappedItemBounds:Rectangle;
        var lastItemIndex:int;
        var lastItemBounds:Rectangle;
        
        if (canScrollHorizontally)
        {
            // The max scroll position is the one which aligns the last element's right edge 
            // with the viewport's right edge
            var viewportWidth:Number = isNaN(viewport.width) ? 0 : viewport.width;
            lastItemIndex = layout.getElementNearestScrollPosition(new Point(viewport.contentWidth, 0), "bottomRight");
            lastItemBounds = layout.getElementBounds(lastItemIndex);
            maxHorizontalScrollPosition = lastItemBounds.right - viewportWidth;
            
            // The minimum scroll position is the one which aligns an element's right edge with the 
            // right edge of the viewport, but also leaves the first element fully visible.
            snappedItemIndex = layout.getElementNearestScrollPosition(new Point(viewportWidth, 0), "bottomRight");
            do
            {
                snappedItemBounds = layout.getElementBounds(snappedItemIndex);
                if (snappedItemBounds.right <= viewportWidth)
                    break;
            }
            while (--snappedItemIndex >= 0); 
            minHorizontalScrollPosition = snappedItemBounds.right - viewportWidth; 
        }
        else if (canScrollVertically)
        {
            // The max scroll position is the one which aligns the last element's bottom edge 
            // with the viewport's bottom edge
            var viewportHeight:Number = isNaN(viewport.height) ? 0 : viewport.height;
            lastItemIndex = layout.getElementNearestScrollPosition(new Point(0, viewport.contentHeight), "bottomRight");
            lastItemBounds = layout.getElementBounds(lastItemIndex);
            maxVerticalScrollPosition = lastItemBounds.bottom - viewportHeight;
            
            // The minimum scroll position is the one which aligns an element's right edge with the 
            // right edge of the viewport, but also leaves the first element fully visible.
            snappedItemIndex = layout.getElementNearestScrollPosition(new Point(0, viewportHeight), "bottomRight");
            do
            {
                snappedItemBounds = layout.getElementBounds(snappedItemIndex);
                if (snappedItemBounds.bottom <= viewportHeight)
                    break;
            }
            while (--snappedItemIndex >= 0); 
            minVerticalScrollPosition = snappedItemBounds.bottom - viewportHeight; 
        }
    }
    
    /**
     *  @private
     *  Determines the minimum/maximum allowed scroll positions. 
     */
    private function determineScrollRanges():void
    {
        minVerticalScrollPosition = maxVerticalScrollPosition = 0;
        minHorizontalScrollPosition = maxHorizontalScrollPosition = 0;
        
        if (viewport)
        {
            var viewportHeight:Number = isNaN(viewport.height) ? 0 : viewport.height;
            var viewportWidth:Number = isNaN(viewport.width) ? 0 : viewport.width;
            
            // For now, having both bounce and pull disabled puts us into a sort of
            // "endless" scrolling mode, in which there are practically no minimum/maximum
            // edges to bounce/pull against.
            // TODO (eday): bounce and pull probably don't need to be controlled separately.  These 
            // should be combined into a single property.
            if (!bounceEnabled && !pullEnabled)
            {
                minVerticalScrollPosition = minHorizontalScrollPosition = -Number.MAX_VALUE;
                maxVerticalScrollPosition = maxHorizontalScrollPosition = Number.MAX_VALUE;
            }
            else if (scrollSnappingMode == ScrollSnappingMode.NONE)
            {
                var remaining:Number;
                maxVerticalScrollPosition = viewport.contentHeight > viewportHeight ? 
                    viewport.contentHeight-viewportHeight : 0; 
                if (pageScrollingEnabled && canScrollVertically && viewportHeight != 0)
                {
                    // If the content height isn't an exact multiple of the viewport height,
                    // then we make sure the max scroll position allows for a full page (including
                    // padding) at the end.
                    remaining = viewport.contentHeight % viewportHeight;
                    if (remaining)
                        maxVerticalScrollPosition += viewportHeight - remaining;                  
                }
                
                maxHorizontalScrollPosition = viewport.contentWidth > viewportWidth ? 
                    viewport.contentWidth-viewportWidth : 0;
                if (pageScrollingEnabled && canScrollHorizontally && viewportWidth != 0)
                {
                    // If the content width isn't an exact multiple of the viewport width,
                    // then we make sure the max scroll position allows for a full page (including
                    // padding) at the end.
                    remaining = viewport.contentWidth % viewportWidth;
                    if (remaining)
                        maxHorizontalScrollPosition += viewportWidth - remaining;                  
                }
            }
            else
            {
                var layout:LayoutBase = viewportLayout;
                
                // Nothing to do if there is no layout or no layout elements
                if (!layout || layout.target.numElements == 0) 
                    return;
                
                // Nothing to do if the viewport dimensions have not been set yet
                if ((canScrollHorizontally && viewportWidth == 0) || (canScrollVertically && viewportHeight == 0)) 
                    return;
                
                switch (scrollSnappingMode)
                {
                    case ScrollSnappingMode.LEADING_EDGE:
                        determineLeadingEdgeSnappingScrollRanges();
                        break;
                    case ScrollSnappingMode.CENTER:
                        determineCenterSnappingScrollRanges();
                        break;
                    case ScrollSnappingMode.TRAILING_EDGE:                
                        determineTrailingEdgeSnappingScrollRanges();
                        break;
                }
            }
        }
        if (verticalScrollBar)
        {
            verticalScrollBar.contentMinimum = minVerticalScrollPosition;
            verticalScrollBar.contentMaximum = maxVerticalScrollPosition;
        }
        if (horizontalScrollBar)
        {
            horizontalScrollBar.contentMinimum = minHorizontalScrollPosition;
            horizontalScrollBar.contentMaximum = maxHorizontalScrollPosition;
        }
    }

    /**
     *  @private 
     */
    private function determineCurrentPageScrollPosition():void
    {
        if (canScrollHorizontally)
        {
            viewport.horizontalScrollPosition = getSnappedPosition(viewport.horizontalScrollPosition,HORIZONTAL_SCROLL_POSITION);
            currentPageScrollPosition = viewport.horizontalScrollPosition;
        }
        else if (canScrollVertically)
        {
            viewport.verticalScrollPosition = getSnappedPosition(viewport.verticalScrollPosition,VERTICAL_SCROLL_POSITION);
            currentPageScrollPosition = viewport.verticalScrollPosition;
        }
    }
    
    /**
     *  @private 
     */
    private function handleSizeChangeOnUpdateComplete(event:FlexEvent):void
    {
        viewport.removeEventListener(FlexEvent.UPDATE_COMPLETE, 
            handleSizeChangeOnUpdateComplete);
        
        handleSizeChange();
    }
    
    /**
     *  @private 
     */
    private function viewport_resizeHandler(event:Event):void
    {
        if (getStyle("interactionMode") == InteractionMode.TOUCH)
        {
            // If the viewport dimensions have changed, then we may need to update the
            // scroll ranges and snap the scroll position per the new viewport size.
            viewport.addEventListener(FlexEvent.UPDATE_COMPLETE, 
                handleSizeChangeOnUpdateComplete);
        }
    }
    
    /**
     *  @private 
     */
    private function viewport_propertyChangeHandler(event:PropertyChangeEvent):void
    {
        switch(event.property) 
        {
            case "contentWidth": 
            case "contentHeight": 
                invalidateSkin();
                if (getStyle("interactionMode") == InteractionMode.TOUCH)
                {
                    // If the content size changed, then the valid scroll position ranges 
                    // may have changed.  In this case, we need to schedule an updateComplete 
                    // handler to check and potentially correct the scroll positions. 
                    viewport.addEventListener(FlexEvent.UPDATE_COMPLETE, 
                        handleSizeChangeOnUpdateComplete);
                }
                break;

            case VERTICAL_SCROLL_POSITION:
            case HORIZONTAL_SCROLL_POSITION:
                if (getStyle("interactionMode") == InteractionMode.TOUCH)
                {
                    // Determine whether the scroll position is being modified programmatically (i.e.
                    // not due to a touch interaction or animation)
                    if (!inTouchInteraction && (!snapElementAnimation || !snapElementAnimation.isPlaying))
                    {
                        // We need to ensure the scroll position is always an appropriately snapped value.
                        if (!settingScrollPosition)
                        {
                            settingScrollPosition = true;
                            viewport[event.property] = getSnappedPosition(Number(event.newValue), String(event.property));
                            settingScrollPosition = false;
                        }
                        
                        // Reset the page scroll position from the programmatically-changed scroll position. 
                        if (canScrollHorizontally && event.property == HORIZONTAL_SCROLL_POSITION)
                            currentPageScrollPosition = viewport.horizontalScrollPosition;
                        if (canScrollVertically && event.property == VERTICAL_SCROLL_POSITION)
                            currentPageScrollPosition = viewport.verticalScrollPosition;
                    }
                    else if (throwEffect && throwEffect.isPlaying && throwEffect.isSnapping)
                    {
                        // If a throw animation is playing just to snap an element into position,
                        // then we want to stop the animation as soon as the final position is reached
                        // to avoid very short snaps taking a relatively long time to complete.
                        if (Math.abs(viewport.horizontalScrollPosition - throwEffect.finalPosition.x) < 1 &&
                            Math.abs(viewport.verticalScrollPosition - throwEffect.finalPosition.y) < 1)
                        {
                            throwEffect.stop();
                            snapContentScrollPosition();
                        }
                    }
                }
                break;
        }
    }
    
    // This keeps us from infinitely recursing while changing a scroll position from 
    // within the scroll position change handler.
    private var settingScrollPosition:Boolean = false;
    
    /**
     *  @private 
     *  Listens for any focusIn events from descendants 
     */ 
    override protected function focusInHandler(event:FocusEvent):void
    {
        super.focusInHandler(event);
        
		var fm:IFocusManager = focusManager;
		
        // When we gain focus, make sure the focused element is visible
        if (fm && viewport && ensureElementIsVisibleForSoftKeyboard)
        {
            var elt:IVisualElement = fm.getFocus() as IVisualElement; 
            lastFocusedElement = elt;
        }
    }
    
    /**
     *  @private
     */ 
    override protected function focusOutHandler(event:FocusEvent):void
    {
        super.focusOutHandler(event);
        lastFocusedElement = null;
    }
    
    /**
     *  @private 
     */
    private function orientationChangingHandler(event:Event):void
    {
        orientationChangeSnapElement = -1;
        
        // The orientation is about to change, so we see which item/page is currently snapped
        // and remember it so we can snap to it again when the orientation change is complete.
        if (scrollSnappingMode == ScrollSnappingMode.NONE && pageScrollingEnabled)
        {
            // For paging without item snapping, we remember the number of the current page.
            var viewportWidth:Number = isNaN(viewport.width) ? 0 : viewport.width;
            var viewportHeight:Number = isNaN(viewport.height) ? 0 : viewport.height;
            
            if (canScrollHorizontally && viewportWidth != 0)
                orientationChangeSnapElement = currentPageScrollPosition / viewportWidth; 
            else if (canScrollVertically && viewportHeight != 0)
                orientationChangeSnapElement = currentPageScrollPosition / viewportHeight;

            // Remember the page count so we'll know whether it changed.
            previousOrientationPageCount = getCurrentPageCount();
        }
        else if (scrollSnappingMode != ScrollSnappingMode.NONE)
        {
            // For item snapping, we remember which specific element is currently snapped. 
            
            if (canScrollHorizontally)
                getSnappedPosition(viewport.horizontalScrollPosition, HORIZONTAL_SCROLL_POSITION);
            else if (canScrollVertically)
                getSnappedPosition(viewport.verticalScrollPosition, VERTICAL_SCROLL_POSITION);
            
            // lastSnappedElement was set as a side-effect of the call to getSnappedPosition above.  
            orientationChangeSnapElement = lastSnappedElement;
        }
    
        // Force the viewport layout to clear its cache of element
        // dimensions so it can be repopulated with correct values
        // after the orientation change is complete.
        if (viewportLayout)
            viewportLayout.clearVirtualLayoutCache();
    }
    
    //--------------------------------------------------------------------------
    //
    //  Methods: IVisualElementContainer
    //
    //--------------------------------------------------------------------------

    /**
     *  Returns 1 if there is a viewport, 0 otherwise.
     * 
     *  @return The number of visual elements in this visual container
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get numElements():int
    {
        return viewport ? 1 : 0;
    }
    
    /**
     *  Returns the viewport if there is a viewport and the 
     *  index passed in is 0.  Otherwise, it throws a RangeError.
     *
     *  @param index The index of the element to retrieve.
     *
     *  @return The element at the specified index.
     * 
     *  @throws RangeError If the index position does not exist in the child list.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */ 
    public function getElementAt(index:int):IVisualElement
    {
        if (viewport && index == 0)
            return viewport;
        else
            throw new RangeError(resourceManager.getString("components", "indexOutOfRange", [index]));
    }
    
    /**
     *  Returns 0 if the element passed in is the viewport.  
     *  Otherwise, it throws an ArgumentError.
     *
     *  @param element The element to identify.
     *
     *  @return The index position of the element to identify.
     * 
     *  @throws ArgumentError If the element is not a child of this object.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */ 
    public function getElementIndex(element:IVisualElement):int
    {
        if (element != null && element == viewport)
            return 0;
        else
            throw ArgumentError(resourceManager.getString("components", "elementNotFoundInScroller", [element]));
    }
    
    /**
     * 
     *  This operation is not supported in Scroller.  
     *  A Scroller control has only one child. 
     *  Use the <code>viewport</code> property to manipulate 
     *  it.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function addElement(element:IVisualElement):IVisualElement
    {
        throw new ArgumentError(resourceManager.getString("components", "operationNotSupported"));
    }
    
    /**
     *  This operation is not supported in Scroller.  
     *  A Scroller control has only one child.  Use the <code>viewport</code> property to manipulate 
     *  it.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function addElementAt(element:IVisualElement, index:int):IVisualElement
    {
        throw new ArgumentError(resourceManager.getString("components", "operationNotSupported"));
    }
    
    /**
     * 
     *  This operation is not supported in Scroller.  
     *  A Scroller control has only one child.  Use the <code>viewport</code> property to manipulate 
     *  it.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function removeElement(element:IVisualElement):IVisualElement
    {
        throw new ArgumentError(resourceManager.getString("components", "operationNotSupported"));
    }
    
    /**
     * 
     *  This operation is not supported in Scroller.  
     *  A Scroller control has only one child.  Use the <code>viewport</code> property to manipulate 
     *  it.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function removeElementAt(index:int):IVisualElement
    {
        throw new ArgumentError(resourceManager.getString("components", "operationNotSupported"));
    }
    
    /**
     * 
     *  This operation is not supported in Scroller.  
     *  A Scroller control has only one child. Use the <code>viewport</code> property to manipulate 
     *  it.
     * 
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function removeAllElements():void
    {
        throw new ArgumentError(resourceManager.getString("components", "operationNotSupported"));
    }
    
    /**
     * 
     *  This operation is not supported in Scroller.  
     *  A Scroller control has only one child.  Use the <code>viewport</code> property to manipulate 
     *  it.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function setElementIndex(element:IVisualElement, index:int):void
    {
        throw new ArgumentError(resourceManager.getString("components", "operationNotSupported"));
    }
    
    /**
     * 
     *  This operation is not supported in Scroller.  
     *  A Scroller control has only one child.  Use the <code>viewport</code> property to manipulate 
     *  it.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function swapElements(element1:IVisualElement, element2:IVisualElement):void
    {
        throw new ArgumentError(resourceManager.getString("components", "operationNotSupported"));
    }
    
    /**
     * 
     *  This operation is not supported in Scroller.  
     *  A Scroller control has only one child.  Use the <code>viewport</code> property to manipulate 
     *  it.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function swapElementsAt(index1:int, index2:int):void
    {
        throw new ArgumentError(resourceManager.getString("components", "operationNotSupported"));
    }
    
    //--------------------------------------------------------------------------
    //
    //  Private Helper Methods
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     *  Helper method to easily invalidate the skins's size and display list.
     */
    private function invalidateSkin():void
    {
        if (skin)
        {
            skin.invalidateSize()
            skin.invalidateDisplayList();
        }
    }
    
    /**
     *  @private
     *  Helper method to grab the ScrollerLayout.
     */
    mx_internal function get scrollerLayout():ScrollerLayout
    {
        if (skin)
            return Group(skin).layout as ScrollerLayout;
        
        return null;
    }
    
    /**
     *  @private
     *  Helper method to grab scrollerLayout.canScrollHorizontally
     */
    private function get canScrollHorizontally():Boolean
    {
        var layout:ScrollerLayout = scrollerLayout;
        if (layout)
            return layout.canScrollHorizontally;

        return false;
    }
    
    /**
     *  @private
     *  Helper method to grab scrollerLayout.canScrollVertically
     */
    private function get canScrollVertically():Boolean
    {
        var layout:ScrollerLayout = scrollerLayout;
        if (layout)
            return layout.canScrollVertically;

        return false;
    }
    
    /**
     *  @private
     *  Helper method to grab viewport.layout
     */
    private function get viewportLayout():LayoutBase
    {
        if (viewport is GroupBase)
            return GroupBase(viewport).layout;
        else if (viewport is SkinnableContainer)
            return SkinnableContainer(viewport).layout;
        return null;
    }
    
    //--------------------------------------------------------------------------
    //
    //  Touch scrolling methods
    //
    //--------------------------------------------------------------------------
	
    /**
     *  @private
     *  Add touch listeners
     */
    private function installTouchListeners():void
    {
        addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
        addEventListener(TouchInteractionEvent.TOUCH_INTERACTION_STARTING, touchInteractionStartingHandler);
        addEventListener(TouchInteractionEvent.TOUCH_INTERACTION_START, touchInteractionStartHandler);
        addEventListener(TouchInteractionEvent.TOUCH_INTERACTION_END, touchInteractionEndHandler);
        
        // capture mouse listeners to help block click and mousedown events.
        // mousedown is blocked when a scroll is in progress
        // click is blocked when a scroll is in progress (or just finished)
        addEventListener(MouseEvent.CLICK, touchScrolling_captureMouseHandler, true);
        addEventListener(MouseEvent.MOUSE_DOWN, touchScrolling_captureMouseHandler, true);
    }
    
    /**
     *  @private
     */
    private function uninstallTouchListeners():void
    {
        removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
        removeEventListener(TouchInteractionEvent.TOUCH_INTERACTION_STARTING, touchInteractionStartingHandler);
        removeEventListener(TouchInteractionEvent.TOUCH_INTERACTION_START, touchInteractionStartHandler);
        removeEventListener(TouchInteractionEvent.TOUCH_INTERACTION_END, touchInteractionEndHandler);
        
        removeEventListener(MouseEvent.CLICK, touchScrolling_captureMouseHandler, true);
        removeEventListener(MouseEvent.MOUSE_DOWN, touchScrolling_captureMouseHandler, true);
    }
    
    /**
     *  @private
     *  This function determines whether a switch to an adjacent page is warranted, given 
     *  the distance dragged and/or the velocity thrown. 
     */
    private function determineNewPageScrollPosition(velocityX:Number, velocityY:Number):void
    {
        // Convert the paging velocity threshold from inches/second to pixels/millisecond 
        var minVelocityPixels:Number = pageThrowVelocityThreshold * Capabilities.screenDPI / 1000;
        
        if (canScrollHorizontally)
        {
            // Check both the throw velocity and the drag distance.  If either exceeds our threholds, then we switch to the next page.
            if (velocityX < -minVelocityPixels || viewport.horizontalScrollPosition >= currentPageScrollPosition + viewport.width * pageDragDistanceThreshold)
            {
                // Go to the next horizontal page
                // Set the new page scroll position so the throw effect animates the page into place
                currentPageScrollPosition = Math.min(currentPageScrollPosition + viewport.width, maxHorizontalScrollPosition);
            }
            else if (velocityX > minVelocityPixels || viewport.horizontalScrollPosition <= currentPageScrollPosition - viewport.width * pageDragDistanceThreshold)
            {
                // Go to the previous horizontal page
                currentPageScrollPosition = Math.max(currentPageScrollPosition - viewport.width, minHorizontalScrollPosition);     
            }
            
            // Ensure the new page position is snapped appropriately 
            currentPageScrollPosition = getSnappedPosition(currentPageScrollPosition, HORIZONTAL_SCROLL_POSITION);
        }
        else if (canScrollVertically)
        {
            // Check both the throw velocity and the drag distance.  If either exceeds our threholds, then we switch to the next page.
            if (velocityY < -minVelocityPixels || viewport.verticalScrollPosition >= currentPageScrollPosition + viewport.height * pageDragDistanceThreshold)
            {
                // Go to the next vertical page
                // Set the new page scroll position so the throw effect animates the page into place
                currentPageScrollPosition = Math.min(currentPageScrollPosition + viewport.height, maxVerticalScrollPosition);     
            }
            else if (velocityY > minVelocityPixels || viewport.verticalScrollPosition <= currentPageScrollPosition - viewport.height * pageDragDistanceThreshold)
            {
                // Go to the previous vertical page
                currentPageScrollPosition = Math.max(currentPageScrollPosition - viewport.height, minVerticalScrollPosition);     
            }

            // Ensure the new page position is snapped appropriately 
            currentPageScrollPosition = getSnappedPosition(currentPageScrollPosition, VERTICAL_SCROLL_POSITION);
        }
    }
    
    /**
     *  @private
     *  Set up the effect to be used for the throw animation
     */
    private function setUpThrowEffect(velocityX:Number, velocityY:Number):Boolean
    {
        if (!throwEffect)
        {
            throwEffect = new ThrowEffect();
            throwEffect.target = viewport;
            throwEffect.addEventListener(EffectEvent.EFFECT_END, throwEffect_effectEndHandler);
        }

        var minHSP:Number = minHorizontalScrollPosition;
        var minVSP:Number = minVerticalScrollPosition;
        var maxHSP:Number = maxHorizontalScrollPosition;
        var maxVSP:Number = maxVerticalScrollPosition;

        if (pageScrollingEnabled)
        {
            // See whether a page switch is warranted for this touch gesture.
            determineNewPageScrollPosition(velocityX, velocityY);
            
            // The throw velocity is greatly attenuated in paging mode.
            // Note that this must be done after the call above to
            // determineNewPageScrollPosition which compares the velocity
            // to our threshold.
            const PAGING_VELOCITY_FACTOR:Number = 0.25; 
            velocityX *= PAGING_VELOCITY_FACTOR;
            velocityY *= PAGING_VELOCITY_FACTOR;

            // Make the scroller "lock" to the current page
            if (canScrollHorizontally)
                minHSP = maxHSP = currentPageScrollPosition;
            else if (canScrollVertically)
                minVSP = maxVSP = currentPageScrollPosition;
        }

        throwEffect.propertyNameX = canScrollHorizontally ? HORIZONTAL_SCROLL_POSITION : null;
        throwEffect.propertyNameY = canScrollVertically ? VERTICAL_SCROLL_POSITION : null;
        throwEffect.startingVelocityX = velocityX;
        throwEffect.startingVelocityY = velocityY;
        throwEffect.startingPositionX = viewport.horizontalScrollPosition;
        throwEffect.startingPositionY = viewport.verticalScrollPosition;
        throwEffect.minPositionX = minHSP;
        throwEffect.minPositionY = minVSP;
        throwEffect.maxPositionX = maxHSP;
        throwEffect.maxPositionY = maxVSP;
        throwEffect.decelerationFactor = throwEffectDecelFactor;
        
        // In snapping mode, we need to ensure that the final throw position is snapped appropriately.
        throwEffect.finalPositionFilterFunction = scrollSnappingMode == ScrollSnappingMode.NONE ? null : getSnappedPosition; 
        
        throwReachedMaximumScrollPosition = false;
        if (throwEffect.setup())
        {
            throwFinalHSP = throwEffect.finalPosition.x;
            if (canScrollHorizontally && bounceEnabled && throwFinalHSP == maxHorizontalScrollPosition)
                throwReachedMaximumScrollPosition = true;
            throwFinalVSP = throwEffect.finalPosition.y;
            if (canScrollVertically && bounceEnabled && throwFinalVSP == maxVerticalScrollPosition)
                throwReachedMaximumScrollPosition = true;
        }
        else
        {
            touchScrollHelper.endTouchScroll();
            return false;
        }
        return true;
    }
        
    
    /**
     *  @private
     *  This function takes a scroll position and the associated property name, and finds
     *  the nearest snapped position (i.e. one that satifises the current scrollSnappingMode).
     */
    private function getSnappedPosition(position:Number, propertyName:String):Number
    {
        var layout:LayoutBase = viewportLayout;
        var nearestElementIndex:int = -1;
        var nearestElementBounds:Rectangle;
        
        var viewportWidth:Number = isNaN(viewport.width) ? 0 : viewport.width;
        var viewportHeight:Number = isNaN(viewport.height) ? 0 : viewport.height;

        if (scrollSnappingMode == ScrollSnappingMode.NONE && pageScrollingEnabled)
        {
            // If we're in paging mode and no snapping is enabled, then we must snap
            // the position to the beginning of a page.  i.e. a multiple of the 
            // viewport size.
            var offset:Number;
            if (canScrollHorizontally && propertyName == HORIZONTAL_SCROLL_POSITION && 
                viewportWidth != 0 && viewport.contentWidth != 0)
            {
                // Get the offset into the current page.  If less than half way, snap
                // to the beginning of the page.  Otherwise, snap to the beginning
                // of the next page
                offset = position % viewportWidth;
                if (offset < viewportWidth / 2)
                    position -= offset;
                else
                    position += viewportWidth - offset;
                
                // Clip the position to the valid min/max range
                position = Math.min(Math.max(minHorizontalScrollPosition, position), maxHorizontalScrollPosition);
            }
            else if (canScrollVertically && propertyName == VERTICAL_SCROLL_POSITION && 
                viewportHeight != 0 && viewport.contentHeight != 0)
            {
                offset = position % viewportHeight;
                if (offset < viewportHeight / 2)
                    position -= offset;
                else
                    position += viewportHeight - offset;

                // Clip the position to the valid min/max range
                position = Math.min(Math.max(minVerticalScrollPosition, position), maxVerticalScrollPosition);
            }
        }
        
        if (layout && layout.target.numElements > 0)
        {
            switch (_scrollSnappingMode)
            {
                case ScrollSnappingMode.LEADING_EDGE:
                    if (canScrollHorizontally && propertyName == HORIZONTAL_SCROLL_POSITION)
                    {
                        nearestElementIndex = layout.getElementNearestScrollPosition(new Point(position, 0), "topLeft");
                        nearestElementBounds = layout.getElementBounds(nearestElementIndex);
                        position = nearestElementBounds.left;
                    }
                    else if (canScrollVertically && propertyName == VERTICAL_SCROLL_POSITION)
                    {
                        nearestElementIndex = layout.getElementNearestScrollPosition(new Point(0, position), "topLeft");
                        nearestElementBounds = layout.getElementBounds(nearestElementIndex);
                        position = nearestElementBounds.top;
                    }
                    break;
                case ScrollSnappingMode.CENTER:
                    if (canScrollHorizontally && propertyName == HORIZONTAL_SCROLL_POSITION)
                    {
                        nearestElementIndex = layout.getElementNearestScrollPosition(new Point(position + viewportWidth/2, 0), "center");
                        nearestElementBounds = layout.getElementBounds(nearestElementIndex);
                        position = nearestElementBounds.left + (nearestElementBounds.width / 2) - (viewportWidth / 2);
                    }
                    else if (canScrollVertically && propertyName == VERTICAL_SCROLL_POSITION)
                    {
                        nearestElementIndex = layout.getElementNearestScrollPosition(new Point(0, position + viewportHeight/2), "center");
                        nearestElementBounds = layout.getElementBounds(nearestElementIndex);
                        position = nearestElementBounds.top + (nearestElementBounds.height / 2) - (viewportHeight / 2);
                    }
                    break;
                case ScrollSnappingMode.TRAILING_EDGE:                
                    if (canScrollHorizontally && propertyName == HORIZONTAL_SCROLL_POSITION)
                    {
                        nearestElementIndex = layout.getElementNearestScrollPosition(new Point(position + viewportWidth, 0), "bottomRight");
                        nearestElementBounds = layout.getElementBounds(nearestElementIndex);
                        position = nearestElementBounds.right - viewportWidth;
                    }
                    else if (canScrollVertically && propertyName == VERTICAL_SCROLL_POSITION)
                    {
                        nearestElementIndex = layout.getElementNearestScrollPosition(new Point(0, position + viewportHeight), "bottomRight");
                        nearestElementBounds = layout.getElementBounds(nearestElementIndex);
                        position = nearestElementBounds.bottom - viewportHeight;
                    }
                    break;
            }
        }
        lastSnappedElement = nearestElementIndex;
        return Math.round(position);
    }

    /**
     *  @private
     *  When the throw or drag scroll is over, we should play a nice 
     *  animation to hide the scrollbars.
     */
    private function hideScrollBars():void
    {
        if (!hideScrollBarAnimation)
        {
            hideScrollBarAnimation = new Animate();
            hideScrollBarAnimation.addEventListener(EffectEvent.EFFECT_END, hideScrollBarAnimation_effectEndHandler);
            hideScrollBarAnimation.duration = 500;
            var alphaMP:Vector.<MotionPath> = Vector.<MotionPath>([new SimpleMotionPath("alpha", 1, 0)]);
            hideScrollBarAnimation.motionPaths = alphaMP;
        }
        
        // set up the target scrollbars (hsb and/or vsb)
        var targets:Array = [];
        if (horizontalScrollBar && horizontalScrollBar.visible)
        {
            targets.push(horizontalScrollBar);
        }
        
        if (verticalScrollBar && verticalScrollBar.visible)
        {
            targets.push(verticalScrollBar);
        }
        
        // we keep track of hideScrollBarAnimationPrematurelyStopped so that we know 
        // if the effect ended naturally or if we prematurely called stop()
        hideScrollBarAnimationPrematurelyStopped = false;
        
        hideScrollBarAnimation.play(targets);
    }
    
    //--------------------------------------------------------------------------
    //
    //  Overridden methods
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    override protected function createChildren():void
    {
        super.createChildren();
        
        // Only listen for softKeyboardEvents if the 
        // softKeyboardBehavior attribute in the application descriptor equals "none"
        if (Application.softKeyboardBehavior == "none")
        {
            addEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATE, 
                softKeyboardActivateHandler, false, 
                EventPriority.DEFAULT, true);
            addEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATE, 
                softKeyboardActivateCaptureHandler, true, 
                EventPriority.DEFAULT, true);
            addEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_DEACTIVATE, 
                softKeyboardDeactivateHandler, false, 
                EventPriority.DEFAULT, true);  
            addEventListener(CaretBoundsChangeEvent.CARET_BOUNDS_CHANGE,
                caretBoundsChangeHandler);
        }
    }
    
    /**
     *  @private
     */
    override public function styleChanged(styleProp:String):void
    {
        super.styleChanged(styleProp);
        
        var allStyles:Boolean = (styleProp == null || styleProp == "styleName");
        
        if (allStyles || styleProp == "horizontalScrollPolicy" || 
            styleProp == "verticalScrollPolicy")
        {
            invalidateSkin();
        }
        
        if (allStyles || styleProp == "interactionMode")
        {
            if (getStyle("interactionMode") == InteractionMode.TOUCH)
            {
                installTouchListeners();
                
                // Need to make sure the scroll ranges are updated now, since they may 	 
                // not have been if the scroller was in non-touch mode when the content 	 
                // was created/changed. 	 
                scrollRangesChanged = true; 	 
                invalidateProperties(); 	 
                
                if (!touchScrollHelper)
                {
                    touchScrollHelper = new TouchScrollHelper();
                    touchScrollHelper.target = this;
                    
                    // Install callbacks with the helper
                    // The dragFunction is called repeatedly during dragging/scrolling.
                    touchScrollHelper.dragFunction = performDrag;
                    
                    // The throwFunction is called once when dragging is done and the finger is released.
                    touchScrollHelper.throwFunction = performThrow;
                }
                
                // We don't support directly interacting with the scrollbars in touch mode
                if (horizontalScrollBar)
                {
                    horizontalScrollBar.mouseEnabled = false;
                    horizontalScrollBar.mouseChildren = false;
                }
                if (verticalScrollBar)
                {
                    verticalScrollBar.mouseEnabled = false;
                    verticalScrollBar.mouseChildren = false;
                }
            }
            else
            {
                // In case we're not in touch mode, we need to instantiate our deferred skin parts immediately
                // TODO (egeorgie): support deferred scrollbar parts in non-touch mode
                ensureDeferredHScrollBarCreated();
                ensureDeferredVScrollBarCreated();
                
                uninstallTouchListeners();
                
                if (horizontalScrollBar)
                {
                    horizontalScrollBar.mouseEnabled = true;
                    horizontalScrollBar.mouseChildren = true;
                }
                if (verticalScrollBar)
                {
                    verticalScrollBar.mouseEnabled = true;
                    verticalScrollBar.mouseChildren = true;
                }
            }
        }
        
        // If the liveScrolling style was set, set the scrollbars' liveDragging styles
        
        if (allStyles || styleProp == "liveScrolling")
        {
            const liveScrolling:* = getStyle("liveScrolling");
            if ((liveScrolling === true) || (liveScrolling === false))
            {
                if (verticalScrollBar)
                    verticalScrollBar.setStyle("liveDragging", Boolean(liveScrolling));
                if (horizontalScrollBar)
                    horizontalScrollBar.setStyle("liveDragging", Boolean(liveScrolling));
            }
        }
    }

    /**
     *  @private
     */
    override protected function attachSkin():void
    {
        super.attachSkin();
        
        if (getStyle("interactionMode") != InteractionMode.TOUCH)
        {
            // TODO (egeorgie): support deferred scrollbar parts in non-touch mode
            // In case we're not in touch mode, we need to instantiate our deferred skin parts immediately
            ensureDeferredHScrollBarCreated();
            ensureDeferredVScrollBarCreated();
        }
        
        Group(skin).layout = new ScrollerLayout();
        installViewport();
        skin.addEventListener(MouseEvent.MOUSE_WHEEL, skin_mouseWheelHandler);
    }
    
    /**
     *  @private
     */
    override protected function detachSkin():void
    {    
        uninstallViewport();
        Group(skin).layout = null;
        skin.removeEventListener(MouseEvent.MOUSE_WHEEL, skin_mouseWheelHandler);
        super.detachSkin();
    }
    
    /**
     *  @private
     */
    override protected function partAdded(partName:String, instance:Object):void
    {
        super.partAdded(partName, instance);
        
        const liveScrolling:* = getStyle("liveScrolling");
        const liveScrollingSet:Boolean = (liveScrolling === true) || (liveScrolling === false);
        const inTouchMode:Boolean =  (getStyle("interactionMode") == InteractionMode.TOUCH);
        
        if (instance == verticalScrollBar)
        {
            verticalScrollBar.viewport = viewport;
            if (liveScrollingSet)
                verticalScrollBar.setStyle("liveDragging", Boolean(liveScrolling));
            verticalScrollBar.contentMinimum = minVerticalScrollPosition;
            verticalScrollBar.contentMaximum = maxVerticalScrollPosition;

            // We don't support directly interacting with the scrollbars in touch mode
            if (inTouchMode)
            {
                verticalScrollBar.mouseEnabled = false;
                verticalScrollBar.mouseChildren = false;
            }
                
        }
        else if (instance == horizontalScrollBar)
        {
            horizontalScrollBar.viewport = viewport;
            if (liveScrollingSet)
                horizontalScrollBar.setStyle("liveDragging", Boolean(liveScrolling));            
            horizontalScrollBar.contentMinimum = minHorizontalScrollPosition;
            horizontalScrollBar.contentMaximum = maxHorizontalScrollPosition; 

            // We don't support directly interacting with the scrollbars in touch mode
            if (inTouchMode)
            {
                horizontalScrollBar.mouseEnabled = false;
                horizontalScrollBar.mouseChildren = false;
            }
        }
    }
    
    /**
     *  @private
     */
    override protected function partRemoved(partName:String, instance:Object):void
    {
        super.partRemoved(partName, instance);
        
        if (instance == verticalScrollBar)
            verticalScrollBar.viewport = null;
        else if (instance == horizontalScrollBar)
            horizontalScrollBar.viewport = null;
    }
    
    /**
     *  @private
     */
    override protected function commitProperties():void
    {
        super.commitProperties();
        
        if (scrollRangesChanged)
        {
            determineScrollRanges();
            scrollRangesChanged = false;
        }
        
        if (pageScrollingChanged)
        {
            stopAnimations();
            determineCurrentPageScrollPosition();
            pageScrollingChanged = false;
        }
        
        if (snappingModeChanged)
        {
            stopAnimations();
            snapContentScrollPosition();
            snappingModeChanged = false;                
        }
    }
    
    //--------------------------------------------------------------------------
    //
    //  Event handlers
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    override protected function keyDownHandler(event:KeyboardEvent):void
    {
        super.keyDownHandler(event);

        var vp:IViewport = viewport;
        if (!vp || event.isDefaultPrevented())
            return;

        // If a TextField has the focus, then assume it will handle all keyboard
        // events, and that it will not use Event.preventDefault().
        if (getFocus() is TextField)
            return;
    
        if (verticalScrollBar && verticalScrollBar.visible)
        {
            var vspDelta:Number = NaN;
            switch (event.keyCode)
            {
                case Keyboard.UP:
                     vspDelta = vp.getVerticalScrollPositionDelta(NavigationUnit.UP);
                     break;
                case Keyboard.DOWN:
                     vspDelta = vp.getVerticalScrollPositionDelta(NavigationUnit.DOWN);
                     break;
                case Keyboard.PAGE_UP:
                     vspDelta = vp.getVerticalScrollPositionDelta(NavigationUnit.PAGE_UP);
                     break;
                case Keyboard.PAGE_DOWN:
                     vspDelta = vp.getVerticalScrollPositionDelta(NavigationUnit.PAGE_DOWN);
                     break;
                case Keyboard.HOME:
                     vspDelta = vp.getVerticalScrollPositionDelta(NavigationUnit.HOME);
                     break;
                case Keyboard.END:
                     vspDelta = vp.getVerticalScrollPositionDelta(NavigationUnit.END);
                     break;
            }
            if (!isNaN(vspDelta))
            {
                vp.verticalScrollPosition += vspDelta;
                event.preventDefault();
            }
        }

        if (horizontalScrollBar && horizontalScrollBar.visible)
        {
            var hspDelta:Number = NaN;
            switch (event.keyCode)
            {
                case Keyboard.LEFT:
                    hspDelta = (layoutDirection == LayoutDirection.LTR) ?
                        vp.getHorizontalScrollPositionDelta(NavigationUnit.LEFT) :
                        vp.getHorizontalScrollPositionDelta(NavigationUnit.RIGHT);
                    break;
                case Keyboard.RIGHT:
                    hspDelta = (layoutDirection == LayoutDirection.LTR) ?
                        vp.getHorizontalScrollPositionDelta(NavigationUnit.RIGHT) :
                        vp.getHorizontalScrollPositionDelta(NavigationUnit.LEFT);
                    break;
                case Keyboard.HOME:
                    hspDelta = vp.getHorizontalScrollPositionDelta(NavigationUnit.HOME);
                    break;
                case Keyboard.END:                
                    hspDelta = vp.getHorizontalScrollPositionDelta(NavigationUnit.END);
                    break;
                // If there's no vertical scrollbar, then map page up/down to
                // page left,right
                case Keyboard.PAGE_UP:
                     if (!verticalScrollBar || !(verticalScrollBar.visible)) 
                     {
                         hspDelta = (LayoutDirection.LTR) ?
                             vp.getHorizontalScrollPositionDelta(NavigationUnit.LEFT) :
                             vp.getHorizontalScrollPositionDelta(NavigationUnit.RIGHT);
                     }
                     break;
                case Keyboard.PAGE_DOWN:
                     if (!verticalScrollBar || !(verticalScrollBar.visible)) 
                     {
                         hspDelta = (LayoutDirection.LTR) ?
                             vp.getHorizontalScrollPositionDelta(NavigationUnit.RIGHT) :
                             vp.getHorizontalScrollPositionDelta(NavigationUnit.LEFT);
                     }
                     break;
            }
            if (!isNaN(hspDelta))
            {
                vp.horizontalScrollPosition += hspDelta;
                event.preventDefault();
            }
        }
    }
    
    private function skin_mouseWheelHandler(event:MouseEvent):void
    {
        const vp:IViewport = viewport;
        if (event.isDefaultPrevented() || !vp || !vp.visible)
            return;
            
        // Dispatch the "mouseWheelChanging" event. If preventDefault() is called
        // on this event, the event will be cancelled.  Otherwise if  the delta
        // is modified the new value will be used.
        var changingEvent:FlexMouseEvent = MouseEventUtil.createMouseWheelChangingEvent(event);
        if (!dispatchEvent(changingEvent))
        {
            event.preventDefault();
            return;
        }
        
        const delta:int = changingEvent.delta;
        
        var nSteps:uint = Math.abs(event.delta);
        var navigationUnit:uint;

        // Scroll delta "steps".  If the VSB is up, scroll vertically,
        // if -only- the HSB is up then scroll horizontally.
         
        // TODO: The problem is that viewport.validateNow() doesn’t necessarily 
        // finish the job, see http://bugs.adobe.com/jira/browse/SDK-25740.   
        // Since some imprecision in mouse-wheel scrolling is tolerable this is
        // ok for now.  For 4.next we should add Scroller API for (reliably) 
        // scrolling in different increments and refactor code like this to 
        // depend on it.  Also applies to VScroller and HScroller mouse
        // handlers.
        
        if (verticalScrollBar && verticalScrollBar.visible)
        {
            navigationUnit = (delta < 0) ? NavigationUnit.DOWN : NavigationUnit.UP;
            for (var vStep:int = 0; vStep < nSteps; vStep++)
            {
                var vspDelta:Number = vp.getVerticalScrollPositionDelta(navigationUnit);
                if (!isNaN(vspDelta))
                {
                    vp.verticalScrollPosition += vspDelta;
                    if (vp is IInvalidating)
                        IInvalidating(vp).validateNow();
                }
            }
            event.preventDefault();
        }
        else if (horizontalScrollBar && horizontalScrollBar.visible)
        {
            navigationUnit = (delta < 0) ? NavigationUnit.RIGHT : NavigationUnit.LEFT;
            for (var hStep:int = 0; hStep < nSteps; hStep++)
            {
                var hspDelta:Number = vp.getHorizontalScrollPositionDelta(navigationUnit);
                if (!isNaN(hspDelta))
                {
                    vp.horizontalScrollPosition += hspDelta;
                    if (vp is IInvalidating)
                        IInvalidating(vp).validateNow();
                }
            }
            event.preventDefault();
        }            
    }
    
    //--------------------------------------------------------------------------
    //
    //  Event handlers: Touch Scrolling
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     *  Event handler dispatched when someone is about to start scrolling.
     */
    private function touchInteractionStartingHandler(event:TouchInteractionEvent):void
    {
        // if it's us, don't do anything
        // if it's someone else and we've started scrolling, cancel this event
        // if it's someone else and we haven't started scrolling, don't do anything
        // here yet. Worry about it in the touchInteractionStartHandler().
        if (event.relatedObject != this && inTouchInteraction)
        {
            event.preventDefault();
        }
    }
    
    /**
     *  @private
     *  Event handler dispatched when someone has started scrolling.
     */
    private function touchInteractionStartHandler(event:TouchInteractionEvent):void
    {
        if (event.relatedObject != this)
        {
            // if it's not us scrolling, abort our scrolling attempt
            touchScrollHelper.stopScrollWatch();
        }
        else
        {
            // we are scrolling
            captureNextClick = true;
            captureNextMouseDown = true;
            preventThrows = false;
            
            hspBeforeTouchScroll = viewport.horizontalScrollPosition;
            vspBeforeTouchScroll = viewport.verticalScrollPosition;
            
            // TODO (rfrishbe): should the ScrollerLayout just listen to 
            // Scroller events to determine this rather than doing it here.
            // Also should figure out who's in charge of fading the alpha of the
            // scrollbars...Scroller or ScrollerLayout (or even HScrollbar/VScrollbar)?
            if (canScrollHorizontally)
                horizontalScrollInProgress = true;
            
            if (canScrollVertically)
                verticalScrollInProgress = true;
            
            // need to invaliadte the ScrollerLayout object so it'll update the
            // scrollbars in overlay mode
            skin.invalidateDisplayList();
            
            // make sure our alpha is set back to normal from hideScrollBarAnimation
            if (hideScrollBarAnimation && hideScrollBarAnimation.isPlaying)
            {
                // stop the effect, but make sure our code for EFFECT_END doesn't actually 
                // run since the effect didn't end on its own.
                hideScrollBarAnimationPrematurelyStopped = true;
                hideScrollBarAnimation.stop();
            }
            
            // We only show want the scroll bars to be visible if some content might actually be
            // off screen.  We determine this by looking at the min/max scroll positions.
            if (horizontalScrollBar)
                horizontalScrollBar.alpha = (maxHorizontalScrollPosition == 0 && minHorizontalScrollPosition == 0) ? 0.0 : 1.0;
            
            if (verticalScrollBar)
                verticalScrollBar.alpha = (maxVerticalScrollPosition == 0 && minVerticalScrollPosition == 0) ? 0.0 : 1.0;
            
            inTouchInteraction = true;
        }
    }
    
    /**
     *  @private
     *  Snap the scroll positions to valid values.
     */
    private function snapContentScrollPosition(snapHorizontal:Boolean = true, snapVertical:Boolean = true):void
    {
        // Note that we only snap the scroll position if content is present.  This allows existing scroll position
        // values to be retained before content is added or when it is removed/readded.
        if (snapHorizontal && viewport.contentWidth != 0)
    {
        viewport.horizontalScrollPosition = getSnappedPosition( 
            Math.min(Math.max(minHorizontalScrollPosition, viewport.horizontalScrollPosition), maxHorizontalScrollPosition),
            HORIZONTAL_SCROLL_POSITION);
        }

        if (snapVertical && viewport.contentHeight != 0)
        {
        viewport.verticalScrollPosition = getSnappedPosition( 
            Math.min(Math.max(minVerticalScrollPosition, viewport.verticalScrollPosition), maxVerticalScrollPosition),
            VERTICAL_SCROLL_POSITION);
    }
    }
    
    /**
     *  @private
     *  Stop the effect if it's currently playing and prepare for a possible scroll
     */
    private function stopThrowEffectOnMouseDown():void
    {
        if (throwEffect && throwEffect.isPlaying)
        {
            // stop the effect.  we don't want to move it to its final value...we want to stop it in place
            stoppedPreemptively = true;
            throwEffect.stop();
                    
            // Snap the scroll position to the content in case the empty space beyond the edge was visible
            // due to bounce/pull.
            snapContentScrollPosition();
            
            // get new values in case we start scrolling again
            hspBeforeTouchScroll = viewport.horizontalScrollPosition;
            vspBeforeTouchScroll = viewport.verticalScrollPosition;
        }
    }
    
    /**
     *  @private
     *  Event listeners added while a scroll/throw animation is in effect
     */
    private function touchScrolling_captureMouseHandler(event:MouseEvent):void
    {
        switch(event.type)
        {
            case MouseEvent.MOUSE_DOWN:
                // If we get a mouse down when the throw animation is within a few
                // pixels of its final destination, we'll go ahead and stop the 
                // touch interaction and allow the event propogation to continue
                // so other handlers can see it.  Otherwise, we'll capture the 
                // down event and start watching for the next scroll.
                
                // 5 pixels at 252dpi worked fairly well for this heuristic.
                const THRESHOLD_INCHES:Number = 0.01984; // 5/252 
                var captureThreshold:Number = Math.round(THRESHOLD_INCHES * Capabilities.screenDPI);
                
                // Need to convert the pixel delta to the local coordinate system in 
                // order to compare it to a scroll position delta. 
                captureThreshold = globalToLocal(
                    new Point(captureThreshold,0)).subtract(globalToLocal(ZERO_POINT)).x;

                if (captureNextMouseDown &&  
                    (Math.abs(viewport.verticalScrollPosition - throwFinalVSP) > captureThreshold || 
                     Math.abs(viewport.horizontalScrollPosition - throwFinalHSP) > captureThreshold))
                {
                    // Capture the down event.
                    stopThrowEffectOnMouseDown();
                    
                    // Watch for a scroll to begin.  The helper object will call our
                    // performDrag and performThrow callbacks as appropriate.
                    touchScrollHelper.startScrollWatch(
                        event,
                        canScrollHorizontally,
                        canScrollVertically,
                        Math.round(minSlopInches * Capabilities.screenDPI), 
                        dragEventThinning ? _maxDragRate : NaN);
                    event.stopImmediatePropagation();
                }
                else
                {
                    // Stop the current throw and allow the down event
                    // to propogate normally.
                    if (throwEffect && throwEffect.isPlaying)
                    {
                        throwEffect.stop();
                        snapContentScrollPosition();
                    }
                }
                break;
            case MouseEvent.CLICK:
                if (!captureNextClick)
                    return;
                
                event.stopImmediatePropagation();
                break;
        }
    }
    
    /**
     *  @private
     *  Mousedown listener that adds the other listeners to watch for a scroll.
     */
    private function mouseDownHandler(event:MouseEvent):void
    {
        stopThrowEffectOnMouseDown();
        
        // If the snap animation is playing, we need to stop it 	 
        // before watching for a scroll and potentially beginning 	 
        // a new touch interaction.
        if (snapElementAnimation && snapElementAnimation.isPlaying)
        {
            snapElementAnimation.stop(); 	 

            // If paging is enabled and the user interrupted the snap animation,
            // we need to set the current page to where the animation was stopped.
            if (pageScrollingEnabled)
                determineCurrentPageScrollPosition();            
        }
                
        captureNextClick = false;
        
        // Watch for a scroll to begin.  The helper object will call our
        // performDrag and performThrow callbacks as appropriate.
        touchScrollHelper.startScrollWatch(
            event, 
            canScrollHorizontally,
            canScrollVertically,
            Math.round(minSlopInches * Capabilities.screenDPI), 
            dragEventThinning ? _maxDragRate : NaN);
    }
    	
    /**
     *  @private
     */
    mx_internal function performDrag(dragX:Number, dragY:Number):void
    {
        if (textSelectionAutoScrollEnabled)
        {
            setUpTextSelectionAutoScroll();
            return;
        }

        // dragX and dragY are delta value in the global coordinate space.
        // In order to use them to change the scroll position we must convert
        // them to the scroller's local coordinate space first.
        // This code converts the deltas from global to local.
        var localDragDeltas:Point = 
            globalToLocal(new Point(dragX,dragY)).subtract(globalToLocal(ZERO_POINT));
        dragX = localDragDeltas.x;
        dragY = localDragDeltas.y;

        var xMove:int = 0;
        var yMove:int = 0;
		
        if (canScrollHorizontally)
            xMove = dragX;
        
        if (canScrollVertically)
            yMove = dragY;
        
        var newHSP:Number = hspBeforeTouchScroll - xMove;
        var newVSP:Number = vspBeforeTouchScroll - yMove;
        
        var viewportWidth:Number = isNaN(viewport.width) ? 0 : viewport.width;
        
        // If we're pulling the list past its end, we want it to move
        // only a portion of the finger distance to simulate tension.
        if (pullEnabled)
        {
            if (newHSP < minHorizontalScrollPosition)
                newHSP = Math.round(minHorizontalScrollPosition + ((newHSP-minHorizontalScrollPosition) * PULL_TENSION_RATIO));
            if (newHSP > maxHorizontalScrollPosition)
                newHSP = Math.round(maxHorizontalScrollPosition + ((newHSP-maxHorizontalScrollPosition) * PULL_TENSION_RATIO));
            
            var viewportHeight:Number = isNaN(viewport.height) ? 0 : viewport.height;
            
            if (newVSP < minVerticalScrollPosition)
                newVSP = Math.round(minVerticalScrollPosition + ((newVSP-minVerticalScrollPosition) * PULL_TENSION_RATIO));
            
            if (newVSP > maxVerticalScrollPosition)
                newVSP = Math.round(maxVerticalScrollPosition + ((newVSP-maxVerticalScrollPosition) * PULL_TENSION_RATIO));
            
            // clamp the values here
            newHSP = Math.min(Math.max(newHSP, -viewportWidth), maxHorizontalScrollPosition+viewportWidth);
            newVSP = Math.min(Math.max(newVSP, -viewportHeight), maxVerticalScrollPosition+viewportHeight);
        }
		
        viewport.horizontalScrollPosition = newHSP;
        viewport.verticalScrollPosition = newVSP;
    }
    
    /**
     *  @private
     */ 
    private function throwEffect_effectEndHandler(event:EffectEvent):void
    {
        // if we stopped the effect ourself (because someone pressed down), then let's not consider
        // this the end
        if (stoppedPreemptively)
            return;
        
        touchScrollHelper.endTouchScroll();
    }

    /**
     *  @private
     */ 
    mx_internal function performThrow(velocityX:Number, velocityY:Number):void
    {
        // Don't throw if we're doing a text selection auto scroll
        if (textSelectionAutoScrollEnabled)
        {
            stopTextSelectionAutoScroll();
            touchScrollHelper.endTouchScroll();
            return;
        }

        // If the soft keyboard is up (or about to come up), or 
        // we're offscreen for some reason, don't start a throw.
        if (preventThrows || !stage)
        {
            touchScrollHelper.endTouchScroll();
            return;
        }

        stoppedPreemptively = false;

        // The velocity values are deltas in the global coordinate space.
        // In order to use them to change the scroll position we must convert
        // them to the scroller's local coordinate space first.
        // This code converts the deltas from global to local.
        //        
        // Note that we scale the velocity values up and then back down around the 
        // calls to globalToLocal.  This is because the runtime only returns values
        // rounded to the nearest 0.05.  The velocities are small number (<4.0) with 
        // lots of precision that we don't want to lose.  The scaling preserves
        // a sufficient level of precision for our purposes.
        var throwVelocity:Point = new Point(velocityX, velocityY);
        throwVelocity.x *= 100000;
        throwVelocity.y *= 100000;
        
        // Because we subtract out the difference between the two coordinate systems' origins,
        // This is essentially just multiplying by a scaling factor.
        throwVelocity = 
            this.globalToLocal(throwVelocity).subtract(this.globalToLocal(new Point(0, 0)));
        
        throwVelocity.x /= 100000;
        throwVelocity.y /= 100000;
        
        if (setUpThrowEffect(throwVelocity.x, throwVelocity.y))
            throwEffect.play();
    }
    
    /**
     *  @private
     *  When the throw is over, no need to listen for mouse events anymore.
     *  Also, use this to hide the scrollbars.
     */
    private function touchInteractionEndHandler(event:TouchInteractionEvent):void
    {
        if (event.relatedObject == this)
        {
            captureNextMouseDown = false;
            // don't reset captureNextClick here because touchScrollEnd
            // may be invoked on mouseUp and mouseClick occurs immediately 
            // after that, so we want to block this next mouseClick
            
            hideScrollBars();
            inTouchInteraction = false;
        }
    }
    
    /**
     *  @private
     *  Called when the effect finishes playing on the scrollbars.  This is so ScrollerLayout 
     *  can hide the scrollbars completely and go back to controlling its visibility.
     */
    private function hideScrollBarAnimation_effectEndHandler(event:EffectEvent):void
    {
        // distinguish between if we called stop() and if the effect ended naturally
        if (hideScrollBarAnimationPrematurelyStopped)
            return;
        
        // now get rid of the scrollbars visibility
        horizontalScrollInProgress = false;
        verticalScrollInProgress = false;
        
        // need to invalidate the ScrollerLayout object so it'll update the
        // scrollbars in overlay mode
        skin.invalidateDisplayList();
    }
	
	//--------------------------------------------------------------------------
	//
	//  Text selection auto scroll
	//
	//--------------------------------------------------------------------------
	
	/**
	 *  @private
	 *  When true, use the text selection scroll behavior instead of the 
	 *  typical "throw" behavior. This is only used when interactionMode="touch"
	 */
	mx_internal var textSelectionAutoScrollEnabled:Boolean = false;
	private var textSelectionAutoScrollTimer:Timer;
	private var minTextSelectionVScrollPos:int = 0;
	private var maxTextSelectionVScrollPos:int = -1;
	private var minTextSelectionHScrollPos:int = 0;
	private var maxTextSelectionHScrollPos:int = -1;
	private static const TEXT_SELECTION_AUTO_SCROLL_FPS:int = 10;
	
	/**
	 *  @private
	 *  Change scroll behavior when selecting text. 
	 */
	mx_internal function enableTextSelectionAutoScroll(enable:Boolean,
					   minHScrollPosition:int = 0, maxHScrollPosition:int = -1,
					   minVScrollPosition:int = 0, maxVScrollPosition:int = -1):void
	{
		if (getStyle("interactionMode") == InteractionMode.TOUCH)
		{
			this.textSelectionAutoScrollEnabled = enable;
			this.minTextSelectionHScrollPos = minHScrollPosition;
			this.maxTextSelectionHScrollPos = maxHScrollPosition;
			this.minTextSelectionVScrollPos = minVScrollPosition;
			this.maxTextSelectionVScrollPos = maxVScrollPosition;
		}
	}
	
	/**
	 *  @private
	 */
	mx_internal function setUpTextSelectionAutoScroll():void
	{
		if (!textSelectionAutoScrollTimer)
		{
			textSelectionAutoScrollTimer = new Timer(1000 / TEXT_SELECTION_AUTO_SCROLL_FPS);
			textSelectionAutoScrollTimer.addEventListener(TimerEvent.TIMER, 
				textSelectionAutoScrollTimerHandler);
			
			textSelectionAutoScrollTimer.start();
		}
	}
	
	/**
	 *  @private
	 */
	mx_internal function stopTextSelectionAutoScroll():void
	{
		if (textSelectionAutoScrollTimer)
		{
			textSelectionAutoScrollTimer.stop();
			textSelectionAutoScrollTimer.removeEventListener(TimerEvent.TIMER,
				textSelectionAutoScrollTimerHandler);
			textSelectionAutoScrollTimer = null;
		}
	}
	
	/**
	 *  @private
	 */
	private function textSelectionAutoScrollTimerHandler(event:TimerEvent):void
	{
		const SLOW_SCROLL_THRESHOLD:int = 12;		// Distance from edge to trigger a slow scroll
		const SLOW_SCROLL_SPEED:int = 20;			// Pixels per timer callback to scroll
		const FAST_SCROLL_THRESHOLD:int = 3;		// Distance from edge to trigger a fast scroll
		const FAST_SCROLL_DELTA:int = 30; 			// Added to SLOW_SCROLL_SPEED to determine fast speed
		
		var newVSP:Number = viewport.verticalScrollPosition;
		var newHSP:Number = viewport.horizontalScrollPosition;
		
		if (canScrollHorizontally)
		{
			if (mouseX > width - SLOW_SCROLL_THRESHOLD)
			{
				newHSP += SLOW_SCROLL_SPEED;
				
				if (mouseX > width - FAST_SCROLL_THRESHOLD)
					newHSP += FAST_SCROLL_DELTA;
				
				if (maxTextSelectionHScrollPos != -1 && newHSP > maxTextSelectionHScrollPos)
					newHSP = maxTextSelectionHScrollPos;
			}
			
			if (mouseX < SLOW_SCROLL_THRESHOLD)
			{
				newHSP -= SLOW_SCROLL_SPEED;
				
				if (mouseX < FAST_SCROLL_THRESHOLD)
					newHSP -= FAST_SCROLL_DELTA;
				
				if (newHSP < minTextSelectionHScrollPos)
					newHSP = minTextSelectionHScrollPos;
    		}
		}
		
		if (canScrollVertically)
		{
			if (mouseY > height - SLOW_SCROLL_THRESHOLD)
			{
				newVSP += SLOW_SCROLL_SPEED;
				
				if (mouseY > height - FAST_SCROLL_THRESHOLD)
					newVSP += FAST_SCROLL_DELTA;
				
				if (maxTextSelectionVScrollPos != -1 && newVSP > maxTextSelectionVScrollPos)
					newVSP = maxTextSelectionVScrollPos;
			}
			
			if (mouseY < SLOW_SCROLL_THRESHOLD)
			{
				newVSP -= SLOW_SCROLL_SPEED;
				
				if (mouseY < FAST_SCROLL_THRESHOLD)
					newVSP -= FAST_SCROLL_DELTA;
				
				if (newVSP < minTextSelectionVScrollPos)
					newVSP = minTextSelectionVScrollPos;
			}
		}
		
		if (newHSP != viewport.horizontalScrollPosition)
			viewport.horizontalScrollPosition = newHSP;
		if (newVSP != viewport.verticalScrollPosition)
			viewport.verticalScrollPosition = newVSP;
	}

    //--------------------------------------------------------------------------
    //
    //  Event handlers: SoftKeyboard Interaction
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */  
    private function addedToStageHandler(event:Event):void
    {
        if (getStyle("interactionMode") == InteractionMode.TOUCH)
        {
            // Note that we listen for orientationChanging in the capture phase.  This is done so we get the event 
            // before Application does to ensure that the pre-orientation-change dimensions are still in effect.
            // On iOS, Application swaps the dimensions and forces a validation in its orientationChanging handler.
            systemManager.stage.addEventListener("orientationChanging", orientationChangingHandler, true);
        }
    }
    
    /**
     *  @private
     */
    private function removedFromStageHandler(event:Event):void
    {
        if (getStyle("interactionMode") == InteractionMode.TOUCH)
            systemManager.stage.removeEventListener("orientationChanging", orientationChangingHandler, true);
    }
    
    /**
     *  @private
     *  Called when the soft keyboard is activated. 
     * 
     *  There are three use cases for Scroller and text component interaction
     * 
     *  A. Pressing a TextInput to open up the soft keyboard
     *  B. Pressing in the middle of a TextArea to open up the soft keyboard
     *  C. Pressing in a text component on a device that doesn't support soft keyboard
     * 
     *  For use case A, lastFocusedElementCaretBounds is never set, so we just
     *  call ensureElementIsVisible on the TextInput
     * 
     *  For use case B, we first get a softKeyboard active event in the 
     *  capture phase. We then receive a caretBoundsChange event from the 
     *  TextArea skin. We store the bounds in lastFocusedElementCaretBounds
     *  and use that value in the call to ensureElementPositionIsVisible in
     *  the softKeyboard activate bubble phase. 
     * 
     *  For use case C, we never receive a soft keyboard activate event, so 
     *  we just listen for caretBoundsChange. 
     */  
    private function softKeyboardActivateHandler(event:SoftKeyboardEvent):void
    {
        preventThrows = true;

        // Size of app has changed, so run this logic again
        var keyboardRect:Rectangle = stage.softKeyboardRect;
        
        if (keyboardRect.width > 0 && keyboardRect.height > 0)
        {
            if (lastFocusedElement && ensureElementIsVisibleForSoftKeyboard &&
                (keyboardRect.height != oldSoftKeyboardHeight ||
                 keyboardRect.width != oldSoftKeyboardWidth))
            {
                // lastFocusedElementCaretBounds might have been set in the 
                // caretBoundsChange event handler
                if (lastFocusedElementCaretBounds == null)
                {
                    ensureElementIsVisible(lastFocusedElement);
                }
                else
                {
                    // Only show entire element if we just activated the soft keyboard
                    // If the predictive text bar showed up, we don't want the
                    // the element to jump
                    var isSoftKeyboardActive:Boolean = oldSoftKeyboardHeight > 0 || oldSoftKeyboardWidth > 0;
                    ensureElementPositionIsVisible(lastFocusedElement, lastFocusedElementCaretBounds, !isSoftKeyboardActive);   
                    lastFocusedElementCaretBounds = null;
                }
            }
            
            oldSoftKeyboardHeight = keyboardRect.height;
            oldSoftKeyboardWidth = keyboardRect.width;
        }
    }
    
    /**
     *  @private 
     *  Listen for softKeyboard activate in the capture phase so we know if
     *  we need to delay calling ensureElementPositionIsVisible if we get
     *  a caretBoundsChange event
     */ 
    private function softKeyboardActivateCaptureHandler(event:SoftKeyboardEvent):void
    {
        var keyboardRect:Rectangle = stage.softKeyboardRect;
        
        if (keyboardRect.width > 0 && keyboardRect.height > 0)
        {
            captureNextCaretBoundsChange = true;
        }
    }
    
    /**
     *  @private
     *  Called when the soft keyboard is deactivated. Tells the top level 
     *  application to resize itself and fix the scroll position if necessary
     */ 
    private function softKeyboardDeactivateHandler(event:SoftKeyboardEvent):void
    {   
        // Adjust the scroll position after the application's size is restored. 
        adjustScrollPositionAfterSoftKeyboardDeactivate();
        oldSoftKeyboardHeight = NaN;
        oldSoftKeyboardWidth = NaN;
        preventThrows = false;
    }
    
    /**
     *  @private
     */ 
    mx_internal function adjustScrollPositionAfterSoftKeyboardDeactivate():void
    {      
        // If the throw animation is still playing, stop it.
        if (throwEffect && throwEffect.isPlaying)
            throwEffect.stop();
        
        // Fix the scroll position in case we're off the end from the animation
        snapContentScrollPosition();
    }
    
    /**
     *  @private
     * 
     *  If we just received a softKeyboardActivate event in the capture phase,
     *  we will wait until the bubble phase to call ensureElementPositionIsVisible
     *  For now, store the caret bounds to be used. 
     */
    private function caretBoundsChangeHandler(event:CaretBoundsChangeEvent):void
    {
        if (event.isDefaultPrevented())
            return;
        
        event.preventDefault();

        if (captureNextCaretBoundsChange)
        {
            lastFocusedElementCaretBounds = event.newCaretBounds;
            captureNextCaretBoundsChange = false;
            return;
        }
        
        // If caretBounds is changing, minimize the scroll
        ensureElementPositionIsVisible(lastFocusedElement, event.newCaretBounds, false, false);
    }
}

}
