Transferred from the Adobe Open Source Subversion Repository

Revision: 8
Author:   open-source-svn-admin@adobe.com
Date:     2007-12-15T01:49:31.087529Z

Log Message:
-----------
The beginning of the open-source Flex SDK.

Populated the flex/sdk/trunk directory with an open-source subset of files from //depot/flex/sdk/...@191097 in the Faramir Perforce server. This changelist is a bit past the 3.0rc0 build.

The Ant scripts will not successfully build yet. They need to be adapted to the open-source subset.

Modified Paths:
--------------
2532 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1269223 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/mx/src/mx/core/Container.as
+++ frameworks/projects/mx/src/mx/core/Container.as
@@ -0,0 +1,5078 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  ADOBE SYSTEMS INCORPORATED
+//  Copyright 2003-2007 Adobe Systems Incorporated
+//  All Rights Reserved.
+//
+//  NOTICE: Adobe permits you to use, modify, and distribute this file
+//  in accordance with the terms of the license agreement accompanying it.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package mx.core
+{
+
+import flash.display.DisplayObject;
+import flash.display.DisplayObjectContainer;
+import flash.display.Graphics;
+import flash.display.InteractiveObject;
+import flash.display.Loader;
+import flash.display.Shape;
+import flash.display.Sprite;
+import flash.events.Event;
+import flash.events.KeyboardEvent;
+import flash.events.MouseEvent;
+import flash.geom.Point;
+import flash.geom.Rectangle;
+import flash.text.TextField;
+import flash.text.TextLineMetrics;
+import flash.ui.Keyboard;
+import flash.utils.getDefinitionByName;
+
+import mx.binding.BindingManager;
+import mx.controls.Button;
+import mx.controls.HScrollBar;
+import mx.controls.VScrollBar;
+import mx.controls.listClasses.IListItemRenderer;
+import mx.controls.scrollClasses.ScrollBar;
+import mx.events.ChildExistenceChangedEvent;
+import mx.events.FlexEvent;
+import mx.events.IndexChangedEvent;
+import mx.events.ScrollEvent;
+import mx.events.ScrollEventDetail;
+import mx.events.ScrollEventDirection;
+import mx.graphics.RoundedRectangle;
+import mx.managers.IFocusManager;
+import mx.managers.IFocusManagerContainer;
+import mx.managers.ILayoutManagerClient;
+import mx.managers.ISystemManager;
+import mx.styles.CSSStyleDeclaration;
+import mx.styles.ISimpleStyleClient;
+import mx.styles.IStyleClient;
+import mx.styles.StyleManager;
+import mx.styles.StyleProtoChain;
+
+use namespace mx_internal;
+
+//--------------------------------------
+//  Events
+//--------------------------------------
+
+/**
+ *  Dispatched after a child has been added to a container.
+ *
+ *
The childAdd event is dispatched when the addChild()
+ *  or addChildAt() method is called.
+ *  When a container is first created, the addChild()
+ *  method is automatically called for each child component declared
+ *  in the MXML file.
+ *  The addChildAt() method is automatically called
+ *  whenever a Repeater object adds or removes child objects.
+ *  The application developer may also manually call these
+ *  methods to add new children.

+ *
+ *
At the time when this event is sent, the child object has been
+ *  initialized, but its width and height have not yet been calculated,
+ *  and the child has not been drawn on the screen.
+ *  If you want to be notified when the child has been fully initialized
+ *  and rendered, then register as a listener for the child's
+ *  creationComplete event.

+ *
+ *  @eventType mx.events.ChildExistenceChangedEvent.CHILD_ADD
+ */
+[Event(name="childAdd", type="mx.events.ChildExistenceChangedEvent")]
+
+/**
+ *  Dispatched after the index (among the container children)
+ *  of a container child changes.
+ *  This event is only dispatched for the child specified as the argument to
+ *  the setChildIndex() method; it is not dispatched
+ *  for any other child whose index changes as a side effect of the call
+ *  to the setChildIndex() method.
+ *
+ *
The child's index is changed when the
+ *  setChildIndex() method is called.

+ *
+ *  @eventType mx.events.IndexChangedEvent.CHILD_INDEX_CHANGE
+ */
+[Event(name="childIndexChange", type="mx.events.IndexChangedEvent")]
+
+/**
+ *  Dispatched before a child of a container is removed.
+ *
+ *
This event is delivered when any of the following methods is called:
+ *  removeChild(), removeChildAt(),
+ *  or removeAllChildren().

+ *
+ *  @eventType mx.events.ChildExistenceChangedEvent.CHILD_REMOVE
+ */
+[Event(name="childRemove", type="mx.events.ChildExistenceChangedEvent")]
+
+/**
+ *  Dispatched when the data property changes.
+ *
+ *
When a container is used as a renderer in a List or other components,
+ *  the data property is used pass to the container
+ *  the data to display.

+ *
+ *  @eventType mx.events.FlexEvent.DATA_CHANGE
+ */
+[Event(name="dataChange", type="mx.events.FlexEvent")]
+
+/**
+ *  Dispatched when the user manually scrolls the container.
+ *
+ *
The event is dispatched when the scroll position is changed using
+ *  either the mouse (e.g. clicking on the scrollbar's "down" button)
+ *  or the keyboard (e.g., clicking on the down-arrow key).
+ *  However, this event is not dispatched if the scroll position
+ *  is changed programatically (e.g., setting the value of the
+ *  horizontalScrollPosition property).
+ *  The viewChanged event is delivered whenever the
+ *  scroll position is changed, either manually or programatically.

+ *
+ *
At the time when this event is dispatched, the scrollbar has
+ *  been updated to the new position, but the container's child objects
+ *  have not been shifted to reflect the new scroll position.

+ *
+ *  @eventType mx.events.ScrollEvent.SCROLL
+ */
+[Event(name="scroll", type="mx.events.ScrollEvent")]
+
+//--------------------------------------
+//  Styles
+//--------------------------------------
+
+include "../styles/metadata/BarColorStyle.as"
+include "../styles/metadata/BorderStyles.as"
+include "../styles/metadata/PaddingStyles.as"
+include "../styles/metadata/TextStyles.as"
+
+/**
+ *  If a background image is specified, this style specifies
+ *  whether it is fixed with regard to the viewport ("fixed")
+ *  or scrolls along with the content ("scroll").
+ *
+ *  @default "scroll"
+ */
+[Style(name="backgroundAttachment", type="String", inherit="no")]
+
+/**
+ *  The alpha value for the overlay that is placed on top of the
+ *  container when it is disabled.
+ */
+[Style(name="disabledOverlayAlpha", type="Number", inherit="no")]
+
+/**
+ *  The name of the horizontal scrollbar style.
+ *
+ *  @default undefined
+ */
+[Style(name="horizontalScrollBarStyleName", type="String", inherit="no")]
+
+/**
+ *  The name of the vertical scrollbar style.
+ *
+ *  @default undefined
+ */
+[Style(name="verticalScrollBarStyleName", type="String", inherit="no")]
+
+/**
+ *  Number of pixels between the container's bottom border
+ *  and the bottom of its content area.
+ *
+ *  @default 0
+ */
+[Style(name="paddingBottom", type="Number", format="Length", inherit="no")]
+
+/**
+ *  Number of pixels between the container's top border
+ *  and the top of its content area.
+ *
+ *  @default 0
+ */
+[Style(name="paddingTop", type="Number", format="Length", inherit="no")]
+
+[ResourceBundle("core")]
+
+/**
+ *  The Container class is an abstract base class for components that
+ *  controls the layout characteristics of child components.
+ *  You do not create an instance of Container in an application.
+ *  Instead, you create an instance of one of Container's subclasses,
+ *  such as Canvas or HBox.
+ *
+ *
The Container class contains the logic for scrolling, clipping,
+ *  and dynamic instantiation.
+ *  It contains methods for adding and removing children.
+ *  It also contains the getChildAt() method, and the logic
+ *  for drawing the background and borders of containers.

+ *
+ *  @mxml
+ *
+ *  Flex Framework containers inherit the following attributes from the Container
+ *  class:

+ *
+ *

+ *  <mx:tagname
+ *    Properties
+ *    autoLayout="true|false"
+ *    clipContent="true|false"
+ *    creationIndex="undefined"
+ *    creationPolicy="auto|all|queued|none"
+ *    defaultButton="No default"
+ *    horizontalLineScrollSize="5"
+ *    horizontalPageScrollSize="0"
+ *    horizontalScrollBar="null"
+ *    horizontalScrollPolicy="auto|on|off"
+ *    horizontalScrollPosition="0"
+ *    icon="undefined"
+ *    label=""
+ *    verticalLineScrollSize="5"
+ *    verticalPageScrollSize="0"
+ *    verticalScrollBar="null"
+ *    verticalScrollPolicy="auto|on|off"
+ *    verticalScrollPosition="0"
+ *
+ *    Styles
+ *    backgroundAlpha="1.0"
+ *    backgroundAttachment="scroll"
+ *    backgroundColor="undefined"
+ *    backgroundDisabledColor="undefined"
+ *    backgroundImage="undefined"
+ *    backgroundSize="auto"
+ *        For the Application container only, backgroundSize="100%"
+ *    barColor="undefined"
+ *    borderColor="0xAAB3B3"
+ *    borderSides="left top right bottom"
+ *    borderSkin="mx.skins.halo.HaloBorder"
+ *    borderStyle="inset"
+ *    borderThickness="1"
+ *    color="0x0B333C"
+ *    cornerRadius="0"
+ *    disabledColor="0xAAB3B3"
+ *    disbledOverlayAlpha="undefined"
+ *    dropShadowColor="0x000000"
+ *    dropShadowEnabled="false"
+ *    fontAntiAliasType="advanced"
+ *    fontfamily="Verdana"
+ *    fontGridFitType="pixel"
+ *    fontSharpness="0""
+ *    fontSize="10"
+ *    fontStyle="normal"
+ *    fontThickness="0"
+ *    fontWeight="normal"
+ *    horizontalScrollBarStyleName="undefined"
+ *    paddingBottom="0"
+ *    paddingLeft="0"
+ *    paddingRight="0"
+ *    paddingTop="0"
+ *    shadowDirection="center"
+ *    shadowDistance="2"
+ *    textAlign="left"
+ *    textDecoration="none|underline"
+ *    textIndent="0"
+ *    verticalScrollBarStyleName="undefined"
+ *
+ *    Events
+ *    childAdd="No default"
+ *    childIndexChange="No default"
+ *    childRemove="No default"
+ *    dataChange="No default"
+ *    scroll="No default"
+ *    >
+ *      ...
+ *      child tags
+ *      ...
+ *  </mx:tagname>
+ *

+ */
+public class Container extends UIComponent
+                       implements IContainer, IDataRenderer,
+                       IFocusManagerContainer, IListItemRenderer,
+                       IRawChildrenContainer
+{
+    include "../core/Version.as"
+
+    //--------------------------------------------------------------------------
+    //
+    //  Notes: Child management
+    //
+    //--------------------------------------------------------------------------
+
+    /*
+
+        Although at the level of a Flash DisplayObjectContainer, all
+        children are equal, in a Flex Container some children are "more
+        equal than others". (George Orwell, "Animal Farm")
+
+        In particular, Flex distinguishes between content children and
+        non-content (or "chrome") children. Content children are the kind
+        that can be specified in MXML. If you put several controls
+        into a VBox, those are its content children. Non-content children
+        are the other ones that you get automatically, such as a
+        background/border, scrollbars, the titlebar of a Panel,
+        AccordionHeaders, etc.
+
+        Most application developers are uninterested in non-content children,
+        so Container overrides APIs such as numChildren and getChildAt()
+        to deal only with content children. For example, Container, keeps
+        its own _numChildren counter.
+
+        Container assumes that content children are contiguous, and that
+        non-content children come before or after the content children.
+        In order words, Container partitions DisplayObjectContainer's
+        index range into three parts:
+
+        A B C D E F G H I
+        0 1 2 3 4 5 6 7 8    <- index for all children
+              0 1 2 3        <- index for content children
+
+        The content partition contains the content children D E F G.
+        The pre-content partition contains the non-content children
+        A B C that always stay before the content children.
+        The post-content partition contains the non-content children
+        H I that always stay after the content children.
+
+        Container maintains two state variables, _firstChildIndex
+        and _numChildren, which keep track of the partitioning.
+        In this example, _firstChildIndex would be 3 and _numChildren
+        would be 4.
+
+    */
+
+    //--------------------------------------------------------------------------
+    //
+    //  Class constants
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  See changedStyles, below
+     */
+    private static const MULTIPLE_PROPERTIES:String = "<MULTIPLE>";
+
+    //--------------------------------------------------------------------------
+    //
+    //  Class methods
+    //
+    //--------------------------------------------------------------------------
+
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Constructor.
+     */
+    public function Container()
+    {
+        super();
+
+        // By default, containers cannot receive focus but their children can.
+        tabChildren = true;
+        tabEnabled = false;
+
+        showInAutomationHierarchy = false;
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Variables
+    //
+    //--------------------------------------------------------------------------
+
+    //----------------------------------
+    //  Child creation vars
+    //----------------------------------
+
+    /**
+     *  The creation policy of this container.
+     *  This property is useful when the container inherits its creation policy
+     *  from its parent container.
+     */
+    protected var actualCreationPolicy:String;
+
+    /**
+     *  @private
+     */
+    private var numChildrenBefore:int;
+
+    /**
+     *  @private
+     */
+    private var recursionFlag:Boolean = true;
+
+    //----------------------------------
+    //  Layout vars
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Remember when a child has been added or removed.
+     *  When that occurs, we want to run the LayoutManager
+     *  (even if autoLayout is false).
+     */
+    private var forceLayout:Boolean = false;
+
+    /**
+     *  @private
+     */
+    mx_internal var doingLayout:Boolean = false;
+
+    //----------------------------------
+    //  Style vars
+    //----------------------------------
+
+    /**
+     *  @private
+     *  If this value is non-null, then we need to recursively notify children
+     *  that a style property has changed.  If one style property has changed,
+     *  this field holds the name of the style that changed.  If multiple style
+     *  properties have changed, then the value of this field is
+     *  Container.MULTIPLE_PROPERTIES.
+     */
+    private var changedStyles:String = null;
+
+    //----------------------------------
+    //  Scrolling vars
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    private var _creatingContentPane:Boolean = false;
+
+    /**
+     *  Containers use an internal content pane to control scrolling.
+     *  The creatingContentPane is true while the container is creating
+     *  the content pane so that some events can be ignored or blocked.
+     */
+    public function get creatingContentPane():Boolean
+    {
+        return _creatingContentPane;
+    }
+    public function set creatingContentPane(value:Boolean):void
+    {
+        _creatingContentPane = value;
+    }
+
+    /**
+     *  @private
+     *  A box that takes up space in the lower right corner,
+     *  between the horizontal and vertical scrollbars.
+     */
+    protected var whiteBox:Shape;
+
+    /**
+     *  @private
+     */
+    mx_internal var contentPane:Sprite = null;
+
+    /**
+     *  @private
+     *  Flags that remember what work to do during the next updateDisplayList().
+     */
+    private var scrollPropertiesChanged:Boolean = false;
+    private var scrollPositionChanged:Boolean = true;
+    private var horizontalScrollPositionPending:Number;
+    private var verticalScrollPositionPending:Number;
+
+    /**
+     *  @private
+     *  Cached values describing the total size of the content being scrolled
+     *  and the size of the area in which the scrolled content is displayed.
+     */
+    private var scrollableWidth:Number = 0;
+    private var scrollableHeight:Number = 0;
+    private var viewableWidth:Number = 0;
+    private var viewableHeight:Number = 0;
+
+    //----------------------------------
+    //  Other vars
+    //----------------------------------
+
+    /**
+     *  @private
+     *  The border/background object.
+     */
+    mx_internal var border:IFlexDisplayObject;
+
+    /**
+     *  @private
+     *  Sprite used to block user input when the container is disabled.
+     */
+    mx_internal var blocker:Sprite;
+
+    /**
+     *  @private
+     *  Keeps track of the number of mouse events we are listening for
+     */
+    private var mouseEventReferenceCount:int = 0;
+
+    //--------------------------------------------------------------------------
+    //
+    //  Overridden properties
+    //
+    //--------------------------------------------------------------------------
+
+    //----------------------------------
+    //  baselinePosition
+    //----------------------------------
+
+    /**
+     *  @private
+     *  The baselinePosition of a Container is calculated
+     *  as if there was a UITextField using the Container's styles
+     *  whose top is at viewMetrics.top.
+     */
+    override public function get baselinePosition():Number
+    {
+        if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_3_0)
+        {
+            // If we have a verticalAlignment of top,
+            // then return the baseline of our first child
+            if (getStyle("verticalAlign") == "top" && numChildren > 0)
+            {
+                var child:IUIComponent = getChildAt(0) as IUIComponent;
+                if (child)
+                    return child.y + child.baselinePosition;
+            }
+
+            return super.baselinePosition;
+        }
+
+        if (!validateBaselinePosition())
+            return NaN;
+
+        // Unless the height is very small, the baselinePosition
+        // of a generic Container is calculated as if there was
+        // a UITextField using the Container's styles
+        // whose top is at viewMetrics.top.
+        // If the height is small, the baselinePosition is calculated
+        // as if there were text within whose ascent the Container
+        // is vertically centered.
+        // At the crossover height, these two calculations
+        // produce the same result.
+
+        var lineMetrics:TextLineMetrics = measureText("Wj");
+
+        if (height < 2 * viewMetrics.top + 4 + lineMetrics.ascent)
+            return int(height + (lineMetrics.ascent - height) / 2);
+
+        return viewMetrics.top + 2 + lineMetrics.ascent;
+    }
+
+    //----------------------------------
+    //  contentMouseX
+    //----------------------------------
+
+    /**
+     *  @copy mx.core.UIComponent#contentMouseX
+     */
+    override public function get contentMouseX():Number
+    {
+        if (contentPane)
+            return contentPane.mouseX;
+
+        return super.contentMouseX;
+    }
+
+    //----------------------------------
+    //  contentMouseY
+    //----------------------------------
+
+    /**
+     *  @copy mx.core.UIComponent#contentMouseY
+     */
+    override public function get contentMouseY():Number
+    {
+        if (contentPane)
+            return contentPane.mouseY;
+
+        return super.contentMouseY;
+    }
+
+    //----------------------------------
+    //  doubleClickEnabled
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Propagate to children.
+     */
+    override public function set doubleClickEnabled(value:Boolean):void
+    {
+        super.doubleClickEnabled = value;
+
+        if (contentPane)
+        {
+            var n:int = contentPane.numChildren;
+            for (var i:int = 0; i < n; i++)
+            {
+                var child:InteractiveObject =
+                    contentPane.getChildAt(i) as InteractiveObject;
+                if (child)
+                    child.doubleClickEnabled = value;
+            }
+        }
+    }
+
+    //----------------------------------
+    //  enabled
+    //----------------------------------
+
+    [Inspectable(category="General", enumeration="true,false", defaultValue="true")]
+
+    /**
+     *  @private
+     */
+    override public function set enabled(value:Boolean):void
+    {
+        super.enabled = value;
+
+        // Scrollbars must be enabled/disabled when this container is.
+        if (horizontalScrollBar)
+            horizontalScrollBar.enabled = value;
+        if (verticalScrollBar)
+            verticalScrollBar.enabled = value;
+
+        invalidateProperties();
+    }
+
+    //----------------------------------
+    //  focusPane
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the focusPane property.
+     */
+    private var _focusPane:Sprite;
+
+    /**
+     *  @private
+     *  Focus pane associated with this object.
+     *  An object has a focus pane when one of its children has got focus.
+     */
+    override public function get focusPane():Sprite
+    {
+        return _focusPane;
+    }
+
+    /**
+     *  @private
+     */
+    override public function set focusPane(o:Sprite):void
+    {
+        // The addition or removal of the focus sprite should not trigger
+        // a measurement/layout pass.  Temporarily set the invalidation flags,
+        // so that calls to invalidateSize() and invalidateDisplayList() have
+        // no effect.
+        var oldInvalidateSizeFlag:Boolean = invalidateSizeFlag;
+        var oldInvalidateDisplayListFlag:Boolean = invalidateDisplayListFlag;
+        invalidateSizeFlag = true;
+        invalidateDisplayListFlag = true;
+
+        if (o)
+        {
+            rawChildren.addChild(o);
+
+            o.x = 0;
+            o.y = 0;
+            o.scrollRect = null;
+
+            _focusPane = o;
+        }
+        else
+        {
+            rawChildren.removeChild(_focusPane);
+
+            _focusPane = null;
+        }
+
+        if (o && contentPane)
+        {
+            o.x = contentPane.x;
+            o.y = contentPane.y;
+            o.scrollRect = contentPane.scrollRect;
+        }
+
+        invalidateSizeFlag = oldInvalidateSizeFlag;
+        invalidateDisplayListFlag = oldInvalidateDisplayListFlag;
+    }
+
+    //----------------------------------
+    //  $numChildren
+    //----------------------------------
+
+    /**
+     *  @private
+     *  This property allows access to the Player's native implementation
+     *  of the numChildren property, which can be useful since components
+     *  can override numChildren and thereby hide the native implementation.
+     *  Note that this "base property" is final and cannot be overridden,
+     *  so you can count on it to reflect what is happening at the player level.
+     */
+    mx_internal final function get $numChildren():int
+    {
+        return super.numChildren;
+    }
+
+    //----------------------------------
+    //  numChildren
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the numChildren property.
+     */
+    mx_internal var _numChildren:int = 0;
+
+    /**
+     *  Number of child components in this container.
+     *
+     *
The number of children is initially equal
+     *  to the number of children declared in MXML.
+     *  At runtime, new children may be added by calling
+     *  addChild() or addChildAt(),
+     *  and existing children may be removed by calling
+     *  removeChild(), removeChildAt(),
+     *  or removeAllChildren().

+     */
+    override public function get numChildren():int
+    {
+        return contentPane ? contentPane.numChildren : _numChildren;
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Properties
+    //
+    //--------------------------------------------------------------------------
+
+    //----------------------------------
+    //  autoLayout
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the autoLayout property.
+     */
+    private var _autoLayout:Boolean = true;
+
+    [Inspectable(defaultValue="true")]
+
+    /**
+     *  If true, measurement and layout are done
+     *  when the position or size of a child is changed.
+     *  If false, measurement and layout are done only once,
+     *  when children are added to or removed from the container.
+     *
+     *
When using the Move effect, the layout around the component that
+     *  is moving does not readjust to fit that the Move effect animates.
+     *  Setting a container's autoLayout property to
+     *  true has no effect on this behavior.

+     *
+     *
The Zoom effect does not work when the autoLayout
+     *  property is false.

+     *
+     *
The autoLayout property does not apply to
+     *  Accordion or ViewStack containers.

+     *
+     *  @default true
+     */
+    public function get autoLayout():Boolean
+    {
+        return _autoLayout;
+    }
+
+    /**
+     *  @private
+     */
+    public function set autoLayout(value:Boolean):void
+    {
+        _autoLayout = value;
+
+        // If layout is being turned back on, trigger a layout to occur now.
+        if (value)
+        {
+            invalidateSize();
+            invalidateDisplayList();
+
+            var p:IInvalidating = parent as IInvalidating;
+            if (p)
+            {
+                p.invalidateSize();
+                p.invalidateDisplayList();
+            }
+        }
+    }
+
+    //----------------------------------
+    //  borderMetrics
+    //----------------------------------
+
+    /**
+     *  Returns an EdgeMetrics object that has four properties:
+     *  left, top, right,
+     *  and bottom.
+     *  The value of each property is equal to the thickness of one side
+     *  of the border, expressed in pixels.
+     *
+     *
Unlike viewMetrics, this property is not
+     *  overriden by subclasses of Container.

+     */
+    public function get borderMetrics():EdgeMetrics
+    {
+        return border && border is IBorder ?
+               IBorder(border).borderMetrics :
+               EdgeMetrics.EMPTY;
+    }
+
+    //----------------------------------
+    //  childDescriptors
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the childDescriptors property.
+     *  This variable is initialized in the construct() method
+     *  using the childDescriptors in the initObj, which is autogenerated.
+     *  If this Container was not created by createComponentFromDescriptor(),
+     *  its childDescriptors property is null.
+     */
+    private var _childDescriptors:Array /* of UIComponentDescriptor */;
+
+    /**
+     *  Array of UIComponentDescriptor objects produced by the MXML compiler.
+     *
+     *
Each UIComponentDescriptor object contains the information
+     *  specified in one child MXML tag of the container's MXML tag.
+     *  The order of the UIComponentDescriptor objects in the Array
+     *  is the same as the order of the child tags.
+     *  During initialization, the child descriptors are used to create
+     *  the container's child UIComponent objects and its Repeater objects,
+     *  and to give them the initial property values, event handlers, effects,
+     *  and so on, that were specified in MXML.

+     *
+     *  @see mx.core.UIComponentDescriptor
+     */
+    public function get childDescriptors():Array /* of UIComponentDescriptor */
+    {
+        return _childDescriptors;
+    }
+
+    //----------------------------------
+    //  childRepeaters
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the childRepeaters property.
+     */
+    private var _childRepeaters:Array;
+
+    /**
+     *  @private
+     *  An array of the Repeater objects found within this container.
+     */
+    mx_internal function get childRepeaters():Array
+    {
+        return _childRepeaters;
+    }
+
+    /**
+     *  @private
+     */
+    mx_internal function set childRepeaters(value:Array):void
+    {
+        _childRepeaters = value;
+    }
+
+    //----------------------------------
+    //  clipContent
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the clipContent property.
+     */
+    private var _clipContent:Boolean = true;
+
+    [Inspectable(defaultValue="true")]
+
+    /**
+     *  Whether to apply a clip mask if the positions and/or sizes
+     *  of this container's children extend outside the borders of
+     *  this container.
+     *  If false, the children of this container
+     *  remain visible when they are moved or sized outside the
+     *  borders of this container.
+     *  If true, the children of this container are clipped.
+     *
+     *
If clipContent is false, then scrolling
+     *  is disabled for this container and scrollbars will not appear.
+     *  If clipContent is true, then scrollbars will usually
+     *  appear when the container's children extend outside the border of
+     *  the container.
+     *  For additional control over the appearance of scrollbars,
+     *  see horizontalScrollPolicy and verticalScrollPolicy.

+     *
+     *  @default true
+     */
+    public function get clipContent():Boolean
+    {
+        return _clipContent;
+    }
+
+    /**
+     *  @private
+     */
+    public function set clipContent(value:Boolean):void
+    {
+        if (_clipContent != value)
+        {
+            _clipContent = value;
+
+            invalidateDisplayList();
+        }
+    }
+
+    //----------------------------------
+    //  createdComponents
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Internal variable used to keep track of the components created
+     *  by this Container.  This is different than the list maintained
+     *  by DisplayObjectContainer, because it includes Repeaters.
+     */
+    private var _createdComponents:Array;
+
+    /**
+     *  @private
+     *  An array of all components created by this container including
+     *  Repeater components.
+     */
+    mx_internal function get createdComponents():Array
+    {
+        return _createdComponents;
+    }
+
+    /**
+     *  @private
+     */
+    mx_internal function set createdComponents(value:Array):void
+    {
+        _createdComponents = value;
+    }
+
+    //----------------------------------
+    //  creationIndex
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the creationIndex property.
+     */
+    private var _creationIndex:int = -1;
+
+    [Inspectable(defaultValue="undefined")]
+
+    /**
+     *  Specifies the order to instantiate and draw the children
+     *  of the container.
+     *
+     *
This property can only be used when the creationPolicy
+     *  property is set to ContainerCreationPolicy.QUEUED.
+     *  Otherwise, it is ignored.

+     *
+     *  @default -1
+     */
+    public function get creationIndex():int
+    {
+        return _creationIndex;
+    }
+
+    /**
+     *  @private
+     */
+    public function set creationIndex(value:int):void
+    {
+        _creationIndex = value;
+    }
+
+    //----------------------------------
+    //  creationPolicy
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the creationPolicy property.
+     *  This variable is initialized in the construct() method
+     *  using the childDescriptors in the initObj, which is autogenerated.
+     *  If this Container was not created by createComponentFromDescriptor(),
+     *  its childDescriptors property is null.
+     */
+    private var _creationPolicy:String;
+
+    [Inspectable(enumeration="all,auto,queued,none")]
+
+    /**
+     *  The child creation policy for this Container.
+     *  ActionScript values can be ContainerCreationPolicy.AUTO,
+     *  ContainerCreationPolicy.ALL,
+     *  ContainerCreationPolicy.NONE,
+     *  or ContainerCreationPolicy.QUEUED.
+     *  MXML values can be "auto", "all",
+     *  "none", or "queued".
+     *
+     *
If no creationPolicy is specified for a container,
+     *  that container inherits its parent's creationPolicy.
+     *  If no creationPolicy is specified for the Application,
+     *  it defaults to ContainerCreationPolicy.AUTO.

+     *
+     *
A creationPolicy of ContainerCreationPolicy.AUTO means
+     *  that the container delays creating some or all descendants
+     *  until they are needed, a process which is known as deferred
+     *  instantiation.
+     *  This policy produces the best startup time because fewer
+     *  UIComponents are created initially.
+     *  However, this introduces navigation delays when a user navigates
+     *  to other parts of the application for the first time.
+     *  Navigator containers such as Accordion, TabNavigator, and ViewStack
+     *  implement the ContainerCreationPolicy.AUTO policy by creating all their
+     *  children immediately, but wait to create the deeper descendants
+     *  of a child until it becomes the selected child of the navigator
+     *  container.

+     *
+     *
A creationPolicy of ContainerCreationPolicy.ALL means
+     *  that the navigator containers immediately create deeper descendants
+     *  for each child, rather than waiting until that child is
+     *  selected. For single-view containers such as a VBox container,
+     *  there is no difference  between the ContainerCreationPolicy.AUTO and
+     *  ContainerCreationPolicy.ALL policies.

+     *
+     *
A creationPolicy of ContainerCreationPolicy.QUEUED means
+     *  that the container is added to a creation queue rather than being
+     *  immediately instantiated and drawn.
+     *  When the application processes the queued container, it creates
+     *  the children of the container and then waits until the children
+     *  have been created before advancing to the next container in the
+     *  creation queue.

+     *
+     *
A creationPolicy of ContainerCreationPolicy.NONE means
+     *  that the container creates none of its children.
+     *  In that case, it is the responsibility of the MXML author
+     *  to create the children by calling the
+     *  createComponentsFromDescriptors() method.

+     */
+    public function get creationPolicy():String
+    {
+        return _creationPolicy;
+    }
+
+    /**
+     *  @private
+     */
+    public function set creationPolicy(value:String):void
+    {
+        _creationPolicy = value;
+
+        setActualCreationPolicies(value);
+    }
+
+    //----------------------------------
+    //  defaultButton
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the defaultButton property.
+     */
+    private var _defaultButton:IFlexDisplayObject;
+
+    [Inspectable(category="General")]
+
+    /**
+     *  The Button control designated as the default button
+     *  for the container.
+     *  When controls in the container have focus, pressing the
+     *  Enter key is the same as clicking this Button control.
+     *
+     *  @default null
+     */
+    public function get defaultButton():IFlexDisplayObject
+    {
+        return _defaultButton;
+    }
+
+    /**
+     *  @private
+     */
+    public function set defaultButton(value:IFlexDisplayObject):void
+    {
+        _defaultButton = value;
+        ContainerGlobals.focusedContainer = null;
+    }
+
+    //----------------------------------
+    //  data
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the data property.
+     */
+    private var _data:Object;
+
+    [Bindable("dataChange")]
+    [Inspectable(environment="none")]
+
+    /**
+     *  The data property lets you pass a value
+     *  to the component when you use it in an item renderer or item editor.
+     *  You typically use data binding to bind a field of the data
+     *  property to a property of this component.
+     *
+     *
You do not set this property in MXML.

+     *
+     *  @default null
+     *  @see mx.core.IDataRenderer
+     */
+    public function get data():Object
+    {
+        return _data;
+    }
+
+    /**
+     *  @private
+     */
+    public function set data(value:Object):void
+    {
+        _data = value;
+
+        dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
+
+        invalidateDisplayList();
+    }
+
+    //----------------------------------
+    //  firstChildIndex
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the firstChildIndex property.
+     */
+    private var _firstChildIndex:int = 0;
+
+    /**
+     *  @private
+     *  The index of the first content child,
+     *  when dealing with both content and non-content children.
+     */
+    mx_internal function get firstChildIndex():int
+    {
+        return _firstChildIndex;
+    }
+
+    //----------------------------------
+    //  horizontalLineScrollSize
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the horizontalLineScrollSize property.
+     */
+    private var _horizontalLineScrollSize:Number = 5;
+
+    [Bindable("horizontalLineScrollSizeChanged")]
+    [Inspectable(defaultValue="5")]
+
+    /**
+     *  Number of pixels to move when the left- or right-arrow
+     *  button in the horizontal scroll bar is pressed.
+     *
+     *  @default 5
+     */
+    public function get horizontalLineScrollSize():Number
+    {
+        return _horizontalLineScrollSize;
+    }
+
+    /**
+     *  @private
+     */
+    public function set horizontalLineScrollSize(value:Number):void
+    {
+        scrollPropertiesChanged = true;
+
+        _horizontalLineScrollSize = value;
+
+        invalidateDisplayList();
+
+        dispatchEvent(new Event("horizontalLineScrollSizeChanged"));
+    }
+
+    //----------------------------------
+    //  horizontalPageScrollSize
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the horizontalPageScrollSize property.
+     */
+    private var _horizontalPageScrollSize:Number = 0;
+
+    [Bindable("horizontalPageScrollSizeChanged")]
+    [Inspectable(defaultValue="0")]
+
+    /**
+     *  Number of pixels to move when the track in the
+     *  horizontal scroll bar is pressed.
+     *  A value of 0 means that the page size
+     *  will be calculated to be a full screen.
+     *
+     *  @default 0
+     */
+    public function get horizontalPageScrollSize():Number
+    {
+        return _horizontalPageScrollSize;
+    }
+
+    /**
+     *  @private
+     */
+    public function set horizontalPageScrollSize(value:Number):void
+    {
+        scrollPropertiesChanged = true;
+
+        _horizontalPageScrollSize = value;
+
+        invalidateDisplayList();
+
+        dispatchEvent(new Event("horizontalPageScrollSizeChanged"));
+    }
+
+    //----------------------------------
+    //  horizontalScrollBar
+    //----------------------------------
+
+    /**
+     *  @private
+     *  The horizontal scrollbar (null if not present).
+     */
+    private var _horizontalScrollBar:ScrollBar;
+
+    /**
+     *  The horizontal scrollbar used in this container.
+     *  This property is null if no horizontal scroll bar
+     *  is currently displayed.
+     *  In general you do not access this property directly.
+     *  Manipulation of the horizontalScrollPolicy
+     *  and horizontalScrollPosition
+     *  properties should provide sufficient control over the scroll bar.
+     */
+    public function get horizontalScrollBar():ScrollBar
+    {
+        return _horizontalScrollBar;
+    }
+
+    /**
+     *  @private
+     */
+    public function set horizontalScrollBar(value:ScrollBar):void
+    {
+        _horizontalScrollBar = value;
+    }
+
+    //----------------------------------
+    //  horizontalScrollPosition
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the horizontalScrollPosition property.
+     */
+    private var _horizontalScrollPosition:Number = 0;
+
+    [Bindable("scroll")]
+    [Bindable("viewChanged")]
+    [Inspectable(defaultValue="0")]
+
+    /**
+     *  The current position of the horizontal scroll bar.
+     *  This is equal to the distance in pixels between the left edge
+     *  of the scrollable surface and the leftmost piece of the surface
+     *  that is currently visible.
+     *
+     *  @default 0
+     */
+    public function get horizontalScrollPosition():Number
+    {
+        if (!isNaN(horizontalScrollPositionPending))
+            return horizontalScrollPositionPending;
+        return _horizontalScrollPosition;
+    }
+
+    /**
+     *  @private
+     */
+    public function set horizontalScrollPosition(value:Number):void
+    {
+        if (_horizontalScrollPosition == value)
+            return;
+
+        // Note: We can't use maxHorizontalScrollPosition to clamp the value here.
+        // The horizontalScrollBar may not exist yet,
+        // or its maxPos might change during layout.
+        // (For example, you could set the horizontalScrollPosition of a childless container,
+        // then add a child which causes it to have a scrollbar.)
+        // The horizontalScrollPosition gets clamped to the range 0 through maxHorizontalScrollPosition
+        // late, in the updateDisplayList() method, just before the scrollPosition
+        // of the horizontalScrollBar is set.
+
+        _horizontalScrollPosition = value;
+        scrollPositionChanged = true;
+        if (!initialized)
+            horizontalScrollPositionPending = value;
+
+        invalidateDisplayList();
+
+        dispatchEvent(new Event("viewChanged"));
+    }
+
+    //----------------------------------
+    //  horizontalScrollPolicy
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the horizontalScrollPolicy property.
+     */
+    mx_internal var _horizontalScrollPolicy:String = ScrollPolicy.AUTO;
+
+    [Bindable("horizontalScrollPolicyChanged")]
+    [Inspectable(category="General", enumeration="off,on,auto", defaultValue="auto")]
+
+    /**
+     *  Specifies whether the horizontal scroll bar is always present,
+     *  always absent, or automatically added when needed.
+     *  ActionScript values can be ScrollPolicy.ON, ScrollPolicy.OFF,
+     *  and ScrollPolicy.AUTO.
+     *  MXML values can be "on", "off",
+     *  and "auto".
+     *
+     *
Setting this property to ScrollPolicy.OFF also prevents the
+     *  horizontalScrollPosition property from having an effect.

+     *
+     *
Note: This property does not apply to the ControlBar container.

+     *
+     *
If the horizontalScrollPolicy is ScrollPolicy.AUTO,
+     *  the horizontal scroll bar appears when all of the following
+     *  are true:

+     *

+     *
One of the container's children extends beyond the left
+     *      edge or right edge of the container.

+     *
The clipContent property is true.

+     *
The width and height of the container are large enough to
+     *      reasonably accommodate a scroll bar.

+     *

+     *
+     *  @default ScrollPolicy.AUTO
+     */
+    public function get horizontalScrollPolicy():String
+    {
+        return _horizontalScrollPolicy;
+    }
+
+    /**
+     *  @private
+     */
+    public function set horizontalScrollPolicy(value:String):void
+    {
+        if (_horizontalScrollPolicy != value)
+        {
+            _horizontalScrollPolicy = value;
+
+            invalidateDisplayList();
+
+            dispatchEvent(new Event("horizontalScrollPolicyChanged"));
+        }
+    }
+
+    //----------------------------------
+    //  icon
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the icon property.
+     */
+    private var _icon:Class = null;
+
+    [Bindable("iconChanged")]
+    [Inspectable(category="General", defaultValue="", format="EmbeddedFile")]
+
+    /**
+     *  The Class of the icon displayed by some navigator
+     *  containers to represent this Container.
+     *
+     *
For example, if this Container is a child of a TabNavigator,
+     *  this icon appears in the corresponding tab.
+     *  If this Container is a child of an Accordion,
+     *  this icon appears in the corresponding header.

+     *
+     *
To embed the icon in the SWF file, use the @Embed()
+     *  MXML compiler directive:

+     *
+     *

+     *    icon="@Embed('filepath')"
+     *

+     *
+     *
The image can be a JPEG, GIF, PNG, SVG, or SWF file.

+     *
+     *  @default null
+     */
+    public function get icon():Class
+    {
+        return _icon;
+    }
+
+    /**
+     *  @private
+     */
+    public function set icon(value:Class):void
+    {
+        _icon = value;
+
+        dispatchEvent(new Event("iconChanged"));
+    }
+
+    //----------------------------------
+    //  label
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the label property.
+     */
+    private var _label:String = "";
+
+    [Bindable("labelChanged")]
+    [Inspectable(category="General", defaultValue="")]
+
+    /**
+     *  The text displayed by some navigator containers to represent
+     *  this Container.
+     *
+     *
For example, if this Container is a child of a TabNavigator,
+     *  this string appears in the corresponding tab.
+     *  If this Container is a child of an Accordion,
+     *  this string appears in the corresponding header.

+     *
+     *  @default ""
+     */
+    public function get label():String
+    {
+        return _label;
+    }
+
+    /**
+     *  @private
+     */
+    public function set label(value:String):void
+    {
+        _label = value;
+
+        dispatchEvent(new Event("labelChanged"));
+    }
+
+    //----------------------------------
+    //  maxHorizontalScrollPosition
+    //----------------------------------
+
+    /**
+     *  The largest possible value for the
+     *  horizontalScrollPosition property.
+     *  Defaults to 0 if the horizontal scrollbar is not present.
+     */
+    public function get maxHorizontalScrollPosition():Number
+    {
+        return horizontalScrollBar ?
+               horizontalScrollBar.maxScrollPosition :
+               Math.max(scrollableWidth - viewableWidth, 0);
+    }
+
+    //----------------------------------
+    //  maxVerticalScrollPosition
+    //----------------------------------
+
+    /**
+     *  The largest possible value for the
+     *  verticalScrollPosition property.
+     *  Defaults to 0 if the vertical scrollbar is not present.
+     */
+    public function get maxVerticalScrollPosition():Number
+    {
+        return verticalScrollBar ?
+               verticalScrollBar.maxScrollPosition :
+               Math.max(scrollableHeight - viewableHeight, 0);
+    }
+
+    //----------------------------------
+    //  numChildrenCreated
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    private var _numChildrenCreated:int = -1;
+
+    /**
+     *  @private
+     *  The number of children created inside this container.
+     *  The default value is 0.
+     */
+    mx_internal function get numChildrenCreated():int
+    {
+        return _numChildrenCreated;
+    }
+
+    /**
+     *  @private
+     */
+    mx_internal function set numChildrenCreated(value:int):void
+    {
+        _numChildrenCreated = value;
+    }
+
+    //----------------------------------
+    //  numRepeaters
+    //----------------------------------
+
+    /**
+     *  @private
+     *  The number of Repeaters in this Container.
+     *
+     *
This number includes Repeaters that are immediate children of this
+     *  container and Repeaters that are nested inside other Repeaters.
+     *  Consider the following example:

+     *
+     *

+     *  <mx:HBox>
+     *    <mx:Repeater dataProvider="[1, 2]">
+     *      <mx:Repeater dataProvider="...">
+     *        <mx:Button/>
+     *      </mx:Repeater>
+     *    </mx:Repeater>
+     *  <mx:HBox>
+     *

+     *
+     *
In this example, the numRepeaters property
+     *  for the HBox would be set equal to 3 -- one outer Repeater
+     *  and two inner repeaters.

+     *
+     *
The numRepeaters property does not include Repeaters
+     *  that are nested inside other containers.
+     *  Consider this example:

+     *
+     *

+     *  <mx:HBox>
+     *    <mx:Repeater dataProvider="[1, 2]">
+     *      <mx:VBox>
+     *        <mx:Repeater dataProvider="...">
+     *          <mx:Button/>
+     *        </mx:Repeater>
+     *      </mx:VBox>
+     *    </mx:Repeater>
+     *  <mx:HBox>
+     *

+     *
+     *
In this example, the numRepeaters property
+     *  for the outer HBox would be set equal to 1 -- just the outer repeater.
+     *  The two inner VBox containers would also have a
+     *  numRepeaters property equal to 1 -- one Repeater
+     *  per VBox.

+     */
+    mx_internal function get numRepeaters():int
+    {
+        return childRepeaters ? childRepeaters.length : 0;
+    }
+
+    //----------------------------------
+    //  rawChildren
+    //----------------------------------
+
+    /**
+     *  @private
+     *  The single IChildList object that's always returned
+     *  from the rawChildren property, below.
+     */
+    private var _rawChildren:ContainerRawChildrenList;
+
+    /**
+     *  A container typically contains child components, which can be enumerated
+     *  using the Container.getChildAt() method and
+     *  Container.numChildren property.  In addition, the container
+     *  may contain style elements and skins, such as the border and background.
+     *  Flash Player and AIR do not draw any distinction between child components
+     *  and skins.  They are all accessible using the player's
+     *  getChildAt() method  and
+     *  numChildren property.
+     *  However, the Container class overrides the getChildAt() method
+     *  and numChildren property (and several other methods)
+     *  to create the illusion that
+     *  the container's children are the only child components.
+     *
+     *
If you need to access all of the children of the container (both the
+     *  content children and the skins), then use the methods and properties
+     *  on the rawChildren property instead of the regular Container methods.
+     *  For example, use the Container.rawChildren.getChildAt()) method.
+     *  However, if a container creates a ContentPane Sprite object for its children,
+     *  the rawChildren property value only counts the ContentPane, not the
+     *  container's children.
+     *  It is not always possible to determine when a container will have a ContentPane.

+     *
+     *
Note:If you call the addChild or
+     *  addChildAtmethod of the rawChildren object,
+     *  set tabEnabled = false on the component that you have added.
+     *  Doing so prevents users from tabbing to the visual-only component
+     *  that you have added.

+     */
+    public function get rawChildren():IChildList
+    {
+        if (!_rawChildren)
+            _rawChildren = new ContainerRawChildrenList(this);
+
+        return _rawChildren;
+    }
+
+    //----------------------------------
+    //  usePadding
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    mx_internal function get usePadding():Boolean
+    {
+        // Containers, by default, always use padding.
+        return true;
+    }
+
+    //----------------------------------
+    //  verticalLineScrollSize
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the verticalLineScrollSize property.
+     */
+    private var _verticalLineScrollSize:Number = 5;
+
+    [Bindable("verticalLineScrollSizeChanged")]
+    [Inspectable(defaultValue="5")]
+
+    /**
+     *  Number of pixels to scroll when the up- or down-arrow
+     *  button in the vertical scroll bar is pressed,
+     *  or when you scroll by using the mouse wheel.
+     *
+     *  @default 5
+     */
+    public function get verticalLineScrollSize():Number
+    {
+        return _verticalLineScrollSize;
+    }
+
+    /**
+     *  @private
+     */
+    public function set verticalLineScrollSize(value:Number):void
+    {
+        scrollPropertiesChanged = true;
+
+        _verticalLineScrollSize = value;
+
+        invalidateDisplayList();
+
+        dispatchEvent(new Event("verticalLineScrollSizeChanged"));
+    }
+
+    //----------------------------------
+    //  verticalPageScrollSize
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the verticalPageScrollSize property.
+     */
+    private var _verticalPageScrollSize:Number = 0;
+
+    [Bindable("verticalPageScrollSizeChanged")]
+    [Inspectable(defaultValue="0")]
+
+    /**
+     *  Number of pixels to scroll when the track
+     *  in the vertical scroll bar is pressed.
+     *  A value of 0 means that the page size
+     *  will be calculated to be a full screen.
+     *
+     *  @default 0
+     */
+    public function get verticalPageScrollSize():Number
+    {
+        return _verticalPageScrollSize;
+    }
+
+    /**
+     *  @private
+     */
+    public function set verticalPageScrollSize(value:Number):void
+    {
+        scrollPropertiesChanged = true;
+
+        _verticalPageScrollSize = value;
+
+        invalidateDisplayList();
+
+        dispatchEvent(new Event("verticalPageScrollSizeChanged"));
+    }
+
+    //----------------------------------
+    //  verticalScrollBar
+    //----------------------------------
+
+    /**
+     *  @private
+     *  The vertical scrollbar (null if not present).
+     */
+    private var _verticalScrollBar:ScrollBar;
+
+    /**
+     *  The vertical scrollbar used in this container.
+     *  This property is null if no vertical scroll bar
+     *  is currently displayed.
+     *  In general you do not access this property directly.
+     *  Manipulation of the verticalScrollPolicy
+     *  and verticalScrollPosition
+     *  properties should provide sufficient control over the scroll bar.
+     */
+    public function get verticalScrollBar():ScrollBar
+    {
+        return _verticalScrollBar;
+    }
+
+    /**
+     *  @private
+     */
+    public function set verticalScrollBar(value:ScrollBar):void
+    {
+        _verticalScrollBar = value;
+    }
+
+    //----------------------------------
+    //  verticalScrollPosition
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the verticalScrollPosition property.
+     */
+    private var _verticalScrollPosition:Number = 0;
+
+    [Bindable("scroll")]
+    [Bindable("viewChanged")]
+    [Inspectable(defaultValue="0")]
+
+    /**
+     *  The current position of the vertical scroll bar.
+     *  This is equal to the distance in pixels between the top edge
+     *  of the scrollable surface and the topmost piece of the surface
+     *  that is currently visible.
+     *
+     *  @default 0
+     */
+    public function get verticalScrollPosition():Number
+    {
+        if (!isNaN(verticalScrollPositionPending))
+            return verticalScrollPositionPending;
+
+        return _verticalScrollPosition;
+    }
+
+    /**
+     *  @private
+     */
+    public function set verticalScrollPosition(value:Number):void
+    {
+        if (_verticalScrollPosition == value)
+            return;
+
+        // Note: We can't use maxVerticalScrollPosition to clamp the value here.
+        // The verticalScrollBar may not exist yet,
+        // or its maxPos might change during layout.
+        // (For example, you could set the verticalScrollPosition of a childless container,
+        // then add a child which causes it to have a scrollbar.)
+        // The verticalScrollPosition gets clamped to the range 0 through maxVerticalScrollPosition
+        // late, in the updateDisplayList() method, just before the scrollPosition
+        // of the verticalScrollBar is set.
+
+        _verticalScrollPosition = value;
+        scrollPositionChanged = true;
+        if (!initialized)
+            verticalScrollPositionPending = value;
+
+        invalidateDisplayList();
+
+        dispatchEvent(new Event("viewChanged"));
+    }
+
+    //----------------------------------
+    //  verticalScrollPolicy
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the verticalScrollPolicy property.
+     */
+    mx_internal var _verticalScrollPolicy:String = ScrollPolicy.AUTO;
+
+    [Bindable("verticalScrollPolicyChanged")]
+    [Inspectable(category="General", enumeration="off,on,auto", defaultValue="auto")]
+
+    /**
+     *  Specifies whether the vertical scroll bar is always present,
+     *  always absent, or automatically added when needed.
+     *  Possible values are ScrollPolicy.ON, ScrollPolicy.OFF,
+     *  and ScrollPolicy.AUTO.
+     *  MXML values can be "on", "off",
+     *  and "auto".
+     *
+     *
Setting this property to ScrollPolicy.OFF also prevents the
+     *  verticalScrollPosition property from having an effect.

+     *
+     *
Note: This property does not apply to the ControlBar container.

+     *
+     *
If the verticalScrollPolicy is ScrollPolicy.AUTO,
+     *  the vertical scroll bar appears when all of the following
+     *  are true:

+     *

+     *
One of the container's children extends beyond the top
+     *      edge or bottom edge of the container.

+     *
The clipContent property is true.

+     *
The width and height of the container are large enough to
+     *      reasonably accommodate a scroll bar.

+     *

+     *
+     *  @default ScrollPolicy.AUTO
+     */
+    public function get verticalScrollPolicy():String
+    {
+        return _verticalScrollPolicy;
+    }
+
+    /**
+     *  @private
+     */
+    public function set verticalScrollPolicy(value:String):void
+    {
+        if (_verticalScrollPolicy != value)
+        {
+            _verticalScrollPolicy = value;
+
+            invalidateDisplayList();
+
+            dispatchEvent(new Event("verticalScrollPolicyChanged"));
+        }
+    }
+
+    //----------------------------------
+    //  viewMetrics
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Offsets including borders and scrollbars
+     */
+    private var _viewMetrics:EdgeMetrics;
+
+    /**
+     *  Returns an object that has four properties: left,
+     *  top, right, and bottom.
+     *  The value of each property equals the thickness of the chrome
+     *  (visual elements) around the edge of the container.
+     *
+     *
The chrome includes the border thickness.
+     *  If the horizontalScrollPolicy or verticalScrollPolicy
+     *  property value is ScrollPolicy.ON, the
+     *  chrome also includes the thickness of the corresponding
+     *  scroll bar. If a scroll policy is ScrollPolicy.AUTO,
+     *  the chrome measurement does not include the scroll bar thickness,
+     *  even if a scroll bar is displayed.

+     *
+     *
Subclasses of Container should override this method, so that
+     *  they include other chrome to be taken into account when positioning
+     *  the Container's children.
+     *  For example, the viewMetrics property for the
+     *  Panel class should return an object whose top property
+     *  includes the thickness of the Panel container's title bar.

+     */
+    public function get viewMetrics():EdgeMetrics
+    {
+        var bm:EdgeMetrics = borderMetrics;
+
+        // If scrollPolicy is ScrollPolicy.ON, then the scrollbars are accounted for
+        // during both measurement and layout.
+        //
+        // If scrollPolicy is ScrollPolicy.AUTO, then scrollbars are ignored during
+        // measurement.  Otherwise, the entire layout of the app could change
+        // everytime that the scrollbars turn on or off.
+        //
+        // However, we do take the width of scrollbars into account when laying
+        // out our children.  That way, children that have a percentage width or
+        // percentage height will only expand to consume space that's left over
+        // after leaving room for the scrollbars.
+        var verticalScrollBarIncluded:Boolean =
+            verticalScrollBar != null &&
+            (doingLayout || verticalScrollPolicy == ScrollPolicy.ON);
+        var horizontalScrollBarIncluded:Boolean =
+            horizontalScrollBar != null &&
+            (doingLayout || horizontalScrollPolicy == ScrollPolicy.ON);
+        if (!verticalScrollBarIncluded && !horizontalScrollBarIncluded)
+            return bm;
+
+        // The viewMetrics property needs to return its own object.
+        // Rather than allocating a new one each time, we'll allocate one once
+        // and then hold a reference to it.
+        if (!_viewMetrics)
+        {
+            _viewMetrics = bm.clone();
+        }
+        else
+        {
+            _viewMetrics.left = bm.left;
+            _viewMetrics.right = bm.right;
+            _viewMetrics.top = bm.top;
+            _viewMetrics.bottom = bm.bottom;
+        }
+
+        if (verticalScrollBarIncluded)
+            _viewMetrics.right += verticalScrollBar.minWidth;
+        if (horizontalScrollBarIncluded)
+            _viewMetrics.bottom += horizontalScrollBar.minHeight;
+
+        return _viewMetrics;
+    }
+
+    //----------------------------------
+    //  viewMetricsAndPadding
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Cached value containing the view metrics plus the object's margins.
+     */
+    private var _viewMetricsAndPadding:EdgeMetrics;
+
+    /**
+     *  Returns an object that has four properties: left,
+     *  top, right, and bottom.
+     *  The value of each property is equal to the thickness of the chrome
+     *  (visual elements)
+     *  around the edge of the container plus the thickness of the object's margins.
+     *
+     *
The chrome includes the border thickness.
+     *  If the horizontalScrollPolicy or verticalScrollPolicy
+     *  property value is ScrollPolicy.ON, the
+     *  chrome also includes the thickness of the corresponding
+     *  scroll bar. If a scroll policy is ScrollPolicy.AUTO,
+     *  the chrome measurement does not include the scroll bar thickness,
+     *  even if a scroll bar is displayed.

+     */
+    public function get viewMetricsAndPadding():EdgeMetrics
+    {
+        // If this object has scrollbars, and if the verticalScrollPolicy
+        // is not ScrollPolicy.ON, then the view metrics change
+        // depending on whether we're doing layout or not.
+        // In that case, we can't use a cached value.
+        // In all other cases, use the cached value if it exists.
+        if (_viewMetricsAndPadding &&
+            (!horizontalScrollBar ||
+             horizontalScrollPolicy == ScrollPolicy.ON) &&
+            (!verticalScrollBar ||
+             verticalScrollPolicy == ScrollPolicy.ON))
+        {
+            return _viewMetricsAndPadding;
+        }
+
+        if (!_viewMetricsAndPadding)
+            _viewMetricsAndPadding = new EdgeMetrics();
+
+        var o:EdgeMetrics = _viewMetricsAndPadding;
+        var vm:EdgeMetrics = viewMetrics;
+
+        o.left = vm.left + getStyle("paddingLeft");
+        o.right = vm.right + getStyle("paddingRight");
+        o.top = vm.top + getStyle("paddingTop");
+        o.bottom = vm.bottom + getStyle("paddingBottom");
+
+        return o;
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Overridden methods: EventDispatcher
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  If we add a mouse event, then we need to add a mouse shield
+     *  to us and to all our children
+     *  The mouseShield style is a non-inheriting style
+     *  that is used by the view.
+     *  The mouseShieldChildren style is an inherting style
+     *  that is used by the children views.
+     */
+    override public function addEventListener(
+                                    type:String, listener:Function,
+                                    useCapture:Boolean = false,
+                                    priority:int = 0,
+                                    useWeakReference:Boolean = false):void
+    {
+        super.addEventListener(type, listener, useCapture,
+                               priority, useWeakReference);
+
+        // If we are a mouse event, then create a mouse shield.
+        if (type == MouseEvent.CLICK ||
+            type == MouseEvent.DOUBLE_CLICK ||
+            type == MouseEvent.MOUSE_DOWN ||
+            type == MouseEvent.MOUSE_MOVE ||
+            type == MouseEvent.MOUSE_OVER ||
+            type == MouseEvent.MOUSE_OUT ||
+            type == MouseEvent.MOUSE_UP ||
+            type == MouseEvent.MOUSE_WHEEL)
+        {
+            if (mouseEventReferenceCount < 0x7FFFFFFF /* int_max */ &&
+                mouseEventReferenceCount++ == 0)
+            {
+                setStyle("mouseShield", true);
+                setStyle("mouseShieldChildren", true);
+            }
+        }
+    }
+
+    /**
+     *  @private
+     *  Remove the mouse shield if we no longer listen to any mouse events
+     */
+    override public function removeEventListener(
+                                    type:String, listener:Function,
+                                    useCapture:Boolean = false):void
+    {
+        super.removeEventListener(type, listener, useCapture);
+
+        // If we are a mouse event,
+        // then decrement the mouse shield reference count.
+        if (type == MouseEvent.CLICK ||
+            type == MouseEvent.DOUBLE_CLICK ||
+            type == MouseEvent.MOUSE_DOWN ||
+            type == MouseEvent.MOUSE_MOVE ||
+            type == MouseEvent.MOUSE_OVER ||
+            type == MouseEvent.MOUSE_OUT ||
+            type == MouseEvent.MOUSE_UP ||
+            type == MouseEvent.MOUSE_WHEEL)
+        {
+            if (mouseEventReferenceCount > 0 &&
+                --mouseEventReferenceCount == 0)
+            {
+                setStyle("mouseShield", false);
+                setStyle("mouseShieldChildren", false);
+            }
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Overridden methods: DisplayObjectContainer
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Adds a child DisplayObject to this Container.
+     *  The child is added after other existing children,
+     *  so that the first child added has index 0,
+     *  the next has index 1, an so on.
+     *
+     *
Note: While the child argument to the method
+     *  is specified as of type DisplayObject, the argument must implement
+     *  the IUIComponent interface to be added as a child of a container.
+     *  All Flex components implement this interface.

+     *
+     *
Children are layered from back to front.
+     *  In other words, if children overlap, the one with index 0
+     *  is farthest to the back, and the one with index
+     *  numChildren - 1 is frontmost.
+     *  This means the newly added children are layered
+     *  in front of existing children.

+     *
+     *  @param child The DisplayObject to add as a child of this Container.
+     *  It must implement the IUIComponent interface.
+     *
+     *  @return The added child as an object of type DisplayObject.
+     *  You typically cast the return value to UIComponent,
+     *  or to the type of the added component.
+     *
+     *  @see mx.core.IUIComponent
+     *
+     *  @tiptext Adds a child object to this container.
+     */
+    override public function addChild(child:DisplayObject):DisplayObject
+    {
+        return addChildAt(child, numChildren);
+
+        /*
+        addingChild(child);
+
+        if (contentPane)
+            contentPane.addChild(child);
+        else
+            $addChild(child);
+
+        childAdded(child);
+
+        return child;
+        */
+    }
+
+    /**
+     *  Adds a child DisplayObject to this Container.
+     *  The child is added at the index specified.
+     *
+     *
Note: While the child argument to the method
+     *  is specified as of type DisplayObject, the argument must implement
+     *  the IUIComponent interface to be added as a child of a container.
+     *  All Flex components implement this interface.

+     *
+     *
Children are layered from back to front.
+     *  In other words, if children overlap, the one with index 0
+     *  is farthest to the back, and the one with index
+     *  numChildren - 1 is frontmost.
+     *  This means the newly added children are layered
+     *  in front of existing children.

+     *
+     *
When you add a new child at an index that is already occupied
+     *  by an old child, it doesn't replace the old child; instead the
+     *  old child and the ones after it "slide over" and have their index
+     *  incremented by one.
+     *  For example, suppose a Container contains the children
+     *  (A, B, C) and you add D at index 1.
+     *  Then the container will contain (A, D, B, C).
+     *  If you want to replace an old child, you must first remove it
+     *  before adding the new one.

+     *
+     *  @param child The DisplayObject to add as a child of this Container.
+     *  It must implement the IUIComponent interface.
+     *
+     *  @param index The index to add the child at.
+     *
+     *  @return The added child as an object of type DisplayObject.
+     *  You typically cast the return value to UIComponent,
+     *  or to the type of the added component.
+     *
+     *  @see mx.core.IUIComponent
+     */
+    override public function addChildAt(child:DisplayObject,
+                                        index:int):DisplayObject
+    {
+        var formerParent:DisplayObjectContainer = child.parent;
+        if (formerParent && !(formerParent is Loader))
+            formerParent.removeChild(child);
+
+        addingChild(child);
+
+        // Add the child to either this container or its contentPane.
+        // The player will dispatch an "added" event from the child
+        // after it has been added, so all "added" handlers execute here.
+        if (contentPane)
+            contentPane.addChildAt(child, index);
+        else
+            $addChildAt(child, _firstChildIndex + index);
+
+        childAdded(child);
+
+        if ((child is UIComponent) && UIComponent(child).isDocument)
+            BindingManager.setEnabled(child, true);
+
+        return child;
+    }
+
+    /**
+     *  Removes a child DisplayObject from the child list of this Container.
+     *  The removed child will have its parent
+     *  property set to null.
+     *  The child will still exist unless explicitly destroyed.
+     *  If you add it to another container,
+     *  it will retain its last known state.
+     *
+     *  @param child The DisplayObject to remove.
+     *
+     *  @return The removed child as an object of type DisplayObject.
+     *  You typically cast the return value to UIComponent,
+     *  or to the type of the removed component.
+     */
+    override public function removeChild(child:DisplayObject):DisplayObject
+    {
+        if (child is IDeferredInstantiationUIComponent &&
+            IDeferredInstantiationUIComponent(child).descriptor)
+        {
+            // if child's descriptor is present, it means child was created
+            // with MXML.  Need to go through and remove component in
+            // createdComponents so there is no memory leak by keeping
+            // a reference to the removed child (SDK-12506)
+
+            if (createdComponents)
+            {
+                var n:int = createdComponents.length;
+                for(var i:int = 0; i < n; i++)
+                {
+                    if (createdComponents[i] === child)
+                    {
+                        // delete this reference
+                        createdComponents.splice(i, 1);
+                    }
+                }
+            }
+        }
+
+        removingChild(child);
+
+        if ((child is UIComponent) && UIComponent(child).isDocument)
+            BindingManager.setEnabled(child, false);
+
+        // Remove the child from either this container or its contentPane.
+        // The player will dispatch a "removed" event from the child
+        // before it is removed, so all "removed" handlers execute here.
+        if (contentPane)
+            contentPane.removeChild(child);
+        else
+            $removeChild(child);
+
+        childRemoved(child);
+
+        return child;
+    }
+
+    /**
+     *  Removes a child DisplayObject from the child list of this Container
+     *  at the specified index.
+     *  The removed child will have its parent
+     *  property set to null.
+     *  The child will still exist unless explicitly destroyed.
+     *  If you add it to another container,
+     *  it will retain its last known state.
+     *
+     *  @param index The child index of the DisplayObject to remove.
+     *
+     *  @return The removed child as an object of type DisplayObject.
+     *  You typically cast the return value to UIComponent,
+     *  or to the type of the removed component.
+     */
+    override public function removeChildAt(index:int):DisplayObject
+    {
+        return removeChild(getChildAt(index));
+
+        /*
+
+        Shouldn't implement removeChildAt() in terms of removeChild().
+
+        */
+    }
+
+    /**
+     *  Gets the nth child component object.
+     *
+     *
The children returned from this method include children that are
+     *  declared in MXML and children that are added using the
+     *  addChild() or addChildAt() method.

+     *
+     *  @param childIndex Number from 0 to (numChildren - 1).
+     *
+     *  @return Reference to the child as an object of type DisplayObject.
+     *  You typically cast the return value to UIComponent,
+     *  or to the type of a specific Flex control, such as ComboBox or TextArea.
+     */
+    override public function getChildAt(index:int):DisplayObject
+    {
+        if (contentPane)
+        {
+            return contentPane.getChildAt(index);
+        }
+        else
+        {
+            // The DisplayObjectContainer implementation of getChildAt()
+            // in the Player throws this error if the index is bad,
+            // so we should too.
+//          if (index < 0 || index >= _numChildren)
+//              throw new RangeError("The supplied index is out of bounds");
+
+            return super.getChildAt(_firstChildIndex + index);
+        }
+    }
+
+    /**
+     *  Returns the child whose name property is the specified String.
+     *
+     *  @param name The identifier of the child.
+     *
+     *  @return The DisplayObject representing the child as an object of type DisplayObject.
+     *  You typically cast the return value to UIComponent,
+     *  or to the type of a specific Flex control, such as ComboBox or TextArea.
+     */
+    override public function getChildByName(name:String):DisplayObject
+    {
+        if (contentPane)
+        {
+            return contentPane.getChildByName(name);
+        }
+        else
+        {
+            var child:DisplayObject = super.getChildByName(name);
+            if (!child)
+                return null;
+
+            // Check if the child is in the index range for content children.
+            var index:int = super.getChildIndex(child) - _firstChildIndex;
+            if (index < 0 || index >= _numChildren)
+                return null;
+
+            return child;
+        }
+    }
+
+    /**
+     *  Gets the zero-based index of a specific child.
+     *
+     *
The first child of the container (i.e.: the first child tag
+     *  that appears in the MXML declaration) has an index of 0,
+     *  the second child has an index of 1, and so on.
+     *  The indexes of a container's children determine
+     *  the order in which they get laid out.
+     *  For example, in a VBox the child with index 0 is at the top,
+     *  the child with index 1 is below it, etc.

+     *
+     *
If you add a child by calling the addChild() method,
+     *  the new child's index is equal to the largest index among existing
+     *  children plus one.
+     *  You can insert a child at a specified index by using the
+     *  addChildAt() method; in that case the indices of the
+     *  child previously at that index, and the children at higher indices,
+     *  all have their index increased by 1 so that all indices fall in the
+     *  range from 0 to (numChildren - 1).

+     *
+     *
If you remove a child by calling removeChild()
+     *  or removeChildAt() method, then the indices of the
+     *  remaining children are adjusted so that all indices fall in the
+     *  range from 0 to (numChildren - 1).

+     *
+     *
If myView.getChildIndex(myChild) returns 5,
+     *  then myView.getChildAt(5) returns myChild.

+     *
+     *
The index of a child may be changed by calling the
+     *  setChildIndex() method.

+     *
+     *  @param child Reference to child whose index to get.
+     *
+     *  @return Number between 0 and (numChildren - 1).
+     */
+    override public function getChildIndex(child:DisplayObject):int
+    {
+        if (contentPane)
+        {
+            return contentPane.getChildIndex(child);
+        }
+        else
+        {
+            var index:int = super.getChildIndex(child) - _firstChildIndex;
+
+            // The DisplayObjectContainer implementation of getChildIndex()
+            // in the Player throws this error if the child isn't a child,
+            // so we should too.
+//          if (index < 0 || index >= _numChildren)
+//              throw new ArgumentError("The DisplayObject supplied must be a child of the caller.");
+
+            return index;
+        }
+    }
+
+    /**
+     *  Sets the index of a particular child.
+     *  See the getChildIndex() method for a
+     *  description of the child's index.
+     *
+     *  @param child Reference to child whose index to set.
+     *
+     *  @param newIndex Number that indicates the new index.
+     *  Must be an integer between 0 and (numChildren - 1).
+     */
+    override public function setChildIndex(child:DisplayObject, newIndex:int):void
+    {
+        var oldIndex:int;
+
+        var eventOldIndex:int = oldIndex;
+        var eventNewIndex:int = newIndex;
+
+        if (contentPane)
+        {
+            contentPane.setChildIndex(child, newIndex);
+
+            if (_autoLayout || forceLayout)
+                invalidateDisplayList();
+        }
+        else
+        {
+            oldIndex = super.getChildIndex(child);
+
+            // Offset the index, to leave room for skins before the list of children
+            newIndex += _firstChildIndex;
+
+            if (newIndex == oldIndex)
+                return;
+
+            // Change the child's index, shifting around other children to make room
+            super.setChildIndex(child, newIndex);
+
+            invalidateDisplayList();
+
+            eventOldIndex = oldIndex - _firstChildIndex;
+            eventNewIndex = newIndex - _firstChildIndex;
+        }
+
+        // Notify others that the child index has changed
+        var event:IndexChangedEvent = new IndexChangedEvent(IndexChangedEvent.CHILD_INDEX_CHANGE);
+        event.relatedObject = child;
+        event.oldIndex = eventOldIndex;
+        event.newIndex = eventNewIndex;
+        dispatchEvent(event);
+
+        dispatchEvent(new Event("childrenChanged"));
+    }
+
+    /**
+     *  @private
+     */
+    override public function contains(child:DisplayObject):Boolean
+    {
+        if (contentPane)
+            return contentPane.contains(child);
+        else
+            return super.contains(child);
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Overridden methods: UIComponent
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    override public function initialize():void
+    {
+        // Until component templating is implemented, the childDescriptors
+        // come either from the top-level descriptor in the component itself
+        // (i.e., the defined children) or from a descriptor for an instance
+        // of that component in some other component or app (i.e., the
+        // instance children). At this point _childDescriptors already
+        // contains the instance children if there are any; but if the
+        // document defines any children, we have to use them instead.
+
+        if (isDocument && documentDescriptor && !processedDescriptors)
+        {
+            // NOTE: documentDescriptor.properties is a potentially
+            // expensive function call, so do it only once.
+            var props:* = documentDescriptor.properties;
+            if (props && props.childDescriptors)
+            {
+                if (_childDescriptors)
+                {
+                    var message:String = resourceManager.getString(
+                        "core", "multipleChildSets_ClassAndInstance");
+                    throw new Error(message);
+                }
+                else
+                {
+                    _childDescriptors = props.childDescriptors;
+                }
+            }
+        }
+
+        super.initialize();
+    }
+
+    /**
+     *  @private
+     *  Create components that are children of this Container.
+     */
+    override protected function createChildren():void
+    {
+        super.createChildren();
+
+        // Create the border/background object.
+        createBorder();
+
+        // To save ourselves an extra layout pass, check to see
+        // if the scrollbars will definitely be needed.
+        // If so, create them now.
+        createOrDestroyScrollbars(
+            horizontalScrollPolicy == ScrollPolicy.ON,
+            verticalScrollPolicy == ScrollPolicy.ON,
+            horizontalScrollPolicy == ScrollPolicy.ON ||
+            verticalScrollPolicy == ScrollPolicy.ON);
+
+        // Determine the child-creation policy (ContainerCreationPolicy.AUTO,
+        // ContainerCreationPolicy.ALL, or ContainerCreationPolicy.NONE).
+        // If the author has specified a policy, use it.
+        // Otherwise, use the parent's policy.
+        // This must be set before createChildren() gets called.
+        if (creationPolicy != null)
+        {
+            actualCreationPolicy = creationPolicy;
+        }
+        else if (parent is Container)
+        {
+            if (Container(parent).actualCreationPolicy ==
+                ContainerCreationPolicy.QUEUED)
+            {
+                actualCreationPolicy = ContainerCreationPolicy.AUTO;
+            }
+            else
+            {
+                actualCreationPolicy = Container(parent).actualCreationPolicy;
+            }
+        }
+
+        // It is ok for actualCreationPolicy to be null. Popups require it.
+
+        if (actualCreationPolicy == ContainerCreationPolicy.NONE)
+        {
+            actualCreationPolicy = ContainerCreationPolicy.AUTO;
+        }
+        else if (actualCreationPolicy == ContainerCreationPolicy.QUEUED)
+        {
+            var mainApp:Application = parentApplication ?
+                                      Application(parentApplication) :
+                                      Application(Application.application);
+
+            mainApp.addToCreationQueue(this, creationIndex, null, this);
+        }
+        else if (recursionFlag)
+        {
+            // Create whatever children are appropriate. If any were
+            // previously created, they don't get re-created.
+            createComponentsFromDescriptors();
+        }
+
+        // If autoLayout is initially false, we still want to do
+        // measurement once (even if we don't have any children)
+        if (autoLayout == false)
+            forceLayout = true;
+
+        // weak references
+        UIComponentGlobals.layoutManager.addEventListener(
+            FlexEvent.UPDATE_COMPLETE, layoutCompleteHandler, false, 0, true);
+    }
+
+    /**
+     *  @private
+     *  Override to NOT set precessedDescriptors.
+     */
+    override protected function initializationComplete():void
+    {
+        // Don't call super.initializationComplete().
+    }
+
+    /**
+     *  @private
+     */
+    override protected function commitProperties():void
+    {
+        super.commitProperties();
+
+        if (changedStyles)
+        {
+            // If multiple properties have changed, set styleProp to null.
+            // Otherwise, set it to the name of the style that has changed.
+            var styleProp:String = changedStyles == MULTIPLE_PROPERTIES ?
+                                   null :
+                                   changedStyles;
+
+            super.notifyStyleChangeInChildren(styleProp, true);
+
+            changedStyles = null;
+        }
+
+        createOrDestroyBlocker();
+    }
+
+    /**
+     *  @private
+     */
+    override public function validateSize(recursive:Boolean = false):void
+    {
+        // If autoLayout is turned off and we haven't recently created
+        // or destroyed any children, then we're not doing any
+        // measurement or layout.
+        // Return false indicating that the measurements haven't changed.
+        if (autoLayout == false && forceLayout == false)
+        {
+            if (recursive)
+            {
+                var n:int = super.numChildren;
+                for (var i:int = 0; i < n; i++)
+                {
+                    var child:DisplayObject = super.getChildAt(i);
+                    if (child is ILayoutManagerClient )
+                        ILayoutManagerClient (child).validateSize(true);
+                }
+            }
+            adjustSizesForScaleChanges();
+        }
+        else
+        {
+            super.validateSize(recursive);
+        }
+    }
+
+    /**
+     *  @private
+     */
+    override public function validateDisplayList():void
+    {
+        // trace(">>Container validateLayoutPhase " + this);
+
+        var vm:EdgeMetrics;
+
+        // If autoLayout is turned off and we haven't recently created or
+        // destroyed any children, then don't do any layout
+        if (_autoLayout || forceLayout)
+        {
+            doingLayout = true;
+            super.validateDisplayList();
+            doingLayout = false;
+        }
+        else
+        {
+            // Layout borders, Panel headers, and other border chrome.
+            layoutChrome(unscaledWidth, unscaledHeight);
+        }
+
+        // Set this to block requeuing when sizing children.
+        invalidateDisplayListFlag = true;
+
+        // Based on the positions of the children, determine
+        // whether a clip mask and scrollbars are needed.
+        if (createContentPaneAndScrollbarsIfNeeded())
+        {
+            // Redo layout if scrollbars just got created or destroyed (because
+            // now we may have more or less space).
+            if (_autoLayout || forceLayout)
+            {
+                doingLayout = true;
+                super.validateDisplayList();
+                doingLayout = false;
+            }
+
+            // If a scrollbar was created, that may precipitate the need
+            // for a second scrollbar, so run it a second time.
+            createContentPaneAndScrollbarsIfNeeded();
+        }
+
+        // The relayout performed by the above calls
+        // to super.validateDisplayList() may result
+        // in new max scroll positions that are less
+        // than previously-set scroll positions.
+        // For example, when a maximally-scrolled container
+        // is resized to be larger, the new max scroll positions
+        // are reduced and the current scroll positions
+        // will be invalid unless we clamp them.
+        if (clampScrollPositions())
+            scrollChildren();
+
+        if (contentPane)
+        {
+            vm = viewMetrics;
+
+            // Set the position and size of the overlay .
+            if (overlay)
+            {
+                overlay.x = 0;
+                overlay.y = 0;
+                overlay.width = unscaledWidth;
+                overlay.height = unscaledHeight;
+            }
+
+            // Set the positions and sizes of the scrollbars.
+            if (horizontalScrollBar || verticalScrollBar)
+            {
+                // Get the view metrics and remove the thickness
+                // of the scrollbars from the view metrics.
+                // We can't simply get the border metrics,
+                // because some subclass (e.g.: Window)
+                // might add to the metrics.
+                if (verticalScrollBar &&
+                    verticalScrollPolicy == ScrollPolicy.ON)
+                {
+                    vm.right -= verticalScrollBar.minWidth;
+                }
+                if (horizontalScrollBar &&
+                    horizontalScrollPolicy == ScrollPolicy.ON)
+                {
+                    vm.bottom -= horizontalScrollBar.minHeight;
+                }
+
+                if (horizontalScrollBar)
+                {
+                    var w:Number = unscaledWidth - vm.left - vm.right;
+                    if (verticalScrollBar)
+                        w -= verticalScrollBar.minWidth;
+
+                    horizontalScrollBar.setActualSize(
+                        w, horizontalScrollBar.minHeight);
+
+                    horizontalScrollBar.move(vm.left,
+                                             unscaledHeight - vm.bottom -
+                                             horizontalScrollBar.minHeight);
+                }
+
+                if (verticalScrollBar)
+                {
+                    var h:Number = unscaledHeight - vm.top - vm.bottom;
+                    if (horizontalScrollBar)
+                        h -= horizontalScrollBar.minHeight;
+
+                    verticalScrollBar.setActualSize(
+                        verticalScrollBar.minWidth, h);
+
+                    verticalScrollBar.move(unscaledWidth - vm.right -
+                                           verticalScrollBar.minWidth,
+                                           vm.top);
+                }
+
+                // Set the position of the box
+                // that covers the gap between the scroll bars.
+                if (whiteBox)
+                {
+                    whiteBox.x = verticalScrollBar.x;
+                    whiteBox.y = horizontalScrollBar.y;
+                }
+            }
+
+            contentPane.x = vm.left;
+            contentPane.y = vm.top;
+
+            if (focusPane)
+            {
+                focusPane.x = vm.left
+                focusPane.y = vm.top;
+            }
+
+            scrollChildren();
+        }
+
+        invalidateDisplayListFlag = false;
+
+        // that blocks UI input as well as draws an alpha overlay.
+        // Make sure the blocker is correctly positioned and sized here.
+        if (blocker)
+        {
+            vm = viewMetrics;
+
+            var bgColor:Object = enabled ?
+                                 null :
+                                 getStyle("backgroundDisabledColor");
+            if (bgColor === null || isNaN(Number(bgColor)))
+                bgColor = getStyle("backgroundColor");
+
+            if (bgColor === null || isNaN(Number(bgColor)))
+                bgColor = 0xFFFFFF;
+
+            var blockerAlpha:Number = getStyle("disabledOverlayAlpha");
+
+            if (isNaN(blockerAlpha))
+                blockerAlpha = 0.6;
+
+            blocker.x = vm.left;
+            blocker.y = vm.top;
+
+            var widthToBlock:Number = unscaledWidth - (vm.left + vm.right);
+            var heightToBlock:Number = unscaledHeight - (vm.top + vm.bottom);
+
+            blocker.graphics.clear();
+            blocker.graphics.beginFill(uint(bgColor), blockerAlpha);
+            blocker.graphics.drawRect(0, 0, widthToBlock, heightToBlock);
+            blocker.graphics.endFill();
+
+            // Blocker must be in front of everything
+            rawChildren.setChildIndex(blocker, rawChildren.numChildren - 1);
+        }
+
+        // trace("<<Container internalValidateDisplayList " + this);
+    }
+
+    /**
+     *  Respond to size changes by setting the positions and sizes
+     *  of this container's children.
+     *
+     *
See the UIComponent.updateDisplayList() method for more information
+     *  about the updateDisplayList() method.

+     *
+     *
The Container.updateDisplayList() method sets the position
+     *  and size of the Container container's border.
+     *  In every subclass of Container, the subclass's updateDisplayList()
+     *  method should call the super.updateDisplayList() method,
+     *  so that the border is positioned properly.

+     *
+     *  @param unscaledWidth Specifies the width of the component, in pixels,
+     *  in the component's coordinates, regardless of the value of the
+     *  scaleX property of the component.
+     *
+     *  @param unscaledHeight Specifies the height of the component, in pixels,
+     *  in the component's coordinates, regardless of the value of the
+     *  scaleY property of the component.
+     *
+     *  @see mx.core.UIComponent
+     */
+    override protected function updateDisplayList(unscaledWidth:Number,
+                                                  unscaledHeight:Number):void
+    {
+        super.updateDisplayList(unscaledWidth, unscaledHeight);
+
+        layoutChrome(unscaledWidth, unscaledHeight);
+
+        if (scrollPositionChanged)
+        {
+            clampScrollPositions();
+
+            scrollChildren();
+
+            scrollPositionChanged = false;
+        }
+
+        if (scrollPropertiesChanged)
+        {
+            if (horizontalScrollBar)
+            {
+                horizontalScrollBar.lineScrollSize = horizontalLineScrollSize;
+                horizontalScrollBar.pageScrollSize = horizontalPageScrollSize;
+            }
+
+            if (verticalScrollBar)
+            {
+                verticalScrollBar.lineScrollSize = verticalLineScrollSize;
+                verticalScrollBar.pageScrollSize = verticalPageScrollSize;
+            }
+
+            scrollPropertiesChanged = false;
+        }
+
+        if (contentPane && contentPane.scrollRect)
+        {
+            // Draw content pane
+
+            var backgroundColor:Object = enabled ?
+                                         null :
+                                         getStyle("backgroundDisabledColor");
+
+            if (backgroundColor === null || isNaN(Number(backgroundColor)))
+                backgroundColor = getStyle("backgroundColor");
+
+            var backgroundAlpha:Number = getStyle("backgroundAlpha");
+
+            if (!_clipContent ||
+                isNaN(Number(backgroundColor)) ||
+                backgroundColor === "" ||
+                (!(horizontalScrollBar || verticalScrollBar) && !cacheAsBitmap))
+            {
+                backgroundColor = null;
+            }
+
+            // If there's a backgroundImage or background, unset
+            // opaqueBackground.
+            else if (getStyle("backgroundImage") ||
+                     getStyle("background"))
+            {
+                backgroundColor = null;
+            }
+
+            // If the background is not opaque, unset opaqueBackground.
+            else if (backgroundAlpha != 1)
+            {
+                backgroundColor = null;
+            }
+
+            contentPane.opaqueBackground = backgroundColor;
+
+            // Set cacheAsBitmap only if opaqueBackground is also set (to avoid
+            // text anti-aliasing issue with device text on Windows).
+            contentPane.cacheAsBitmap = (backgroundColor != null);
+        }
+    }
+
+    /**
+     *  @copy mx.core.UIComponent#contentToGlobal()
+     */
+    override public function contentToGlobal(point:Point):Point
+    {
+        if (contentPane)
+            return contentPane.localToGlobal(point);
+
+        return localToGlobal(point);
+    }
+
+    /**
+     *  @copy mx.core.UIComponent#globalToContent()
+     */
+    override public function globalToContent(point:Point):Point
+    {
+        if (contentPane)
+            return contentPane.globalToLocal(point);
+
+        return globalToLocal(point);
+    }
+
+    /**
+     *  @copy mx.core.UIComponent#contentToLocal()
+     */
+    override public function contentToLocal(point:Point):Point
+    {
+        if (!contentPane)
+            return point;
+
+        point = contentToGlobal(point);
+        return globalToLocal(point);
+    }
+
+    /**
+     *  @copy mx.core.UIComponent#localToContent()
+     */
+    override public function localToContent(point:Point):Point
+    {
+        if (!contentPane)
+            return point;
+
+        point = localToGlobal(point);
+        return globalToContent(point);
+    }
+
+    /**
+     *  @private
+     */
+    override public function styleChanged(styleProp:String):void
+    {
+        var allStyles:Boolean = styleProp == null || styleProp == "styleName";
+
+        // Check to see if this is one of the style properties that is known
+        // to affect page layout.
+        if (allStyles || StyleManager.isSizeInvalidatingStyle(styleProp))
+        {
+            // Some styles, such as horizontalAlign and verticalAlign,
+            // affect the layout of this object's children without changing the
+            // view's size.  This function forces the view to be remeasured
+            // and layed out.
+            invalidateDisplayList();
+        }
+
+        // Replace the borderSkin
+        if (allStyles || styleProp == "borderSkin")
+        {
+            if (border)
+            {
+                rawChildren.removeChild(DisplayObject(border));
+                border = null;
+                createBorder();
+            }
+        }
+
+        // Create a border object, if none previously existed and
+        // one is needed now.
+        if (allStyles ||
+            styleProp == "borderStyle" ||
+            styleProp == "backgroundColor" ||
+            styleProp == "backgroundImage" ||
+            styleProp == "mouseShield" ||
+            styleProp == "mouseShieldChildren")
+        {
+            createBorder();
+        }
+
+        super.styleChanged(styleProp);
+
+        // Check to see if this is one of the style properties that is known.
+        // to affect page layout.
+        if (allStyles ||
+            StyleManager.isSizeInvalidatingStyle(styleProp))
+        {
+            invalidateViewMetricsAndPadding();
+        }
+
+        if (allStyles || styleProp == "horizontalScrollBarStyleName")
+        {
+            if (horizontalScrollBar && horizontalScrollBar is ISimpleStyleClient)
+            {
+                var horizontalScrollBarStyleName:String =
+                    getStyle("horizontalScrollBarStyleName");
+                ISimpleStyleClient(horizontalScrollBar).styleName =
+                    horizontalScrollBarStyleName;
+            }
+        }
+
+        if (allStyles || styleProp == "verticalScrollBarStyleName")
+        {
+            if (verticalScrollBar && verticalScrollBar is ISimpleStyleClient)
+            {
+                var verticalScrollBarStyleName:String =
+                    getStyle("verticalScrollBarStyleName");
+                ISimpleStyleClient(verticalScrollBar).styleName =
+                    verticalScrollBarStyleName;
+            }
+        }
+    }
+
+    /**
+     *  @private
+     *  Call the styleChanged method on children of this container
+     *
+     *  Notify chrome children immediately, and recursively call this
+     *  function for all descendants of the chrome children.  We recurse
+     *  regardless of the recursive flag because one of the descendants
+     *  might have a styleName property that points to this object.
+     *
+     *  If recursive is true, then also notify content children ... but
+     *  do it later.  Notification is deferred so that multiple calls to
+     *  setStyle can be batched up into one traversal.
+     */
+    override public function notifyStyleChangeInChildren(
+                                styleProp:String, recursive:Boolean):void
+    {
+        // Notify chrome children immediately, recursively calling this
+        // this function
+        var n:int = super.numChildren;
+        for (var i:int = 0; i < n; i++)
+        {
+            // Is this a chrome child?
+            if (contentPane ||
+                i < _firstChildIndex ||
+                i >= _firstChildIndex + _numChildren)
+            {
+                var child:ISimpleStyleClient = super.getChildAt(i) as ISimpleStyleClient;
+                if (child)
+                {
+                    child.styleChanged(styleProp);
+                    if (child is IStyleClient)
+                        IStyleClient(child).notifyStyleChangeInChildren(styleProp, recursive);
+                }
+            }
+        }
+
+        // If recursive, then remember to notify the content children later
+        if (recursive)
+        {
+            // If multiple styleProps have changed, set changedStyles to
+            // MULTIPLE_PROPERTIES.  Otherwise, set it to the name of the
+            // changed property.
+            changedStyles = (changedStyles != null || styleProp == null) ?
+                MULTIPLE_PROPERTIES : styleProp;
+            invalidateProperties();
+        }
+    }
+
+    /**
+     *  @private
+     */
+    override public function regenerateStyleCache(recursive:Boolean):void
+    {
+        super.regenerateStyleCache(recursive);
+
+        if (contentPane)
+        {
+            // Do the same thing as UIComponent, but don't check the child's index to
+            // ascertain that it's a content child (we already know that here).
+
+            var n:int = contentPane.numChildren;
+            for (var i:int = 0; i < n; i++)
+            {
+                var child:DisplayObject = getChildAt(i);
+
+                if (recursive && child is UIComponent)
+                {
+                    // Does this object already have a proto chain?  If not,
+                    // there's no need to regenerate a new one.
+                    if (UIComponent(child).inheritingStyles != UIComponent.STYLE_UNINITIALIZED)
+                        UIComponent(child).regenerateStyleCache(recursive);
+                }
+                else if (child is IUITextField && IUITextField(child).inheritingStyles)
+                {
+                    StyleProtoChain.initTextField(IUITextField(child));
+                }
+            }
+        }
+    }
+
+    /**
+     *  Used internally by the Dissolve Effect to add the overlay to the chrome of a container.
+     */
+    override protected function attachOverlay():void
+    {
+        rawChildren_addChild(overlay);
+    }
+
+    /**
+     *  Fill an overlay object which is always the topmost child in the container.
+     *  This method is used
+     *  by the Dissolve effect; never call it directly. It is called
+     *  internally by the addOverlay() method.
+     *
+     *  The Container fills the overlay object so it covers the viewable area returned
+     *  by the viewMetrics property and uses the cornerRadius style.
+     */
+    override mx_internal function fillOverlay(overlay:UIComponent, color:uint,
+                                              targetArea:RoundedRectangle = null):void
+    {
+        var vm:EdgeMetrics = viewMetrics;
+        var cornerRadius:Number = 0; //getStyle("cornerRadius");
+
+        if (!targetArea)
+        {
+            targetArea = new RoundedRectangle(
+                vm.left, vm.top,
+                unscaledWidth - vm.right - vm.left,
+                unscaledHeight - vm.bottom - vm.top,cornerRadius);
+        }
+
+        if (isNaN(targetArea.x) || isNaN(targetArea.y) ||
+            isNaN(targetArea.width) || isNaN(targetArea.height) ||
+            isNaN(targetArea.cornerRadius))
+            return;
+
+        var g:Graphics = overlay.graphics;
+        g.clear();
+        g.beginFill(color);
+        g.drawRoundRect(targetArea.x, targetArea.y,
+                        targetArea.width, targetArea.height,
+                        targetArea.cornerRadius * 2,
+                        targetArea.cornerRadius * 2);
+        g.endFill();
+    }
+
+    /**
+     *  Executes all the data bindings on this Container. Flex calls this method
+     *  automatically once a Container has been created to cause any data bindings that
+     *  have destinations inside of it to execute.
+     *
+     *  Workaround for MXML container/bindings problem (177074):
+     *  override Container.executeBindings() to prefer descriptor.document over parentDocument in the
+     *  call to BindingManager.executeBindings().
+     *
+     *  This should always provide the correct behavior for instances created by descriptor, and will
+     *  provide the original behavior for procedurally-created instances. (The bug may or may not appear
+     *  in the latter case.)
+     *
+     *  A more complete fix, guaranteeing correct behavior in both non-DI and reparented-component
+     *  scenarios, is anticipated for updater 1.
+     */
+    override public function executeBindings(recurse:Boolean = false):void
+    {
+        var bindingsHost:Object = descriptor && descriptor.document ? descriptor.document : parentDocument;
+        BindingManager.executeBindings(bindingsHost, id, this);
+
+        if (recurse)
+            executeChildBindings(recurse);
+    }
+
+    /**
+     *  @private
+     *  Prepare the Object for printing
+     *
+     *  @see mx.printing.FlexPrintJob
+     */
+    override public function prepareToPrint(target:IFlexDisplayObject):Object
+    {
+        var rect:Rectangle = (contentPane &&  contentPane.scrollRect) ? contentPane.scrollRect : null;
+
+        if (rect)
+            contentPane.scrollRect = null;
+
+        super.prepareToPrint(target);
+
+        return rect;
+    }
+
+    /**
+     *  @private
+     *  After printing is done
+     *
+     *  @see mx.printing.FlexPrintJob
+     */
+    override public function finishPrint(obj:Object, target:IFlexDisplayObject):void
+    {
+        if (obj)
+            contentPane.scrollRect = Rectangle(obj);
+
+        super.finishPrint(obj,target);
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Methods: Child management
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    override mx_internal function addingChild(child:DisplayObject):void
+    {
+        // Throw an RTE if child is not an IUIComponent.
+        var uiChild:IUIComponent = IUIComponent(child);
+
+        // Set the child's virtual parent, nestLevel, document, etc.
+        super.addingChild(child);
+
+        invalidateSize();
+        invalidateDisplayList();
+
+        if (!contentPane)
+        {
+            // If this is the first content child, then any chrome
+            // that already exists is positioned in front of it.
+            // If other content children already existed, then set the
+            // depth of this object to be just behind the existing
+            // content children.
+            if (_numChildren == 0)
+                _firstChildIndex = super.numChildren;
+
+            // Increment the number of content children.
+            _numChildren++;
+        }
+
+        if (contentPane && !autoLayout)
+        {
+            forceLayout = true;
+            // weak reference
+            UIComponentGlobals.layoutManager.addEventListener(
+                FlexEvent.UPDATE_COMPLETE, layoutCompleteHandler, false, 0, true);
+        }
+    }
+
+    /**
+     *  @private
+     */
+    override mx_internal function childAdded(child:DisplayObject):void
+    {
+        dispatchEvent(new Event("childrenChanged"));
+
+        var event:ChildExistenceChangedEvent =
+            new ChildExistenceChangedEvent(
+            ChildExistenceChangedEvent.CHILD_ADD);
+        event.relatedObject = child;
+        dispatchEvent(event);
+
+        child.dispatchEvent(new FlexEvent(FlexEvent.ADD));
+
+        super.childAdded(child); // calls createChildren()
+    }
+
+    /**
+     *  @private
+     */
+    override mx_internal function removingChild(child:DisplayObject):void
+    {
+        super.removingChild(child);
+
+        child.dispatchEvent(new FlexEvent(FlexEvent.REMOVE));
+
+        var event:ChildExistenceChangedEvent =
+            new ChildExistenceChangedEvent(
+            ChildExistenceChangedEvent.CHILD_REMOVE);
+        event.relatedObject = child;
+        dispatchEvent(event);
+    }
+
+    /**
+     *  @private
+     */
+    override mx_internal function childRemoved(child:DisplayObject):void
+    {
+        super.childRemoved(child);
+
+        invalidateSize();
+        invalidateDisplayList();
+
+        if (!contentPane)
+        {
+            _numChildren--;
+
+            if (_numChildren == 0)
+                _firstChildIndex = super.numChildren;
+        }
+
+        if (contentPane && !autoLayout)
+        {
+            forceLayout = true;
+            // weak reference
+            UIComponentGlobals.layoutManager.addEventListener(
+                FlexEvent.UPDATE_COMPLETE, layoutCompleteHandler, false, 0, true);
+        }
+
+        dispatchEvent(new Event("childrenChanged"));
+    }
+
+    [Bindable("childrenChanged")]
+
+    /**
+     *  Returns an Array of DisplayObject objects consisting of the content children
+     *  of the container.
+     *  This array does not include the DisplayObjects that implement
+     *  the container's display elements, such as its border and
+     *  the background image.
+     *
+     *  @return Array of DisplayObject objects consisting of the content children
+     *  of the container.
+     *
+     *  @see #rawChildren
+     */
+    public function getChildren():Array
+    {
+        var results:Array = [];
+
+        var n:int = numChildren;
+        for (var i:int = 0; i < n; i++)
+        {
+            results.push(getChildAt(i));
+        }
+
+        return results;
+    }
+
+    /**
+     *  Removes all children from the child list of this container.
+     */
+    public function removeAllChildren():void
+    {
+        while (numChildren > 0)
+        {
+            removeChildAt(0);
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Methods: Deferred instantiation
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  For containers, we need to ensure that at most one set of children
+     *  has been specified for the component.
+     *  There are two ways to specify multiple sets of children:
+     *  a) the component itself, as well as an instance of the component,
+     *  might specify children;
+     *  b) both a base and derived component might specify children.
+     *  Case (a) is handled in initialize(), above.
+     *  Case (b) is handled here.
+     *  This method is called in overrides of initialize()
+     *  that are generated for MXML components.
+     */
+    mx_internal function setDocumentDescriptor(desc:UIComponentDescriptor):void
+    {
+        if (processedDescriptors)
+            return;
+
+        if (_documentDescriptor && _documentDescriptor.properties.childDescriptors)
+        {
+            if (desc.properties.childDescriptors)
+            {
+                var message:String = resourceManager.getString(
+                    "core", "multipleChildSets_ClassAndSubclass");
+                throw new Error(message);
+            }
+        }
+        else
+        {
+            _documentDescriptor = desc;
+            _documentDescriptor.document = this;
+        }
+    }
+
+    /**
+     *  @private
+     *  Used by subclasses, so must be public.
+     */
+    mx_internal function setActualCreationPolicies(policy:String):void
+    {
+        actualCreationPolicy = policy;
+
+        // Recursively set the actualCreationPolicy of all descendant
+        // containers which have an undefined creationPolicy.
+        var childPolicy:String = policy;
+
+        if (policy == ContainerCreationPolicy.QUEUED)
+            childPolicy = ContainerCreationPolicy.AUTO;
+
+        //trace("setActualCreationPolicies policy", policy, "childPolicy", childPolicy);
+
+        var n:int = numChildren;
+        for (var i:int = 0; i < n; i++)
+        {
+            var child:IFlexDisplayObject = IFlexDisplayObject(getChildAt(i));
+            if (child is Container)
+            {
+                var childContainer:Container = Container(child);
+                if (childContainer.creationPolicy == null)
+                    childContainer.setActualCreationPolicies(childPolicy);
+            }
+        }
+    }
+
+    /**
+     *  Iterate through the Array of childDescriptors,
+     *  and call the createComponentFromDescriptor() method for each one.
+     *
+     *
If the value of the container's creationPolicy property is
+     *  ContainerCreationPolicy.ALL, then this method is called
+     *  automatically during the initialization sequence.

+     *
+     *
If the value of the container's creationPolicy is
+     *  ContainerCreationPolicy.AUTO,
+     *  then this method is called automatically when the
+     *  container's children are about to become visible.

+     *
+     *
If the value of the container's creationPolicy property is
+     *  ContainerCreationPolicy.NONE,
+     *  then you should call this function
+     *  when you want to create this container's children.

+     *
+     *  @param recurse If true, recursively
+     *  create components.
+     */
+    public function createComponentsFromDescriptors(
+                        recurse:Boolean = true):void
+    {
+        numChildrenBefore = numChildren;
+
+        createdComponents = [];
+
+        var n:int = childDescriptors ? childDescriptors.length : 0;
+        for (var i:int = 0; i < n; i++)
+        {
+            var component:IFlexDisplayObject =
+                createComponentFromDescriptor(childDescriptors[i], recurse);
+
+            createdComponents.push(component);
+        }
+
+        if (creationPolicy == ContainerCreationPolicy.QUEUED ||
+            creationPolicy == ContainerCreationPolicy.NONE)
+        {
+            UIComponentGlobals.layoutManager.usePhasedInstantiation = false;
+        }
+
+        numChildrenCreated = numChildren - numChildrenBefore;
+
+        processedDescriptors = true;
+    }
+
+   /**
+     *  Given a single UIComponentDescriptor, create the corresponding
+     *  component and add the component as a child of this Container.
+     *
+     *
This method instantiates the new object but does not add it to the display list, so the object does not
+     *  appear on the screen by default. To add the new object to the display list, call the validateNow()
+     *  method on the container after calling the createComponentFromDescriptor() method,
+     *  as the following example shows:
+     *

+     *  myVBox.createComponentFromDescriptor(myVBox.childDescriptors[0],false);
+     *  myVBox.validateNow();
+     *

+     *

+     *
+     *
Alternatively, you can call the createComponentsFromDescriptors() method on the
+     *  container to create all components at one time. You are not required to call the validateNow()
+     *  method after calling the createComponentsFromDescriptors() method.

+     *
+     *
+     *  @param descriptorOrIndex The UIComponentDescriptor for the
+     *  component to be created. This argument is either a
+     *  UIComponentDescriptor object or the index of one of the container's
+     *  children (an integer between 0 and n-1, where n is the total
+     *  number of children of this container).
+     *
+     *  @param recurse If false, create this component
+     *  but none of its children.
+     *  If true, after creating the component, Flex calls
+     *  the createComponentsFromDescriptors() method to create all or some
+     *  of its children, based on the value of the component's creationPolicy property.
+     *
+     *  @see mx.core.UIComponentDescriptor
+     */
+    public function createComponentFromDescriptor(
+                            descriptor:ComponentDescriptor,
+                            recurse:Boolean):IFlexDisplayObject
+    {
+        // If recurse is 'false', we create this component but none
+        // of its children.
+
+        // If recurse is 'true', after creating the component we call
+        // createComponentsFromDescriptors() to create all or some
+        // of its children, based on the component's
+        // actualContainerCreationPolicy.
+
+        var childDescriptor:UIComponentDescriptor =
+            UIComponentDescriptor(descriptor);
+
+        var childProperties:Object = childDescriptor.properties;
+
+        // This function could be asked to create the same child component
+        // twice.  That's fine if the child component is inside a repeater.
+        // In other cases, though, we want to avoid creating the same child
+        // twice.
+        //
+        // The hasChildMatchingDescriptor function is a bit expensive, so
+        // we try to avoid calling it if we know we're inside the first call
+        // to createComponents.
+        if ((numChildrenBefore != 0 || numChildrenCreated != -1) &&
+            childDescriptor.instanceIndices == null &&
+            hasChildMatchingDescriptor(childDescriptor))
+        {
+            return null;
+        }
+
+        // Turn on the three-frame instantiation scheme.
+        UIComponentGlobals.layoutManager.usePhasedInstantiation = true;
+
+        // Create the new child object and give it a unique name
+        var childType:Class = childDescriptor.type;
+        var child:IDeferredInstantiationUIComponent = new childType();
+        child.id = childDescriptor.id;
+        if (child.id && child.id != "")
+            child.name = child.id;
+
+        // Copy property values from the descriptor
+        // to the newly created component.
+        child.descriptor = childDescriptor;
+        if (childProperties.childDescriptors && child is Container)
+        {
+            Container(child)._childDescriptors =
+                childProperties.childDescriptors;
+            delete childProperties.childDescriptors;
+        }
+        for (var p:String in childProperties)
+        {
+            child[p] = childProperties[p];
+        }
+
+        // Set a flag indicating whether we should call
+        // this function recursively.
+        if (child is Container)
+            Container(child).recursionFlag = recurse;
+
+        if (childDescriptor.instanceIndices)
+        {
+            if (child is IRepeaterClient)
+            {
+                var rChild:IRepeaterClient = IRepeaterClient(child);
+                rChild.instanceIndices = childDescriptor.instanceIndices;
+                rChild.repeaters = childDescriptor.repeaters;
+                rChild.repeaterIndices = childDescriptor.repeaterIndices;
+            }
+        }
+
+        if (child is IStyleClient)
+        {
+            var scChild:IStyleClient = IStyleClient(child);
+
+            // Initialize the CSSStyleDeclaration.
+            // It is used by initProtoChain(), which is called by addChild().
+            if (childDescriptor.stylesFactory != null)
+            {
+                if (!scChild.styleDeclaration)
+                    scChild.styleDeclaration = new CSSStyleDeclaration();
+                scChild.styleDeclaration.factory =
+                    childDescriptor.stylesFactory;
+            }
+        }
+
+        // For each event, register the handle method, which is specified in
+        // the descriptor by name, as one of the child's event listeners.
+        var childEvents:Object = childDescriptor.events;
+        if (childEvents)
+        {
+            for (var eventName:String in childEvents)
+            {
+                var eventHandler:String = childEvents[eventName];
+                child.addEventListener(eventName,
+                                       childDescriptor.document[eventHandler]);
+            }
+        }
+
+        // For each effect, register the EffectManager as an event listener
+        var childEffects:Array = childDescriptor.effects;
+        if (childEffects)
+            child.registerEffects(childEffects);
+
+        if (child is IRepeaterClient)
+            IRepeaterClient(child).initializeRepeaterArrays(this);
+
+        // If an MXML id was specified, create a property with this name on
+        // the MXML document object whose value references the child.
+        // This should be the last step in initializing the child, so that
+        // it can't be referenced until initialization is complete.
+        // However, it must be done before executing executeBindings().
+        child.createReferenceOnParentDocument(
+            IFlexDisplayObject(childDescriptor.document));
+
+        if (!child.document)
+            child.document = childDescriptor.document;
+
+        // Repeaters don't get added as children of the Container,
+        // so they have their own initialization sequence.
+        if (child is IRepeater)
+        {
+            // Add this repeater to the list maintained by the parent
+            // container
+            if (!childRepeaters)
+                childRepeaters = [];
+            childRepeaters.push(child);
+
+            // The Binding Manager may have some data that it wants to bind to
+            // various properties of the newly created repeater.
+            child.executeBindings();
+
+            IRepeater(child).initializeRepeater(this, recurse);
+        }
+        else
+        {
+            // This needs to run before child.executeBindings(), because
+            // executeBindings() depends on the parent being set.
+            addChild(DisplayObject(child));
+
+            // The Binding Manager may have some data that it wants to bind to
+            // various properties of the newly created child.
+            child.executeBindings();
+
+            if (creationPolicy == ContainerCreationPolicy.QUEUED ||
+                creationPolicy == ContainerCreationPolicy.NONE)
+            {
+                child.addEventListener(FlexEvent.CREATION_COMPLETE,
+                                       creationCompleteHandler);
+            }
+        }
+
+        // Return a reference to the child UIComponent that was just created.
+        return child;
+    }
+
+    /**
+     *  @private
+     */
+    private function hasChildMatchingDescriptor(
+                            descriptor:UIComponentDescriptor):Boolean
+    {
+        // Optimization: If the descriptor has an id but no such id
+        // reference exists on the document, then there are no children
+        // in this container with that descriptor.
+        // (On the other hand, if there IS an id reference on the document,
+        // we can't be sure that it is for a child of this container. It
+        // could be an indexed reference in which some instances are
+        // in other containers. This happens when you have
+        // <Repeater>
+        //     <VBox>
+        //         <Button>
+        var id:String = descriptor.id;
+        if (id != null && document[id] == null)
+            return false;
+
+        var n:int = numChildren;
+        var i:int;
+
+        // Iterate over this container's children, looking for one
+        // that matches this descriptor
+        for (i = 0; i < n; i++)
+        {
+            var child:IUIComponent = IUIComponent(getChildAt(i));
+            if (child is IDeferredInstantiationUIComponent &&
+                IDeferredInstantiationUIComponent(child)
+                    .descriptor == descriptor)
+            {
+                return true;
+            }
+        }
+
+        // Also check this container's Repeaters, if there are any.
+        if (childRepeaters)
+        {
+            n = childRepeaters.length;
+            for (i = 0; i < n; i++)
+            {
+                if (IDeferredInstantiationUIComponent(childRepeaters[i])
+                        .descriptor == descriptor)
+                {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Methods: Support for rawChildren access
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  This class overrides addChild() to deal with only content children,
+     *  so in order to implement the rawChildren property we need
+     *  a parallel method that deals with all children.
+     */
+    mx_internal function rawChildren_addChild(child:DisplayObject):DisplayObject
+    {
+        // This method is only used to implement rawChildren.addChild(),
+        // so the child being added is assumed to be a non-content child.
+        // (You would use just addChild() to add a content child.)
+        // If there are no content children, the new child is placed
+        // in the pre-content partition.
+        // If there are content children, the new child is placed
+        // in the post-content partition.
+        if (_numChildren == 0)
+            _firstChildIndex++;
+
+        super.addingChild(child);
+        $addChild(child);
+        super.childAdded(child);
+
+        dispatchEvent(new Event("childrenChanged"));
+
+        return child;
+    }
+
+    /**
+     *  @private
+     *  This class overrides addChildAt() to deal with only content children,
+     *  so in order to implement the rawChildren property we need
+     *  a parallel method that deals with all children.
+     */
+    mx_internal function rawChildren_addChildAt(child:DisplayObject,
+                                                index:int):DisplayObject
+    {
+        if (_firstChildIndex < index &&
+            index < _firstChildIndex + _numChildren + 1)
+        {
+            _numChildren++;
+        }
+        else if (index <= _firstChildIndex)
+        {
+            _firstChildIndex++;
+        }
+
+        super.addingChild(child);
+        $addChildAt(child, index);
+        super.childAdded(child);
+
+        dispatchEvent(new Event("childrenChanged"));
+
+        return child;
+    }
+
+    /**
+     *  @private
+     *  This class overrides removeChild() to deal with only content children,
+     *  so in order to implement the rawChildren property we need
+     *  a parallel method that deals with all children.
+     */
+    mx_internal function rawChildren_removeChild(
+                                child:DisplayObject):DisplayObject
+    {
+        var index:int = rawChildren_getChildIndex(child);
+        return rawChildren_removeChildAt(index);
+    }
+
+    /**
+     *  @private
+     *  This class overrides removeChildAt() to deal with only content children,
+     *  so in order to implement the rawChildren property we need
+     *  a parallel method that deals with all children.
+     */
+    mx_internal function rawChildren_removeChildAt(index:int):DisplayObject
+    {
+        var child:DisplayObject = super.getChildAt(index);
+
+        super.removingChild(child);
+        $removeChildAt(index);
+        super.childRemoved(child);
+
+        if (_firstChildIndex < index &&
+            index < _firstChildIndex + _numChildren)
+        {
+            _numChildren--;
+        }
+        else if (_numChildren == 0 || index < _firstChildIndex)
+        {
+            _firstChildIndex--;
+        }
+
+        invalidateSize();
+        invalidateDisplayList();
+
+        dispatchEvent(new Event("childrenChanged"));
+
+        return child;
+    }
+
+    /**
+     *  @private
+     *  This class overrides getChildAt() to deal with only content children,
+     *  so in order to implement the rawChildren property we need
+     *  a parallel method that deals with all children.
+     */
+    mx_internal function rawChildren_getChildAt(index:int):DisplayObject
+    {
+        return super.getChildAt(index);
+    }
+
+    /**
+     *  @private
+     *  This class overrides getChildByName() to deal with only content children,
+     *  so in order to implement the rawChildren property we need
+     *  a parallel method that deals with all children.
+     */
+    mx_internal function rawChildren_getChildByName(name:String):DisplayObject
+    {
+        return super.getChildByName(name);
+    }
+
+    /**
+     *  @private
+     *  This class overrides getChildIndex() to deal with only content children,
+     *  so in order to implement the rawChildren property we need
+     *  a parallel method that deals with all children.
+     */
+    mx_internal function rawChildren_getChildIndex(child:DisplayObject):int
+    {
+        return super.getChildIndex(child);
+    }
+
+    /**
+     *  @private
+     *  This class overrides setChildIndex() to deal with only content children,
+     *  so in order to implement the rawChildren property we need
+     *  a parallel method that deals with all children.
+     */
+    mx_internal function rawChildren_setChildIndex(child:DisplayObject,
+                                                   newIndex:int):void
+    {
+        var oldIndex:int = super.getChildIndex(child);
+
+        super.setChildIndex(child, newIndex);
+
+        // Is this a piece of chrome that was previously before
+        // the content children and is now after them in the list?
+        if (oldIndex < _firstChildIndex && newIndex >= _firstChildIndex)
+        {
+            _firstChildIndex--;
+        }
+
+        // Is this a piece of chrome that was previously after
+        // the content children and is now before them in the list?
+        else if (oldIndex >= _firstChildIndex && newIndex <= _firstChildIndex)
+        {
+            _firstChildIndex++
+        }
+
+        dispatchEvent(new Event("childrenChanged"));
+    }
+
+    /**
+     *  @private
+     *  This class overrides getObjectsUnderPoint() to deal with only content children,
+     *  so in order to implement the rawChildren property we need
+     *  a parallel method that deals with all children.
+     */
+    mx_internal function rawChildren_getObjectsUnderPoint(pt:Point):Array
+    {
+        return super.getObjectsUnderPoint(pt);
+    }
+
+    /**
+     *  @private
+     *  This class overrides contains() to deal with only content children,
+     *  so in order to implement the rawChildren property we need
+     *  a parallel method that deals with all children.
+     */
+    mx_internal function rawChildren_contains(child:DisplayObject):Boolean
+    {
+        return super.contains(child);
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Methods: Chrome management
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Respond to size changes by setting the positions and sizes
+     *  of this container's borders.
+     *  This is an advanced method that you might override
+     *  when creating a subclass of Container.
+     *
+     *
Flex calls the layoutChrome() method when the
+     *  container is added to a parent container using the addChild() method,
+     *  and when the container's invalidateDisplayList() method is called.

+     *
+     *
The Container.layoutChrome() method is called regardless of the
+     *  value of the autoLayout property.

+     *
+     *
The Container.layoutChrome() method sets the
+     *  position and size of the Container container's border.
+     *  In every subclass of Container, the subclass's layoutChrome()
+     *  method should call the super.layoutChrome() method,
+     *  so that the border is positioned properly.

+     *
+     *  @param unscaledWidth Specifies the width of the component, in pixels,
+     *  in the component's coordinates, regardless of the value of the
+     *  scaleX property of the component.
+     *
+     *  @param unscaledHeight Specifies the height of the component, in pixels,
+     *  in the component's coordinates, regardless of the value of the
+     *  scaleY property of the component.
+     */
+    protected function layoutChrome(unscaledWidth:Number,
+                                    unscaledHeight:Number):void
+    {
+        // Border covers the whole thing.
+        if (border)
+        {
+            updateBackgroundImageRect();
+
+            border.move(0, 0);
+            border.setActualSize(unscaledWidth, unscaledHeight);
+        }
+    }
+
+    /**
+     *  Creates the container's border skin
+     *  if it is needed and does not already exist.
+     */
+    protected function createBorder():void
+    {
+        if (!border && isBorderNeeded())
+        {
+            var borderClass:Class = getStyle("borderSkin");
+
+            if (borderClass != null)
+            {
+                border = new borderClass();
+                border.name = "border";
+
+                if (border is IUIComponent)
+                    IUIComponent(border).enabled = enabled;
+                if (border is ISimpleStyleClient)
+                    ISimpleStyleClient(border).styleName = this;
+
+                // Add the border behind all the children.
+                rawChildren.addChildAt(DisplayObject(border), 0);
+
+                invalidateDisplayList();
+            }
+        }
+    }
+
+    /**
+     *  @private
+     */
+    private function isBorderNeeded():Boolean
+    {
+        //trace("isBorderNeeded",this,"ms",getStyle("mouseShield"),"borderStyle",getStyle("borderStyle"));
+
+        // If the borderSkin is a custom class, always assume the border is needed.
+        var c:Class = getStyle("borderSkin");
+
+        // Lookup the HaloBorder class by name to avoid a linkage dependency.
+        // Note: this code assumes HaloBorder is the default border skin. If this is changed
+        // in defaults.css, it must also be changed here.
+        try
+        {
+            if (c != getDefinitionByName("mx.skins.halo::HaloBorder"))
+                return true;
+        }
+        catch(e:Error)
+        {
+            return true;
+        }
+
+        var v:Object = getStyle("borderStyle");
+        if (v)
+        {
+            // If borderStyle is "none", then only create a border if the mouseShield style is true
+            // (meaning that there is a mouse event listener on this view). We don't create a border
+            // if our parent's mouseShieldChildren style is true.
+            if ((v != "none") || (v == "none" && getStyle("mouseShield")))
+            {
+                return true;
+            }
+        }
+
+        v = getStyle("backgroundColor");
+        if (v !== null && v !== "")
+            return true;
+
+        v = getStyle("backgroundImage");
+        return v != null && v != "";
+    }
+
+    /**
+     *  @private
+     */
+    mx_internal function invalidateViewMetricsAndPadding():void
+    {
+        _viewMetricsAndPadding = null;
+    }
+
+    /**
+     *  @private
+     */
+    private function createOrDestroyBlocker():void
+    {
+        // If this container is being enabled and a blocker exists,
+        // remove it. If this container is being disabled and a
+        // blocker doesn't exist, create it.
+        if (enabled)
+        {
+            if (blocker)
+            {
+                rawChildren.removeChild(blocker);
+                blocker = null;
+            }
+        }
+        else
+        {
+            if (!blocker)
+            {
+                blocker = new FlexSprite();
+                blocker.name = "blocker";
+                blocker.mouseEnabled = true;
+                rawChildren.addChild(blocker);
+
+                blocker.addEventListener(MouseEvent.CLICK,
+                                         blocker_clickHandler);
+
+                // If the focus is a child of ours, we clear it here.
+                var o:DisplayObject =
+                    focusManager ?
+                    DisplayObject(focusManager.getFocus()) :
+                    null;
+
+                while (o)
+                {
+                    if (o == this)
+                    {
+                        var sm:ISystemManager = systemManager;
+                        if (sm && sm.stage)
+                            sm.stage.focus = null;
+                        break;
+                    }
+                    o = o.parent;
+                }
+            }
+        }
+    }
+
+    /**
+     *  @private
+     */
+    private function updateBackgroundImageRect():void
+    {
+        var rectBorder:IRectangularBorder = border as IRectangularBorder;
+
+        if (!rectBorder)
+            return;
+
+        // If viewableWidth and viewableHeight are 0, we don't have any
+        // scrollbars or clipped content.
+        if (viewableWidth == 0 && viewableHeight == 0)
+        {
+            rectBorder.backgroundImageBounds = null;
+            return;
+        }
+
+        var vm:EdgeMetrics = viewMetrics;
+        var bkWidth:Number = viewableWidth ? viewableWidth :
+                    unscaledWidth - vm.left - vm.right;
+        var bkHeight:Number = viewableHeight ? viewableHeight :
+                    unscaledHeight - vm.top - vm.bottom;
+
+        if (getStyle("backgroundAttachment") == "fixed")
+        {
+            rectBorder.backgroundImageBounds = new Rectangle(vm.left, vm.top,
+                                                bkWidth, bkHeight);
+        }
+        else
+        {
+            rectBorder.backgroundImageBounds = new Rectangle(vm.left, vm.top,
+                    Math.max(scrollableWidth, bkWidth),
+                    Math.max(scrollableHeight, bkHeight));
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Methods: Scrolling
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    private function createContentPaneAndScrollbarsIfNeeded():Boolean
+    {
+        var bounds:Rectangle;
+        var changed:Boolean;
+
+        // No mask is needed if clipping isn't active
+        if (_clipContent)
+        {
+            // Get the new scrollable width, which is the equal to the right
+            // edge of the rightmost child.  Also get the new scrollable height.
+            bounds = getScrollableRect();
+
+            // Create or destroy scrollbars if necessary, and update the
+            // properties of the scrollbars.
+            changed = createScrollbarsIfNeeded(bounds);
+
+            if (border)
+                updateBackgroundImageRect();
+
+            return changed;
+        }
+        else
+        {
+            changed = createOrDestroyScrollbars(false, false, false);
+
+            // Get scrollableWidth and scrollableHeight for scrollChildren()
+            bounds = getScrollableRect();
+            scrollableWidth = bounds.right;
+            scrollableHeight = bounds.bottom;
+
+            if (changed && border)
+                updateBackgroundImageRect();
+
+            return changed;
+        }
+    }
+
+    /**
+     *  @private
+     */
+    mx_internal function getScrollableRect():Rectangle
+    {
+        var left:Number = 0;
+        var top:Number = 0;
+        var right:Number = 0;
+        var bottom:Number = 0;
+
+        var n:int = numChildren;
+        for (var i:int = 0; i < n; i++)
+        {
+            var child:DisplayObject = getChildAt(i);
+
+            if (child is IUIComponent && !IUIComponent(child).includeInLayout)
+                continue;
+
+            left = Math.min(left, child.x);
+            top = Math.min(top, child.y);
+
+            // width/height can be NaN if using percentages and
+            // hasn't been layed out yet.
+            if (!isNaN(child.width))
+                right = Math.max(right, child.x + child.width);
+            if (!isNaN(child.height))
+                bottom = Math.max(bottom, child.y + child.height);
+        }
+
+        // Add in the right/bottom margins and view metrics.
+        var vm:EdgeMetrics = viewMetrics;
+
+        var bounds:Rectangle = new Rectangle();
+        bounds.left = left;
+        bounds.top = top;
+        bounds.right = right;
+        bounds.bottom = bottom;
+
+        if (mx_internal::usePadding)
+        {
+            bounds.right += getStyle("paddingRight");
+            bounds.bottom += getStyle("paddingBottom");
+        }
+
+        return bounds;
+    }
+
+    /**
+     *  @private
+     */
+    private function createScrollbarsIfNeeded(bounds:Rectangle):Boolean
+    {
+        var newScrollableWidth:Number = bounds.right;
+        var newScrollableHeight:Number = bounds.bottom;
+        var newViewableWidth:Number = unscaledWidth;
+        var newViewableHeight:Number = unscaledHeight;
+        var hasNegativeCoords:Boolean = bounds.left < 0 || bounds.top < 0;
+
+        var vm:EdgeMetrics = viewMetrics;
+
+        // Several of the layout managers round floating-point numbers
+        // down, using Math.floor().
+        // The rounded-down width value is passed to UIComponent.setActualSize,
+        // which does the following:
+        //
+        //   unscaledWidth = w / scaleX
+        //
+        // Suppose "w" was originally 91.9 but the layout manager
+        // rounded it down to 91. Suppose scaleX is 0.01.
+        // Then unscaledWidth is 91/0.01 = 9100, but it would have been
+        // 91.9/0.01 = 9190 if it weren't for the rounding.
+        // To undo the effect of the rounding, we'll add a fudge factor to
+        // newViewableWidth. That way, we don't display unwanted scrollbars.
+        if (scaleX != 1.0)
+            newViewableWidth += 1.0 / Math.abs(scaleX);
+        if (scaleY != 1.0)
+            newViewableHeight += 1.0 / Math.abs(scaleY);
+
+        newViewableWidth = Math.floor(newViewableWidth);
+        newViewableHeight = Math.floor(newViewableHeight);
+        newScrollableWidth = Math.floor(newScrollableWidth);
+        newScrollableHeight = Math.floor(newScrollableHeight);
+
+        if (horizontalScrollBar && horizontalScrollPolicy != ScrollPolicy.ON)
+            newViewableHeight -= horizontalScrollBar.minHeight;
+        if (verticalScrollBar && verticalScrollPolicy != ScrollPolicy.ON)
+            newViewableWidth -= verticalScrollBar.minWidth;
+
+        newViewableWidth -= (vm.left + vm.right);
+        newViewableHeight -= (vm.top + vm.bottom);
+
+        var needHorizontal:Boolean =
+            horizontalScrollPolicy == ScrollPolicy.ON;
+        var needVertical:Boolean =
+            verticalScrollPolicy == ScrollPolicy.ON;
+
+        var needContentPane:Boolean =
+            needHorizontal ||
+            needVertical ||
+            hasNegativeCoords ||
+            overlay != null ||
+            vm.left > 0 ||
+            vm.top > 0;
+
+        // These "if" statements are tuned for the most common case,
+        // which is that the Container does not need scrollbars.
+        if (newViewableWidth < newScrollableWidth)
+        {
+            needContentPane = true;
+
+            // Don't display scrollbars if the Container is so small
+            // that scrollbars would occlude everything else
+            // or the scrollbar buttons would overlap.
+            if (horizontalScrollPolicy == ScrollPolicy.AUTO &&
+                unscaledHeight - vm.top - vm.bottom >= 18 &&
+                unscaledWidth - vm.left - vm.right >= 32)
+            {
+                needHorizontal = true;
+            }
+        }
+        if (newViewableHeight < newScrollableHeight)
+        {
+            needContentPane = true;
+
+            if (verticalScrollPolicy == ScrollPolicy.AUTO &&
+                unscaledWidth - vm.left - vm.right >= 18 &&
+                unscaledHeight - vm.top - vm.bottom >= 32)
+            {
+                needVertical = true;
+            }
+        }
+
+        // Fix for 106095. The logic here says "if removing the scrollbars
+        // would make enough room to display the view's children, then remove
+        // the scrollbars".
+        if (needHorizontal &&
+            needVertical &&
+            horizontalScrollPolicy == ScrollPolicy.AUTO &&
+            verticalScrollPolicy == ScrollPolicy.AUTO &&
+            horizontalScrollBar &&
+            verticalScrollBar &&
+            newViewableWidth + verticalScrollBar.minWidth >= newScrollableWidth &&
+            newViewableHeight + horizontalScrollBar.minHeight >= newScrollableHeight)
+        {
+            needHorizontal = needVertical = false;
+        }
+
+        // If the vertical scrollbar is going to be removed anyway, and
+        // removing it would also free up enough space for the contents to fit
+        // horizontally, then there's no need for the horizontal scrollbar
+        // either.
+        else if (needHorizontal &&
+                 !needVertical &&
+                 verticalScrollBar &&
+                 horizontalScrollPolicy == ScrollPolicy.AUTO &&
+                 newViewableWidth + verticalScrollBar.minWidth >= newScrollableWidth)
+        {
+            needHorizontal = false;
+        }
+
+        var changed:Boolean = createOrDestroyScrollbars(
+            needHorizontal, needVertical, needContentPane);
+
+        if ((scrollableWidth != newScrollableWidth ||
+             viewableWidth != newViewableWidth) ||
+             changed)
+        {
+            if (horizontalScrollBar)
+            {
+                horizontalScrollBar.setScrollProperties(
+                    newViewableWidth, 0,
+                    newScrollableWidth - newViewableWidth, horizontalPageScrollSize);
+                scrollPositionChanged = true;
+            }
+
+            viewableWidth = newViewableWidth;
+            scrollableWidth = newScrollableWidth;
+        }
+
+        if ((scrollableHeight != newScrollableHeight ||
+             viewableHeight != newViewableHeight) ||
+             changed)
+        {
+
+            if (verticalScrollBar)
+            {
+                verticalScrollBar.setScrollProperties(
+                    newViewableHeight, 0,
+                    newScrollableHeight-newViewableHeight, verticalPageScrollSize);
+
+                scrollPositionChanged = true;
+            }
+
+            viewableHeight = newViewableHeight;
+            scrollableHeight = newScrollableHeight;
+        }
+
+        return changed;
+    }
+
+    /**
+     *  @private
+     */
+    private function createOrDestroyScrollbars(
+                            needHorizontal:Boolean,
+                            needVertical:Boolean,
+                            needContentPane:Boolean):Boolean
+    {
+        var changed:Boolean = false;
+        var fm:IFocusManager;
+
+        if (needHorizontal || needVertical || needContentPane)
+            createContentPane();
+
+        // Create or destroy horizontal scrollbar.
+        if (needHorizontal)
+        {
+            if (!horizontalScrollBar)
+            {
+                horizontalScrollBar = new HScrollBar();
+                horizontalScrollBar.name = "horizontalScrollBar";
+
+                var horizontalScrollBarStyleName:String =
+                    getStyle("horizontalScrollBarStyleName");
+                if (horizontalScrollBarStyleName && horizontalScrollBar is ISimpleStyleClient)
+                    ISimpleStyleClient(horizontalScrollBar).styleName = horizontalScrollBarStyleName;
+
+                rawChildren.addChild(DisplayObject(horizontalScrollBar));
+                horizontalScrollBar.lineScrollSize = horizontalLineScrollSize;
+                horizontalScrollBar.pageScrollSize = horizontalPageScrollSize;
+                horizontalScrollBar.addEventListener(ScrollEvent.SCROLL, horizontalScrollBar_scrollHandler);
+                horizontalScrollBar.enabled = enabled;
+                if (horizontalScrollBar is IInvalidating)
+                    IInvalidating(horizontalScrollBar).validateNow();
+
+                invalidateDisplayList();
+                invalidateViewMetricsAndPadding();
+
+                changed = true;
+
+                if (!verticalScrollBar)
+                    addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
+            }
+        }
+        else
+        {
+            if (horizontalScrollBar)
+            {
+                horizontalScrollBar.removeEventListener(
+                    ScrollEvent.SCROLL,
+                    horizontalScrollBar_scrollHandler);
+
+                rawChildren.removeChild(DisplayObject(horizontalScrollBar));
+                horizontalScrollBar = null;
+
+                viewableWidth = scrollableWidth = 0;
+
+                if (_horizontalScrollPosition != 0)
+                {
+                    _horizontalScrollPosition = 0;
+                    scrollPositionChanged = true;
+                }
+
+                invalidateDisplayList();
+                invalidateViewMetricsAndPadding();
+
+                changed = true;
+
+                fm = focusManager;
+                if (!verticalScrollBar && (!fm || fm.getFocus() != this))
+                    removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
+            }
+        }
+
+        // Create or destroy vertical scrollbar.
+        if (needVertical)
+        {
+            if (!verticalScrollBar)
+            {
+                verticalScrollBar = new VScrollBar();
+                verticalScrollBar.name = "verticalScrollBar";
+
+                var verticalScrollBarStyleName:String =
+                    getStyle("verticalScrollBarStyleName");
+                if (verticalScrollBarStyleName && verticalScrollBar is ISimpleStyleClient)
+                    ISimpleStyleClient(verticalScrollBar).styleName = verticalScrollBarStyleName;
+
+                rawChildren.addChild(DisplayObject(verticalScrollBar));
+                verticalScrollBar.lineScrollSize = verticalLineScrollSize;
+                verticalScrollBar.pageScrollSize = verticalPageScrollSize;
+                verticalScrollBar.addEventListener(ScrollEvent.SCROLL, verticalScrollBar_scrollHandler);
+                verticalScrollBar.enabled = enabled;
+                if (verticalScrollBar is IInvalidating)
+                    IInvalidating(verticalScrollBar).validateNow();
+
+                invalidateDisplayList();
+                invalidateViewMetricsAndPadding();
+
+                changed = true;
+
+                if (!horizontalScrollBar)
+                    addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
+
+                // Listen for "mouseWheel" events on myself or any of my children
+                addEventListener(MouseEvent.MOUSE_WHEEL, mouseWheelHandler);
+            }
+        }
+        else
+        {
+            if (verticalScrollBar)
+            {
+                verticalScrollBar.removeEventListener(ScrollEvent.SCROLL, verticalScrollBar_scrollHandler);
+
+                rawChildren.removeChild(DisplayObject(verticalScrollBar));
+                verticalScrollBar = null;
+
+                viewableHeight = scrollableHeight = 0;
+
+                if (_verticalScrollPosition != 0)
+                {
+                    _verticalScrollPosition = 0;
+                    scrollPositionChanged = true;
+                }
+
+                invalidateDisplayList();
+                invalidateViewMetricsAndPadding();
+
+                changed = true;
+
+                fm = focusManager;
+                if (!horizontalScrollBar && (!fm || fm.getFocus() != this))
+                    removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
+
+                removeEventListener(MouseEvent.MOUSE_WHEEL, mouseWheelHandler);
+            }
+        }
+
+        // Create or destroy the whiteBox.
+        // If both scrollBars are active, there's an empty space
+        // between the two scrollBars in the lower right corner.
+        // The whiteBox fills that space, so that the container's
+        // children aren't visible when they scroll underneath.
+        if (horizontalScrollBar && verticalScrollBar)
+        {
+            if (!whiteBox)
+            {
+                whiteBox = new FlexShape();
+                whiteBox.name = "whiteBox";
+
+                var g:Graphics = whiteBox.graphics;
+                g.beginFill(0xFFFFFF);
+                g.drawRect(0, 0, verticalScrollBar.minWidth, horizontalScrollBar.minHeight);
+                g.endFill()
+
+                rawChildren.addChild(whiteBox);
+            }
+        }
+        else
+        {
+            if (whiteBox)
+            {
+                rawChildren.removeChild(whiteBox);
+                whiteBox = null;
+            }
+        }
+
+        return changed;
+    }
+
+    /**
+     *  @private
+     *  Ensures that horizontalScrollPosition is in the range
+     *  from 0 through maxHorizontalScrollPosition and that
+     *  verticalScrollPosition is in the range from 0 through
+     *  maxVerticalScrollPosition.
+     *  Returns true if either horizontalScrollPosition or
+     *  verticalScrollPosition was changed to ensure this.
+     */
+    private function clampScrollPositions():Boolean
+    {
+        var changed:Boolean = false;
+
+        // Clamp horizontalScrollPosition to the range
+        // 0 through maxHorizontalScrollPosition.
+        // If horizontalScrollBar doesn't exist,
+        // maxHorizontalScrollPosition will be 0.
+        if (_horizontalScrollPosition < 0)
+        {
+            _horizontalScrollPosition = 0;
+            changed = true;
+        }
+        else if (_horizontalScrollPosition > maxHorizontalScrollPosition)
+        {
+            _horizontalScrollPosition = maxHorizontalScrollPosition;
+            changed = true;
+        }
+
+        // Set the position of the horizontal scrollbar's thumb.
+        if (horizontalScrollBar &&
+            horizontalScrollBar.scrollPosition != _horizontalScrollPosition)
+        {
+            horizontalScrollBar.scrollPosition = _horizontalScrollPosition;
+        }
+
+        // Clamp verticalScrollPosition to the range
+        // 0 through maxVerticalScrollPosition.
+        // If verticalScrollBar doesn't exist,
+        // maxVerticalScrollPosition will be 0.
+        if (_verticalScrollPosition < 0)
+        {
+            _verticalScrollPosition = 0;
+            changed = true;
+        }
+        else if (_verticalScrollPosition > maxVerticalScrollPosition)
+        {
+            _verticalScrollPosition = maxVerticalScrollPosition;
+            changed = true;
+        }
+
+        // Set the position of the vertical scrollbar's thumb.
+        if (verticalScrollBar &&
+            verticalScrollBar.scrollPosition != _verticalScrollPosition)
+        {
+            verticalScrollBar.scrollPosition = _verticalScrollPosition;
+        }
+
+        return changed;
+    }
+
+    /**
+     *  @private
+     */
+    mx_internal function createContentPane():void
+    {
+        if (contentPane)
+            return;
+
+        creatingContentPane = true;
+
+        // Reparent the children.  Get the number before we create contentPane
+        // because that changes logic of how many children we have
+        var n:int = numChildren;
+
+        var newPane:Sprite = new FlexSprite();
+        newPane.name = "contentPane";
+        newPane.tabChildren = true;
+
+        // Place content pane above border and background image but below
+        // all other chrome.
+        var childIndex:int;
+        if (border)
+        {
+            childIndex = rawChildren.getChildIndex(DisplayObject(border)) + 1;
+            if (border is IRectangularBorder && IRectangularBorder(border).hasBackgroundImage)
+                childIndex++;
+        }
+        else
+        {
+            childIndex = 0;
+        }
+        rawChildren.addChildAt(newPane, childIndex);
+
+        for (var i:int = 0; i < n; i++)
+        {
+            // use super because contentPane now exists and messes up getChildAt();
+            var child:IUIComponent =
+                IUIComponent(super.getChildAt(_firstChildIndex));
+            newPane.addChild(DisplayObject(child));
+            child.parentChanged(newPane);
+            _numChildren--; // required
+        }
+
+        contentPane = newPane;
+
+        creatingContentPane = false
+
+        // UIComponent sets $visible to false. If we don't make it true here,
+        // nothing shows up. Making this true should be harmless, as the
+        // container itself should be false, and so should all its children.
+        contentPane.visible = true;
+    }
+
+    /**
+     *  Positions the container's content area relative to the viewable area
+     *  based on the horizontalScrollPosition and verticalScrollPosition properties.
+     *  Content that doesn't appear in the viewable area gets clipped.
+     *  This method should be overridden by subclasses that have scrollable
+     *  chrome in the content area.
+     */
+    protected function scrollChildren():void
+    {
+        if (!contentPane)
+            return;
+
+        var vm:EdgeMetrics = viewMetrics;
+
+        var x:Number = 0;
+        var y:Number = 0;
+        var w:Number = unscaledWidth - vm.left - vm.right;
+        var h:Number = unscaledHeight - vm.top - vm.bottom;
+
+        if (_clipContent)
+        {
+            x += _horizontalScrollPosition;
+
+            if (horizontalScrollBar)
+                 w = viewableWidth;
+
+            y += _verticalScrollPosition;
+
+            if (verticalScrollBar)
+                h = viewableHeight;
+        }
+        else
+        {
+            w = scrollableWidth;
+            h = scrollableHeight;
+        }
+
+        // If we have enough space to display everything, don't set
+        // scrollRect.
+        var sr:Rectangle = getScrollableRect();
+        if (x == 0 && y == 0                            // Not scrolled
+                && w >= sr.right && h >= sr.bottom &&   // Vertical content visible
+                sr.left >= 0 && sr.top >= 0 && _forceClippingCount <= 0)            // No negative coordinates
+        {
+            contentPane.scrollRect = null;
+            contentPane.opaqueBackground = null;
+            contentPane.cacheAsBitmap = false;
+        }
+        else
+        {
+            contentPane.scrollRect = new Rectangle(x, y, w, h);
+        }
+
+        if (focusPane)
+            focusPane.scrollRect = contentPane.scrollRect;
+
+        if (border && border is IRectangularBorder &&
+            IRectangularBorder(border).hasBackgroundImage)
+        {
+            IRectangularBorder(border).layoutBackgroundImage();
+        }
+    }
+
+    /**
+     *  @private
+     */
+    private function dispatchScrollEvent(direction:String,
+                                         oldPosition:Number,
+                                         newPosition:Number,
+                                         detail:String):void
+    {
+        var event:ScrollEvent = new ScrollEvent(ScrollEvent.SCROLL);
+        event.direction = direction;
+        event.position = newPosition;
+        event.delta = newPosition - oldPosition;
+        event.detail = detail;
+        dispatchEvent(event);
+    }
+
+    /**
+     *  @private
+     *  Used by a child component to force clipping during a Move effect
+     */
+    private var _forceClippingCount:int;
+
+    mx_internal function set forceClipping(value:Boolean):void
+    {
+        if (_clipContent) // Can only force clipping if clipContent == true
+        {
+            if (value)
+                _forceClippingCount++
+            else
+                _forceClippingCount--;
+
+            createContentPane();
+            scrollChildren();
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Methods: Binding
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Executes the bindings into this Container's child UIComponent objects.
+     *  Flex calls this method automatically once a Container has been created.
+     *
+     *  @param recurse If false, then only execute the bindings
+     *  on the immediate children of this Container.
+     *  If true, then also execute the bindings on this
+     *  container's grandchildren,
+     *  great-grandchildren, and so on.
+     */
+    public function executeChildBindings(recurse:Boolean):void
+    {
+        var n:int = numChildren;
+        for (var i:int = 0; i < n; i++)
+        {
+            var child:IUIComponent = IUIComponent(getChildAt(i));
+            if (child is IDeferredInstantiationUIComponent)
+            {
+                IDeferredInstantiationUIComponent(child).
+                    executeBindings(recurse);
+            }
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Overridden event handlers
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    override protected function keyDownHandler(event:KeyboardEvent):void
+    {
+        // If a text field currently has focus, it is handling all arrow keys.
+        // We shouldn't also scroll this Container.
+        var focusObj:Object = getFocus();
+        if (focusObj is TextField)
+            return;
+
+        var direction:String;
+        var oldPos:Number;
+
+        if (verticalScrollBar)
+        {
+            direction = ScrollEventDirection.VERTICAL;
+            oldPos = verticalScrollPosition;
+
+            switch (event.keyCode)
+            {
+                case Keyboard.DOWN:
+                {
+                    verticalScrollPosition += verticalLineScrollSize;
+                    dispatchScrollEvent(direction, oldPos,
+                                        verticalScrollPosition,
+                                        ScrollEventDetail.LINE_DOWN);
+                    event.stopPropagation();
+                    break;
+                }
+
+                case Keyboard.UP:
+                {
+                    verticalScrollPosition -= verticalLineScrollSize;
+                    dispatchScrollEvent(direction, oldPos,
+                                        verticalScrollPosition,
+                                        ScrollEventDetail.LINE_UP);
+                    event.stopPropagation();
+                    break;
+                }
+
+                case Keyboard.PAGE_UP:
+                {
+                    verticalScrollPosition -= verticalPageScrollSize;
+                    dispatchScrollEvent(direction, oldPos,
+                                        verticalScrollPosition,
+                                        ScrollEventDetail.PAGE_UP);
+                    event.stopPropagation();
+                    break;
+                }
+
+                case Keyboard.PAGE_DOWN:
+                {
+                    verticalScrollPosition += verticalPageScrollSize;
+                    dispatchScrollEvent(direction, oldPos,
+                                        verticalScrollPosition,
+                                        ScrollEventDetail.PAGE_DOWN);
+                    event.stopPropagation();
+                    break;
+                }
+
+                case Keyboard.HOME:
+                {
+                    verticalScrollPosition =
+                        verticalScrollBar.minScrollPosition;
+                    dispatchScrollEvent(direction, oldPos,
+                                        verticalScrollPosition,
+                                        ScrollEventDetail.AT_TOP);
+
+                    event.stopPropagation();
+                    break;
+                }
+
+                case Keyboard.END:
+                {
+                    verticalScrollPosition =
+                        verticalScrollBar.maxScrollPosition;
+                    dispatchScrollEvent(direction, oldPos,
+                                        verticalScrollPosition,
+                                        ScrollEventDetail.AT_BOTTOM);
+                    event.stopPropagation();
+                    break;
+                }
+            }
+        }
+
+        if (horizontalScrollBar)
+        {
+            direction = ScrollEventDirection.HORIZONTAL;
+            oldPos = horizontalScrollPosition;
+
+            switch (event.keyCode)
+            {
+                case Keyboard.LEFT:
+                {
+                    horizontalScrollPosition -= horizontalLineScrollSize;
+                    dispatchScrollEvent(direction, oldPos,
+                                        horizontalScrollPosition,
+                                        ScrollEventDetail.LINE_LEFT);
+                    event.stopPropagation();
+                    break;
+                }
+
+                case Keyboard.RIGHT:
+                {
+                    horizontalScrollPosition += horizontalLineScrollSize;
+                    dispatchScrollEvent(direction, oldPos,
+                                        horizontalScrollPosition,
+                                        ScrollEventDetail.LINE_RIGHT);
+                    event.stopPropagation();
+                    break;
+                }
+            }
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Event handlers
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  This method copied verbatim from mx.core.ScrollControlBase.
+     */
+    private function mouseWheelHandler(event:MouseEvent):void
+    {
+        // If this Container has a vertical scrollbar, then handle the event
+        // and prevent further bubbling
+        if (verticalScrollBar)
+        {
+            event.stopPropagation();
+
+            var scrollDirection:int = event.delta <= 0 ? 1 : -1;
+
+            var lineScrollSize:int = verticalScrollBar ?
+                                     verticalScrollBar.lineScrollSize :
+                                     1;
+
+            // Make sure we scroll by at least one line
+            var scrollAmount:Number =
+                Math.max(Math.abs(event.delta), lineScrollSize);
+
+            // Multiply by 3 to make scrolling a little faster
+            var oldPosition:Number = verticalScrollPosition;
+            verticalScrollPosition += 3 * scrollAmount * scrollDirection;
+
+            dispatchScrollEvent(ScrollEventDirection.VERTICAL,
+                                oldPosition, verticalScrollPosition,
+                                event.delta <= 0 ?
+                                ScrollEventDetail.LINE_UP :
+                                ScrollEventDetail.LINE_DOWN);
+        }
+    }
+
+    /**
+     *  @private
+     *  This function is called when the LayoutManager finishes running.
+     *  Clear the forceLayout flag that was set earlier.
+     */
+    private function layoutCompleteHandler(event:FlexEvent):void
+    {
+        UIComponentGlobals.layoutManager.removeEventListener(
+            FlexEvent.UPDATE_COMPLETE, layoutCompleteHandler);
+        forceLayout = false;
+
+        var needToScrollChildren:Boolean = false;
+
+        if (!isNaN(horizontalScrollPositionPending))
+        {
+            if (horizontalScrollPositionPending < 0)
+                horizontalScrollPositionPending = 0;
+            else if (horizontalScrollPositionPending > maxHorizontalScrollPosition)
+                horizontalScrollPositionPending = maxHorizontalScrollPosition;
+
+            // Set the position of the horizontal scrollbar's thumb.
+            if (horizontalScrollBar &&
+                horizontalScrollBar.scrollPosition !=
+                horizontalScrollPositionPending)
+            {
+                _horizontalScrollPosition = horizontalScrollPositionPending;
+                horizontalScrollBar.scrollPosition =
+                    horizontalScrollPositionPending;
+                needToScrollChildren = true;
+            }
+
+            horizontalScrollPositionPending = NaN;
+        }
+
+        if (!isNaN(verticalScrollPositionPending))
+        {
+            // Clamp verticalScrollPosition to the range 0 through maxVerticalScrollPosition.
+            // If verticalScrollBar doesn't exist, maxVerticalScrollPosition will be 0.
+            if (verticalScrollPositionPending < 0)
+                verticalScrollPositionPending = 0;
+            else if (verticalScrollPositionPending > maxVerticalScrollPosition)
+                verticalScrollPositionPending = maxVerticalScrollPosition;
+
+            // Set the position of the vertical scrollbar's thumb.
+            if (verticalScrollBar && verticalScrollBar.scrollPosition != verticalScrollPositionPending)
+            {
+                _verticalScrollPosition = verticalScrollPositionPending;
+                verticalScrollBar.scrollPosition = verticalScrollPositionPending;
+                needToScrollChildren = true;
+            }
+
+            verticalScrollPositionPending = NaN;
+        }
+
+        if (needToScrollChildren)
+            scrollChildren();
+    }
+
+    /**
+     *  @private
+     */
+    private function creationCompleteHandler(event:FlexEvent):void
+    {
+        numChildrenCreated--;
+        if (numChildrenCreated <= 0)
+            dispatchEvent(new FlexEvent("childrenCreationComplete"));
+    }
+
+    /**
+     *  @private
+     *  This method is called if the user interactively moves
+     *  the horizontal scrollbar thumb.
+     */
+    private function horizontalScrollBar_scrollHandler(event:Event):void
+    {
+        // TextField.scroll bubbles so you might see it here
+        if (event is ScrollEvent)
+        {
+            var oldPos:Number = horizontalScrollPosition;
+            horizontalScrollPosition = horizontalScrollBar.scrollPosition;
+
+            dispatchScrollEvent(ScrollEventDirection.HORIZONTAL,
+                                oldPos,
+                                horizontalScrollPosition,
+                                ScrollEvent(event).detail);
+        }
+    }
+
+    /**
+     *  @private
+     *  This method is called if the user interactively moves
+     *  the vertical scrollbar thumb.
+     */
+    private function verticalScrollBar_scrollHandler(event:Event):void
+    {
+        // TextField.scroll bubbles so you might see it here
+        if (event is ScrollEvent)
+        {
+            var oldPos:Number = verticalScrollPosition;
+            verticalScrollPosition = verticalScrollBar.scrollPosition;
+
+            dispatchScrollEvent(ScrollEventDirection.VERTICAL,
+                                oldPos,
+                                verticalScrollPosition,
+                                ScrollEvent(event).detail);
+        }
+    }
+
+    /**
+     *  @private
+     */
+    private function blocker_clickHandler(event:Event):void
+    {
+        // Swallow click events from blocker.
+        event.stopPropagation();
+    }
+}
+
+}