Transferred from the Adobe Open Source Subversion Repository

Revision: 19230
Author:   clucier@adobe.com
Date:     2010-12-09T19:21:38.155713Z

Log Message:
-----------
Proper URL handling for BitmapImage..we now support unicode characters.

QE notes: None
Doc notes: None
Bugs: SDK-28725
Reviewer: Ryan
Tests run: Checkin, Cyclone (some tests had to be excluded).
Is noteworthy for integration: No

Modified Paths:
--------------
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/controls/SWFLoader.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/primitives/BitmapImage.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/utils/LoaderUtil.as</path>

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

--- frameworks/projects/spark/src/spark/primitives/BitmapImage.as
+++ frameworks/projects/spark/src/spark/primitives/BitmapImage.as
@@ -11,1788 +11,1796 @@

 package spark.primitives
 {
-
-    import flash.display.Bitmap;
-    import flash.display.BitmapData;
-    import flash.display.DisplayObject;
-    import flash.display.DisplayObjectContainer;
-    import flash.display.Graphics;
-    import flash.display.Loader;
-    import flash.display.LoaderInfo;
-    import flash.display.Sprite;
-    import flash.events.Event;
-    import flash.events.HTTPStatusEvent;
-    import flash.events.IOErrorEvent;
-    import flash.events.ProgressEvent;
-    import flash.events.SecurityErrorEvent;
-    import flash.geom.Matrix;
-    import flash.geom.Point;
-    import flash.geom.Rectangle;
-    import flash.net.URLRequest;
-    import flash.system.ApplicationDomain;
-    import flash.system.LoaderContext;
-    import flash.utils.ByteArray;
-
-    import mx.core.IInvalidating;
-    import mx.core.mx_internal;
-    import mx.events.FlexEvent;
-    import mx.graphics.BitmapFillMode;
-    import mx.graphics.BitmapScaleMode;
-    import mx.graphics.BitmapSmoothingQuality;
-
-    import spark.core.ContentRequest;
-    import spark.core.DisplayObjectSharingMode;
-    import spark.core.IContentLoader;
-    import spark.layouts.HorizontalAlign;
-    import spark.layouts.VerticalAlign;
-    import spark.primitives.supportClasses.GraphicElement;
-
-    use namespace mx_internal;
-
-    //--------------------------------------
-    //  Events
-    //--------------------------------------
-
-    /**
-     *  Dispatched when content loading is complete. This
-     *  event is only dispatched for url and ByteArray based
-     *  sources (those sources requiring a Loader).
-     *
-     *
Note that for content loaded via Loader, both
-     *  ready and complete events
-     *  are dispatched.
  For other source types such as
-     *  embeds, only ready is dispatched.
-     *
-     *  @eventType flash.events.Event.COMPLETE
+
+import flash.display.Bitmap;
+import flash.display.BitmapData;
+import flash.display.DisplayObject;
+import flash.display.DisplayObjectContainer;
+import flash.display.Graphics;
+import flash.display.Loader;
+import flash.display.LoaderInfo;
+import flash.display.Sprite;
+import flash.events.Event;
+import flash.events.HTTPStatusEvent;
+import flash.events.IOErrorEvent;
+import flash.events.ProgressEvent;
+import flash.events.SecurityErrorEvent;
+import flash.geom.Matrix;
+import flash.geom.Point;
+import flash.geom.Rectangle;
+import flash.net.URLRequest;
+import flash.system.ApplicationDomain;
+import flash.system.LoaderContext;
+import flash.utils.ByteArray;
+
+import mx.core.IInvalidating;
+import mx.core.mx_internal;
+import mx.events.FlexEvent;
+import mx.graphics.BitmapFillMode;
+import mx.graphics.BitmapScaleMode;
+import mx.graphics.BitmapSmoothingQuality;
+import mx.utils.LoaderUtil;
+
+import spark.core.ContentRequest;
+import spark.core.DisplayObjectSharingMode;
+import spark.core.IContentLoader;
+import spark.layouts.HorizontalAlign;
+import spark.layouts.VerticalAlign;
+import spark.primitives.supportClasses.GraphicElement;
+
+use namespace mx_internal;
+
+//--------------------------------------
+//  Events
+//--------------------------------------
+
+/**
+ *  Dispatched when content loading is complete. This
+ *  event is only dispatched for url and ByteArray based
+ *  sources (those sources requiring a Loader).
+ *
+ *
Note that for content loaded via Loader, both
+ *  ready and complete events
+ *  are dispatched.
  For other source types such as
+ *  embeds, only ready is dispatched.
+ *
+ *  @eventType flash.events.Event.COMPLETE
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 2.0
+ *  @productversion Flex 4.5
+ */
+[Event(name="complete", type="flash.events.Event")]
+
+/**
+ *  Dispatched when a network request is made over HTTP
+ *  and Flash Player or AIR can detect the HTTP status code.
+ *
+ *  @eventType flash.events.HTTPStatusEvent.HTTP_STATUS
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 2.0
+ *  @productversion Flex 4.5
+ */
+[Event(name="httpStatus", type="flash.events.HTTPStatusEvent")]
+
+/**
+ *  Dispatched when an input/output error occurs.
+ *  @see flash.events.IOErrorEvent
+ *
+ *  @eventType flash.events.IOErrorEvent.IO_ERROR
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 2.0
+ *  @productversion Flex 4.5
+ */
+[Event(name="ioError", type="flash.events.IOErrorEvent")]
+
+/**
+ *  Dispatched when content is loading.
+ *
+ *
Note:
+ *  The progress event is not guaranteed to be dispatched.
+ *  The complete event may be received, without any
+ *  progress events being dispatched.
+ *  This can happen when the loaded content is a local file.

+ *
+ *  @eventType flash.events.ProgressEvent.PROGRESS
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 2.0
+ *  @productversion Flex 4.5
+ */
+[Event(name="progress", type="flash.events.ProgressEvent")]
+
+/**
+ *  Dispatched when content loading is complete.  Unlike the
+ *  complete event, this event is dispatched for
+ *  all source types.
+ *
+ *
Note that for content loaded via Loader, both
+ *  ready and complete events
+ *  are dispatched.
  For other source types such as
+ *  embeds, only ready is dispatched.
+ *
+ *  @eventType mx.events.FlexEvent.READY
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 2.0
+ *  @productversion Flex 4.5
+ */
+[Event(name="ready", type="mx.events.FlexEvent")]
+
+/**
+ *  Dispatched when a security error occurs.
+ *  @see flash.events.SecurityErrorEvent
+ *
+ *  @eventType flash.events.SecurityErrorEvent.SECURITY_ERROR
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 2.0
+ *  @productversion Flex 4.5
+ */
+[Event(name="securityError", type="flash.events.SecurityErrorEvent")]
+
+/**
+ *  A BitmapImage element defines a rectangular region in its parent element's
+ *  coordinate space, filled with bitmap data drawn from a source file or
+ *  source URL.
+ *
+ *  @includeExample examples/BitmapImageExample.mxml
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 2.0
+ *  @productversion Flex 4.0
+ */
+public class BitmapImage extends GraphicElement
+{
+    include "../core/Version.as";
+
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Constructor.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function BitmapImage()
+    {
+        super();
+
+        // Typically, this should not be mirrored.
+        layoutDirection = "ltr";
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Properties
+    //
+    //--------------------------------------------------------------------------
+
+    private var _scaleGridBottom:Number;
+    private var _scaleGridLeft:Number;
+    private var _scaleGridRight:Number;
+    private var _scaleGridTop:Number;
+    private var bitmapDataCreated:Boolean;
+    private static var matrix:Matrix = new Matrix();
+    private var cachedSourceGrid:Array;
+    private var cachedDestGrid:Array;
+    private var imageWidth:Number = NaN;
+    private var imageHeight:Number = NaN;
+    private var loadedContent:DisplayObject;
+    private var loadingContent:Object;
+    private var previousUnscaledWidth:Number;
+    private var previousUnscaledHeight:Number;
+    private var sourceInvalid:Boolean;
+    private var loadFailed:Boolean;
+
+    //----------------------------------
+    //  bitmapData
+    //----------------------------------
+
+    private var _bitmapData:BitmapData;
+
+    /**
+     *  Returns a copy of the BitmapData object representing
+     *  the currently loaded image content (unscaled).  This property
+     *  is null for untrusted cross domain content.
+     *
+     *  @default null
      *
      *  @langversion 3.0
      *  @playerversion Flash 10
      *  @playerversion AIR 2.0
      *  @productversion Flex 4.5
      */
-    [Event(name="complete", type="flash.events.Event")]
-
-    /**
-     *  Dispatched when a network request is made over HTTP
-     *  and Flash Player or AIR can detect the HTTP status code.
-     *
-     *  @eventType flash.events.HTTPStatusEvent.HTTP_STATUS
+    public function get bitmapData():BitmapData
+    {
+        return _bitmapData ? _bitmapData.clone() : _bitmapData;
+    }
+
+    //----------------------------------
+    //  bytesLoaded
+    //----------------------------------
+
+    private var _bytesLoaded:Number = NaN;
+
+    /**
+     *  The number of bytes of the image already loaded.
+     *  Only relevant for images loaded by request URL.
+     *
+     *  @default NaN
      *
      *  @langversion 3.0
      *  @playerversion Flash 10
      *  @playerversion AIR 2.0
      *  @productversion Flex 4.5
      */
-    [Event(name="httpStatus", type="flash.events.HTTPStatusEvent")]
-
-    /**
-     *  Dispatched when an input/output error occurs.
-     *  @see flash.events.IOErrorEvent
-     *
-     *  @eventType flash.events.IOErrorEvent.IO_ERROR
+    public function get bytesLoaded():Number
+    {
+        return _bytesLoaded;
+    }
+
+    //----------------------------------
+    //  bytesTotal
+    //----------------------------------
+
+    private var _bytesTotal:Number = NaN;
+
+    /**
+     *  The total image data in bytes loaded or pending load.
+     *  Only relevant for images loaded by request URL.
+     *
+     *  @default NaN
      *
      *  @langversion 3.0
      *  @playerversion Flash 10
      *  @playerversion AIR 2.0
      *  @productversion Flex 4.5
      */
-    [Event(name="ioError", type="flash.events.IOErrorEvent")]
-
-    /**
-     *  Dispatched when content is loading.
-     *
-     *
Note:
-     *  The progress event is not guaranteed to be dispatched.
-     *  The complete event may be received, without any
-     *  progress events being dispatched.
-     *  This can happen when the loaded content is a local file.

-     *
-     *  @eventType flash.events.ProgressEvent.PROGRESS
+    public function get bytesTotal():Number
+    {
+        return _bytesTotal;
+    }
+
+    //----------------------------------
+    //  clearOnLoad
+    //----------------------------------
+
+    private var _clearOnLoad:Boolean = true;
+
+    /**
+     *  Denotes whether or not to clear previous
+     *  image content prior to loading new content.
+     *
+     *  @default true
      *
      *  @langversion 3.0
      *  @playerversion Flash 10
      *  @playerversion AIR 2.0
      *  @productversion Flex 4.5
      */
-    [Event(name="progress", type="flash.events.ProgressEvent")]
-
-    /**
-     *  Dispatched when content loading is complete.  Unlike the
-     *  complete event, this event is dispatched for
-     *  all source types.
-     *
-     *
Note that for content loaded via Loader, both
-     *  ready and complete events
-     *  are dispatched.
  For other source types such as
-     *  embeds, only ready is dispatched.
+    public function get clearOnLoad():Boolean
+    {
+        return _clearOnLoad;
+    }
+
+    /**
+     *  @private
+     */
+    public function set clearOnLoad(value:Boolean):void
+    {
+        _clearOnLoad = value;
+    }
+
+    //----------------------------------
+    //  contentLoaderGrouping
+    //----------------------------------
+
+    private var _contentLoaderGrouping:String;
+
+    /**
+     *  Optional content grouping identifier to pass to the an
+     *  associated IContentLoader instance's load() method.
+     *  This property is only considered when a valid contentLoader
+     *  is assigned.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4.5
+     */
+    public function get contentLoaderGrouping():String
+    {
+        return _contentLoaderGrouping;
+    }
+
+    /**
+     *  @private
+     */
+    public function set contentLoaderGrouping(value:String):void
+    {
+        if (value != _contentLoaderGrouping)
+        {
+            _contentLoaderGrouping = value;
+            invalidateProperties();
+        }
+    }
+
+    //----------------------------------
+    //  contentLoader
+    //----------------------------------
+
+    private var _contentLoader:IContentLoader;
+    private var contentLoaderInvalid:Boolean;
+
+    /**
+     *  Optional custom image loader (e.g. image cache or queue) to
+     *  associate with content loader client.
+     *
+     *  @default null
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4.5
+     */
+    public function get contentLoader():IContentLoader
+    {
+        return _contentLoader;
+    }
+
+    /**
+     *  @private
+     */
+    public function set contentLoader(value:IContentLoader):void
+    {
+        if (value != _contentLoader)
+        {
+            _contentLoader = value;
+            contentLoaderInvalid = true;
+            invalidateProperties();
+        }
+    }
+
+    //----------------------------------
+    //  fillMode
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    protected var _fillMode:String = BitmapFillMode.SCALE;
+
+    [Inspectable(category="General", enumeration="clip,repeat,scale", defaultValue="scale")]
+
+    /**
+     *  The fillMode determines how the bitmap fills in the dimensions. If you set the value
+     *  of this property in a tag, use the string (such as "repeat"). If you set the value of
+     *  this property in ActionScript, use the constant (such as BitmapFillMode.CLIP).
+     *
+     *  When set to BitmapFillMode.CLIP ("clip"), the bitmap
+     *  ends at the edge of the region.
+     *
+     *  When set to BitmapFillMode.REPEAT ("repeat"), the bitmap
+     *  repeats to fill the region.
      *
-     *  @eventType mx.events.FlexEvent.READY
-     *
-     *  @langversion 3.0
-     *  @playerversion Flash 10
+     *  When set to BitmapFillMode.SCALE ("scale"), the bitmap
+     *  stretches to fill the region.
+     *
+     *  @default BitmapFillMode.SCALE
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function get fillMode():String
+    {
+        return _fillMode;
+    }
+
+    /**
+     *  @private
+     */
+    public function set fillMode(value:String):void
+    {
+        if (value != _fillMode)
+        {
+            _fillMode = value;
+            invalidateDisplayList();
+        }
+    }
+
+    //----------------------------------
+    //  horizontalAlign
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    private var _horizontalAlign:String = HorizontalAlign.CENTER;
+
+    [Inspectable(category="General", enumeration="left,right,center", defaultValue="center")]
+
+    /**
+     *  The horizontal alignment of the content when it does not have
+     *  a one-to-one aspect ratio and scaleMode is set to
+     *  BitmapScaleMode.LETTERBOX.
+     *
+     *
Can be one of HorizontalAlign.LEFT ("left"),
+     *  HorizontalAlign.RIGHT ("right"), or
+     *  HorizontalAlign.CENTER ("center").

+     *
+     *
This property is only applicable when fillMode is set to
+     *  to BitmapFillMode.SCALE ("scale").

+     *
+     *  @default HorizontalAlign.CENTER
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function get horizontalAlign():String
+    {
+        return _horizontalAlign;
+    }
+
+    /**
+     *  @private
+     */
+    public function set horizontalAlign(value:String):void
+    {
+        if (value == _horizontalAlign)
+            return;
+
+        _horizontalAlign = value;
+        invalidateDisplayList();
+    }
+
+    /**
+     *  @private
+     */
+    private function getHorizontalAlignValue():Number
+    {
+        if (_horizontalAlign == HorizontalAlign.LEFT)
+            return 0;
+        else if (_horizontalAlign == HorizontalAlign.RIGHT)
+            return 1;
+        else
+            return 0.5;
+    }
+
+    //----------------------------------
+    //  preliminaryHeight
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    private var _preliminaryHeight:Number = NaN;
+
+    /**
+     *  Provides an estimate to use for height when the "measured" bounds
+     *  of the image is requested by layout, but the image data has
+     *  yet to complete loading. When NaN the measured height is 0 until
+     *  the image has finished loading.
+     *
+     *  @default NaN
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4.5
+     */
+    public function get preliminaryHeight():Number
+    {
+        return _preliminaryHeight;
+    }
+
+    /**
+     *  @private
+     */
+    public function set preliminaryHeight(value:Number):void
+    {
+        if (value != _preliminaryHeight)
+        {
+            _preliminaryHeight = value;
+            invalidateSize();
+        }
+    }
+
+    //----------------------------------
+    //  preliminaryWidth
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    private var _preliminaryWidth:Number = NaN;
+
+    /**
+     *  Provides an estimate to use for width when the "measured" bounds
+     *  of the image is requested by layout, but the image data has
+     *  yet to complete loading. When NaN the measured width is 0 until
+     *  the image has finished loading.
+     *
+     *  @default NaN
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4.5
+     */
+    public function get preliminaryWidth():Number
+    {
+        return _preliminaryWidth;
+    }
+
+    /**
+     *  @private
+     */
+    public function set preliminaryWidth(value:Number):void
+    {
+        if (value != _preliminaryWidth)
+        {
+            _preliminaryWidth = value;
+            invalidateSize();
+        }
+    }
+
+    //----------------------------------
+    //  scaleMode
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    private var _scaleMode:String = BitmapScaleMode.STRETCH;
+
+    [Inspectable(category="General", enumeration="stretch,letterbox", defaultValue="stretch")]
+
+    /**
+     *  Determines how the image is scaled when fillMode is set to
+     *  BitmapFillMode.SCALE.
+     *
+     *
When set to BitmapScaleMode.STRETCH ("stretch"),
+     *  the image is stretched to fit.

+     *
+     *
When set to BitmapScaleMode.LETTERBOX ("letterbox"),
+     *  the image is scaled with respect to the original unscaled image's
+     *  aspect ratio.

+     *
+     *  @default BitmapScaleMode.STRETCH
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10.1
      *  @playerversion AIR 2.0
      *  @productversion Flex 4.5
      */
-    [Event(name="ready", type="mx.events.FlexEvent")]
-
-    /**
-     *  Dispatched when a security error occurs.
-     *  @see flash.events.SecurityErrorEvent
+    public function get scaleMode():String
+    {
+        return _scaleMode;
+    }
+
+    /**
+     *  @private
+     */
+    public function set scaleMode(value:String):void
+    {
+        if (value == _scaleMode)
+            return;
+
+        _scaleMode = value;
+        invalidateDisplayList();
+    }
+
+    //----------------------------------
+    //  smooth
+    //----------------------------------
+
+    private var _smooth:Boolean = false;
+
+    [Inspectable(category="General", enumeration="true,false", defaultValue="false")]
+
+    /**
+     *  @copy flash.display.GraphicsBitmapFill#smooth
      *
-     *  @eventType flash.events.SecurityErrorEvent.SECURITY_ERROR
-     *
-     *  @langversion 3.0
-     *  @playerversion Flash 10
-     *  @playerversion AIR 2.0
+     *  @default false
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function set smooth(value:Boolean):void
+    {
+        if (value != _smooth)
+        {
+            _smooth = value;
+            invalidateDisplayList();
+        }
+    }
+
+    /**
+     *  @private
+     */
+    public function get smooth():Boolean
+    {
+        return _smooth;
+    }
+
+    //----------------------------------
+    //  smoothingQuality
+    //----------------------------------
+
+    private var _smoothingQuality:String = BitmapSmoothingQuality.DEFAULT;
+
+    [Inspectable(category="General", enumeration="default,high", defaultValue="default")]
+
+    /**
+     *  Determines how the image is down-scaled.  When set to
+     *  BitmapSmoothingQuality.BEST, the image is resampled (if data
+     *  is from a trusted source) to achieve a higher quality result.
+     *  If set to BitmapSmoothingQuality.DEFAULT, the default stage
+     *  quality for scaled bitmap fills is used.
+     *
+     *  @default BitmapSmoothingQuality.DEFAULT
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
      *  @productversion Flex 4.5
      */
-    [Event(name="securityError", type="flash.events.SecurityErrorEvent")]
-
-    /**
-     *  A BitmapImage element defines a rectangular region in its parent element's
-     *  coordinate space, filled with bitmap data drawn from a source file or
-     *  source URL.
-     *
-     *  @includeExample examples/BitmapImageExample.mxml
-     *
-     *  @langversion 3.0
-     *  @playerversion Flash 10
-     *  @playerversion AIR 2.0
-     *  @productversion Flex 4.0
-     */
-    public class BitmapImage extends GraphicElement
-    {
-        include "../core/Version.as";
-
-        //--------------------------------------------------------------------------
-        //
-        //  Constructor
-        //
-        //--------------------------------------------------------------------------
-
-        /**
-         *  Constructor.
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10
-         *  @playerversion AIR 1.5
-         *  @productversion Flex 4
-         */
-        public function BitmapImage()
-        {
-            super();
-
-            // Typically, this should not be mirrored.
-            layoutDirection = "ltr";
-        }
-
-        //--------------------------------------------------------------------------
-        //
-        //  Properties
-        //
-        //--------------------------------------------------------------------------
-
-        private var _scaleGridBottom:Number;
-        private var _scaleGridLeft:Number;
-        private var _scaleGridRight:Number;
-        private var _scaleGridTop:Number;
-        private var bitmapDataCreated:Boolean;
-        private static var matrix:Matrix = new Matrix();
-        private var cachedSourceGrid:Array;
-        private var cachedDestGrid:Array;
-        private var imageWidth:Number = NaN;
-        private var imageHeight:Number = NaN;
-        private var loadedContent:DisplayObject;
-        private var loadingContent:Object;
-        private var previousUnscaledWidth:Number;
-        private var previousUnscaledHeight:Number;
-        private var sourceInvalid:Boolean;
-        private var loadFailed:Boolean;
-
-        //----------------------------------
-        //  bitmapData
-        //----------------------------------
-
-        private var _bitmapData:BitmapData;
-
-        /**
-         *  Returns a copy of the BitmapData object representing
-         *  the currently loaded image content (unscaled).  This property
-         *  is null for untrusted cross domain content.
-         *
-         *  @default null
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10
-         *  @playerversion AIR 2.0
-         *  @productversion Flex 4.5
-         */
-        public function get bitmapData():BitmapData
-        {
-            return _bitmapData ? _bitmapData.clone() : _bitmapData;
-        }
-
-        //----------------------------------
-        //  bytesLoaded
-        //----------------------------------
-
-        private var _bytesLoaded:Number = NaN;
-
-        /**
-         *  The number of bytes of the image already loaded.
-         *  Only relevant for images loaded by request URL.
-         *
-         *  @default NaN
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10
-         *  @playerversion AIR 2.0
-         *  @productversion Flex 4.5
-         */
-        public function get bytesLoaded():Number
-        {
-            return _bytesLoaded;
-        }
-
-        //----------------------------------
-        //  bytesTotal
-        //----------------------------------
-
-        private var _bytesTotal:Number = NaN;
-
-        /**
-         *  The total image data in bytes loaded or pending load.
-         *  Only relevant for images loaded by request URL.
-         *
-         *  @default NaN
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10
-         *  @playerversion AIR 2.0
-         *  @productversion Flex 4.5
-         */
-        public function get bytesTotal():Number
-        {
-            return _bytesTotal;
-        }
-
-        //----------------------------------
-        //  clearOnLoad
-        //----------------------------------
-
-        private var _clearOnLoad:Boolean = true;
-
-        /**
-         *  Denotes whether or not to clear previous
-         *  image content prior to loading new content.
-         *
-         *  @default true
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10
-         *  @playerversion AIR 2.0
-         *  @productversion Flex 4.5
-         */
-        public function get clearOnLoad():Boolean
-        {
-            return _clearOnLoad;
-        }
-
-        /**
-         *  @private
-         */
-        public function set clearOnLoad(value:Boolean):void
-        {
-            _clearOnLoad = value;
-        }
-
-        //----------------------------------
-        //  contentLoaderGrouping
-        //----------------------------------
-
-        private var _contentLoaderGrouping:String;
-
-        /**
-         *  Optional content grouping identifier to pass to the an
-         *  associated IContentLoader instance's load() method.
-         *  This property is only considered when a valid contentLoader
-         *  is assigned.
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10
-         *  @playerversion AIR 1.5
-         *  @productversion Flex 4.5
-         */
-        public function get contentLoaderGrouping():String
-        {
-            return _contentLoaderGrouping;
-        }
-
-        /**
-         *  @private
-         */
-        public function set contentLoaderGrouping(value:String):void
-        {
-            if (value != _contentLoaderGrouping)
-            {
-                _contentLoaderGrouping = value;
-                invalidateProperties();
+    public function set smoothingQuality(value:String):void
+    {
+        if (value != _smoothingQuality)
+        {
+            _smoothingQuality = value;
+            invalidateDisplayList();
+        }
+    }
+
+    /**
+     *  @private
+     */
+    public function get smoothingQuality():String
+    {
+        return _smoothingQuality;
+    }
+
+    //----------------------------------
+    //  source
+    //----------------------------------
+
+    private var _source:Object;
+
+    [Bindable("sourceChanged")]
+    [Inspectable(category="General")]
+
+    /**
+     *  The source used for the bitmap fill. The fill can render from various
+     *  graphical sources, including the following:
+     *

+     *
A Bitmap or BitmapData instance.

+     *
A class representing a subclass of DisplayObject. The BitmapFill
+     *       instantiates the class and creates a bitmap rendering of it.

+     *
An instance of a DisplayObject. The BitmapFill copies it into a
+     *       Bitmap for filling.

+     *
The name of an external image file.

+     *

+     *
+     *
If you use an image file for the source, it can be of type PNG, GIF,
+     *  or JPG.

+     *
+     *
To specify an embedded image source, you can use the @Embed directive,
+     *  as the following example shows:
+     *

+     *  source="@Embed('<i>image_location</i>')"
+     *

+     *

+     *
+     *
The image location can be specified via a URL, URLRequest, or file
+     *  reference. If it is a file reference, its location is relative to the
+     *  location of the file that is being compiled.

+     *
+     *
The BitmapImage class is designed to work with embedded images or
+     *  images that are loaded at run time.

+     *
+     *
If the source is a Bitmap or BitmapData instance or is an external
+     *  image file, it is the responsibility of the caller to dispose of the
+     *  source once it is no longer needed. If ImageLoader created the BitmapData
+     *  instance, then it will dispose of the BitmapData once the source has
+     *  changed.

+     *
+     *  @see flash.display.Bitmap
+     *  @see flash.display.BitmapData
+     *  @see mx.graphics.BitmapFill
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function get source():Object
+    {
+        return _source;
+    }
+
+    /**
+     *  @private
+     */
+    public function set source(value:Object):void
+    {
+        if (value != _source)
+        {
+            // Remove listeners from any previous load instance and clear
+            // our reference to any existing load-event dispatcher. This ensures
+            // for example that we do not receive further load related events
+            // our previous content before we can consider the new source.
+            clearLoadingContent();
+
+            // Remove any event listeners from previous source.
+            removeAddedToStageHandler(_source);
+
+            _source = value;
+            sourceInvalid = true;
+            loadFailed = false;
+            invalidateProperties();
+            dispatchEvent(new Event("sourceChanged"));
+        }
+    }
+
+    //----------------------------------
+    //  sourceHeight
+    //----------------------------------
+
+    /**
+     *  Provides the unscaled height of the original image data.
+     *
+     *  @default NaN
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4.5
+     */
+    public function get sourceHeight():Number
+    {
+        return imageHeight;
+    }
+
+    //----------------------------------
+    //  sourceWidth
+    //----------------------------------
+
+    /**
+     *  Provides the unscaled width of the original image data.
+     *
+     *  @default NaN
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4.5
+     */
+    public function get sourceWidth():Number
+    {
+        return imageWidth;
+    }
+
+    //----------------------------------
+    //  trustedSource
+    //----------------------------------
+
+    private var _trustedSource:Boolean = true;
+
+    /**
+     *  A read-only flag denoting whether the currently loaded
+     *  content is considered loaded form a source whose security
+     *  policy allows for cross domain image access.  When false,
+     *  advanced bitmap operations such as high quality scaling,
+     *  tiling, etc. are not permitted.  This flag is set once an
+     *  image has been fully loaded.
+     *
+     *  @default true
+     *
+     *  @langversion 4.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4.5
+     */
+    public function get trustedSource():Boolean
+    {
+        return _trustedSource;
+    }
+
+    //----------------------------------
+    //  verticalAlign
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    private var _verticalAlign:String = VerticalAlign.MIDDLE;
+
+    [Inspectable(category="General", enumeration="top,bottom,middle", defaultValue="middle")]
+
+    /**
+     *  The vertical alignment of the content when it does not have
+     *  a one-to-one aspect ratio and scaleMode is set to
+     *  BitmapScaleMode.LETTERBOX.
+     *
+     *
Can be one of VerticalAlign.TOP ("top"),
+     *  VerticalAlign.BOTTOM ("bottom"), or
+     *  VerticalAlign.MIDDLE ("middle").

+     *
+     *
This property is only applicable when scaleMode is set to
+     *  to BitmapFillMode.SCALE ("scale").

+     *
+     *  @default VerticalAlign.MIDDLE
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4.5
+     */
+    public function get verticalAlign():String
+    {
+        return _verticalAlign;
+    }
+
+    /**
+     *  @private
+     */
+    public function set verticalAlign(value:String):void
+    {
+        if (value == _verticalAlign)
+            return;
+
+        _verticalAlign = value;
+        invalidateDisplayList();
+    }
+
+    /**
+     *  @private
+     */
+    private function getVerticalAlignValue():Number
+    {
+        if (_verticalAlign == VerticalAlign.TOP)
+            return 0;
+        else if (_verticalAlign == VerticalAlign.BOTTOM)
+            return 1;
+        else
+            return 0.5;
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  GraphicElement Overrides
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @inheritDoc
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    override protected function commitProperties():void
+    {
+        validateSource();
+        super.commitProperties();
+    }
+
+    /**
+     *  @inheritDoc
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    override protected function measure():void
+    {
+        if (loadedContent)
+        {
+            // Return size of our loaded image content.
+            measuredWidth = imageWidth;
+            measuredHeight = imageHeight;
+        }
+        else if (_bitmapData)
+        {
+            // Return size of our bitmap data.
+            measuredWidth = _bitmapData.width;
+            measuredHeight = _bitmapData.height;
+        }
+        else
+        {
+            // If we are loading new content we keep the old measured width/height to avoid
+            // sizing to 0,0 for a frame unnecessarily. Otherwise we fall back to 0 unless
+            // a preliminaryWidth/Height is set.
+            var usePreviousSize:Boolean = !(_source == null || _source == "" || loadFailed);
+            var previousWidth:Number = usePreviousSize ? measuredWidth : 0;
+            var previousHeight:Number = usePreviousSize ? measuredHeight : 0;
+
+            measuredWidth = !isNaN(_preliminaryWidth) && (previousWidth == 0) ?
+                _preliminaryWidth : previousWidth;
+            measuredHeight = !isNaN(_preliminaryHeight) && (previousHeight == 0) ?
+                _preliminaryHeight : previousHeight;
+
+            if (parent)
+                parent.dispatchEvent(new FlexEvent(FlexEvent.MEASURED_SIZE_PRELIMINARY, true, true));
+
+            return;
+        }
+
+        // Consider aspectRatio
+        if (maintainAspectRatio && measuredWidth > 0 && measuredHeight > 0)
+        {
+            if(!isNaN(explicitWidth) && isNaN(explicitHeight) &&
+                isNaN(percentHeight))
+            {
+                measuredHeight = explicitWidth/measuredWidth * measuredHeight;
             }
-        }
-
-        //----------------------------------
-        //  contentLoader
-        //----------------------------------
-
-        private var _contentLoader:IContentLoader;
-        private var contentLoaderInvalid:Boolean;
-
-        /**
-         *  Optional custom image loader (e.g. image cache or queue) to
-         *  associate with content loader client.
-         *
-         *  @default null
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10
-         *  @playerversion AIR 1.5
-         *  @productversion Flex 4.5
-         */
-        public function get contentLoader():IContentLoader
-        {
-            return _contentLoader;
-        }
-
-        /**
-         *  @private
-         */
-        public function set contentLoader(value:IContentLoader):void
-        {
-            if (value != _contentLoader)
-            {
-                _contentLoader = value;
-                contentLoaderInvalid = true;
-                invalidateProperties();
+            else if (!isNaN(explicitHeight) && isNaN(explicitWidth) &&
+                isNaN(percentWidth))
+            {
+                measuredWidth = explicitHeight/measuredHeight * measuredWidth;
             }
-        }
-
-        //----------------------------------
-        //  fillMode
-        //----------------------------------
-
-        /**
-         *  @private
-         */
-        protected var _fillMode:String = BitmapFillMode.SCALE;
-
-        [Inspectable(category="General", enumeration="clip,repeat,scale", defaultValue="scale")]
-
-        /**
-         *  The fillMode determines how the bitmap fills in the dimensions. If you set the value
-         *  of this property in a tag, use the string (such as "repeat"). If you set the value of
-         *  this property in ActionScript, use the constant (such as BitmapFillMode.CLIP).
-         *
-         *  When set to BitmapFillMode.CLIP ("clip"), the bitmap
-         *  ends at the edge of the region.
-         *
-         *  When set to BitmapFillMode.REPEAT ("repeat"), the bitmap
-         *  repeats to fill the region.
-         *
-         *  When set to BitmapFillMode.SCALE ("scale"), the bitmap
-         *  stretches to fill the region.
-         *
-         *  @default BitmapFillMode.SCALE
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10
-         *  @playerversion AIR 1.5
-         *  @productversion Flex 4
-         */
-        public function get fillMode():String
-        {
-            return _fillMode;
-        }
-
-        /**
-         *  @private
-         */
-        public function set fillMode(value:String):void
-        {
-            if (value != _fillMode)
-            {
-                _fillMode = value;
-                invalidateDisplayList();
+            else if (!isNaN(percentWidth) && isNaN(explicitHeight) &&
+                isNaN(percentHeight) && width > 0)
+            {
+                measuredHeight = width/measuredWidth * measuredHeight;
             }
-        }
-
-        //----------------------------------
-        //  horizontalAlign
-        //----------------------------------
-
-        /**
-         *  @private
-         */
-        private var _horizontalAlign:String = HorizontalAlign.CENTER;
-
-        [Inspectable(category="General", enumeration="left,right,center", defaultValue="center")]
-
-        /**
-         *  The horizontal alignment of the content when it does not have
-         *  a one-to-one aspect ratio and scaleMode is set to
-         *  BitmapScaleMode.LETTERBOX.
-         *
-         *
Can be one of HorizontalAlign.LEFT ("left"),
-         *  HorizontalAlign.RIGHT ("right"), or
-         *  HorizontalAlign.CENTER ("center").

-         *
-         *
This property is only applicable when fillMode is set to
-         *  to BitmapFillMode.SCALE ("scale").

-         *
-         *  @default HorizontalAlign.CENTER
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10
-         *  @playerversion AIR 1.5
-         *  @productversion Flex 4
-         */
-        public function get horizontalAlign():String
-        {
-            return _horizontalAlign;
-        }
-
-        /**
-         *  @private
-         */
-        public function set horizontalAlign(value:String):void
-        {
-            if (value == _horizontalAlign)
-                return;
-
-            _horizontalAlign = value;
-            invalidateDisplayList();
-        }
-
-        /**
-         *  @private
-         */
-        private function getHorizontalAlignValue():Number
-        {
-            if (_horizontalAlign == HorizontalAlign.LEFT)
-                return 0;
-            else if (_horizontalAlign == HorizontalAlign.RIGHT)
-                return 1;
-            else
-                return 0.5;
-        }
-
-        //----------------------------------
-        //  preliminaryHeight
-        //----------------------------------
-
-        /**
-         *  @private
-         */
-        private var _preliminaryHeight:Number = NaN;
-
-        /**
-         *  Provides an estimate to use for height when the "measured" bounds
-         *  of the image is requested by layout, but the image data has
-         *  yet to complete loading. When NaN the measured height is 0 until
-         *  the image has finished loading.
-         *
-         *  @default NaN
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10
-         *  @playerversion AIR 1.5
-         *  @productversion Flex 4.5
-         */
-        public function get preliminaryHeight():Number
-        {
-            return _preliminaryHeight;
-        }
-
-        /**
-         *  @private
-         */
-        public function set preliminaryHeight(value:Number):void
-        {
-            if (value != _preliminaryHeight)
-            {
-                _preliminaryHeight = value;
-                invalidateSize();
+            else if (!isNaN(percentHeight) && isNaN(explicitWidth) &&
+                isNaN(percentWidth) && height > 0)
+            {
+                measuredWidth = height/measuredHeight * measuredWidth;
             }
         }
-
-        //----------------------------------
-        //  preliminaryWidth
-        //----------------------------------
-
-        /**
-         *  @private
-         */
-        private var _preliminaryWidth:Number = NaN;
-
-        /**
-         *  Provides an estimate to use for width when the "measured" bounds
-         *  of the image is requested by layout, but the image data has
-         *  yet to complete loading. When NaN the measured width is 0 until
-         *  the image has finished loading.
-         *
-         *  @default NaN
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10
-         *  @playerversion AIR 1.5
-         *  @productversion Flex 4.5
-         */
-        public function get preliminaryWidth():Number
-        {
-            return _preliminaryWidth;
-        }
-
-        /**
-         *  @private
-         */
-        public function set preliminaryWidth(value:Number):void
-        {
-            if (value != _preliminaryWidth)
-            {
-                _preliminaryWidth = value;
-                invalidateSize();
-            }
-        }
-
-        //----------------------------------
-        //  scaleMode
-        //----------------------------------
-
-        /**
-         *  @private
-         */
-        private var _scaleMode:String = BitmapScaleMode.STRETCH;
-
-        [Inspectable(category="General", enumeration="stretch,letterbox", defaultValue="stretch")]
-
-        /**
-         *  Determines how the image is scaled when fillMode is set to
-         *  BitmapFillMode.SCALE.
-         *
-         *
When set to BitmapScaleMode.STRETCH ("stretch"),
-         *  the image is stretched to fit.

-         *
-         *
When set to BitmapScaleMode.LETTERBOX ("letterbox"),
-         *  the image is scaled with respect to the original unscaled image's
-         *  aspect ratio.

-         *
-         *  @default BitmapScaleMode.STRETCH
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10.1
-         *  @playerversion AIR 2.0
-         *  @productversion Flex 4.5
-         */
-        public function get scaleMode():String
-        {
-            return _scaleMode;
-        }
-
-        /**
-         *  @private
-         */
-        public function set scaleMode(value:String):void
-        {
-            if (value == _scaleMode)
-                return;
-
-            _scaleMode = value;
-            invalidateDisplayList();
-        }
-
-        //----------------------------------
-        //  smooth
-        //----------------------------------
-
-        private var _smooth:Boolean = false;
-
-        [Inspectable(category="General", enumeration="true,false", defaultValue="false")]
-
-        /**
-         *  @copy flash.display.GraphicsBitmapFill#smooth
-         *
-         *  @default false
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10
-         *  @playerversion AIR 1.5
-         *  @productversion Flex 4
-         */
-        public function set smooth(value:Boolean):void
-        {
-            if (value != _smooth)
-            {
-                _smooth = value;
-                invalidateDisplayList();
-            }
-        }
-
-        /**
-         *  @private
-         */
-        public function get smooth():Boolean
-        {
-            return _smooth;
-        }
-
-        //----------------------------------
-        //  smoothingQuality
-        //----------------------------------
-
-        private var _smoothingQuality:String = BitmapSmoothingQuality.DEFAULT;
-
-        [Inspectable(category="General", enumeration="default,high", defaultValue="default")]
-
-        /**
-         *  Determines how the image is down-scaled.  When set to
-         *  BitmapSmoothingQuality.BEST, the image is resampled (if data
-         *  is from a trusted source) to achieve a higher quality result.
-         *  If set to BitmapSmoothingQuality.DEFAULT, the default stage
-         *  quality for scaled bitmap fills is used.
-         *
-         *  @default BitmapSmoothingQuality.DEFAULT
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10
-         *  @playerversion AIR 1.5
-         *  @productversion Flex 4.5
-         */
-        public function set smoothingQuality(value:String):void
-        {
-            if (value != _smoothingQuality)
-            {
-                _smoothingQuality = value;
-                invalidateDisplayList();
-            }
-        }
-
-        /**
-         *  @private
-         */
-        public function get smoothingQuality():String
-        {
-            return _smoothingQuality;
-        }
-
-        //----------------------------------
-        //  source
-        //----------------------------------
-
-        private var _source:Object;
-
-        [Bindable("sourceChanged")]
-        [Inspectable(category="General")]
-
-        /**
-         *  The source used for the bitmap fill. The fill can render from various
-         *  graphical sources, including the following:
-         *

-         *
A Bitmap or BitmapData instance.

-         *
A class representing a subclass of DisplayObject. The BitmapFill
-         *       instantiates the class and creates a bitmap rendering of it.

-         *
An instance of a DisplayObject. The BitmapFill copies it into a
-         *       Bitmap for filling.

-         *
The name of an external image file.

-         *

-         *
-         *
If you use an image file for the source, it can be of type PNG, GIF,
-         *  or JPG.

-         *
-         *
To specify an embedded image source, you can use the @Embed directive,
-         *  as the following example shows:
-         *

-         *  source="@Embed('<i>image_location</i>')"
-         *

-         *

-         *
-         *
The image location can be specified via a URL, URLRequest, or file
-         *  reference. If it is a file reference, its location is relative to the
-         *  location of the file that is being compiled.

-         *
-         *
The BitmapImage class is designed to work with embedded images or
-         *  images that are loaded at run time.

-         *
-         *
If the source is a Bitmap or BitmapData instance or is an external
-         *  image file, it is the responsibility of the caller to dispose of the
-         *  source once it is no longer needed. If ImageLoader created the BitmapData
-         *  instance, then it will dispose of the BitmapData once the source has
-         *  changed.

-         *
-         *  @see flash.display.Bitmap
-         *  @see flash.display.BitmapData
-         *  @see mx.graphics.BitmapFill
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10
-         *  @playerversion AIR 1.5
-         *  @productversion Flex 4
-         */
-        public function get source():Object
-        {
-            return _source;
-        }
-
-        /**
-         *  @private
-         */
-        public function set source(value:Object):void
-        {
-            if (value != _source)
-            {
-                // Remove listeners from any previous load instance and clear
-                // our reference to any existing load-event dispatcher. This ensures
-                // for example that we do not receive further load related events
-                // our previous content before we can consider the new source.
-                clearLoadingContent();
+    }
+
+    /**
+     *  @inheritDoc
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    override protected function updateDisplayList(unscaledWidth:Number,
+                                                  unscaledHeight:Number):void
+    {
+        super.updateDisplayList(unscaledWidth, unscaledHeight);
+
+        var adjustedHeight:Number = unscaledHeight;
+        var adjustedWidth:Number = unscaledWidth;
+
+        // Consider aspectRatio
+        if (maintainAspectRatio)
+        {
+            var aspectRatio:Number = unscaledWidth/unscaledHeight;
+            var imageAspectRatio:Number = imageWidth/imageHeight;
+            if (!isNaN(imageAspectRatio))
+            {
+                if (imageAspectRatio > aspectRatio)
+                    adjustedHeight = unscaledWidth / imageAspectRatio;
+                else
+                    adjustedWidth = unscaledHeight * imageAspectRatio;

-                // Remove any event listeners from previous source.
-                removeAddedToStageHandler(_source);
-
-                _source = value;
-                sourceInvalid = true;
-                loadFailed = false;
-                invalidateProperties();
-                dispatchEvent(new Event("sourceChanged"));
-            }
-        }
-
-        //----------------------------------
-        //  sourceHeight
-        //----------------------------------
-
-        /**
-         *  Provides the unscaled height of the original image data.
-         *
-         *  @default NaN
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10
-         *  @playerversion AIR 1.5
-         *  @productversion Flex 4.5
-         */
-        public function get sourceHeight():Number
-        {
-            return imageHeight;
-        }
-
-        //----------------------------------
-        //  sourceWidth
-        //----------------------------------
-
-        /**
-         *  Provides the unscaled width of the original image data.
-         *
-         *  @default NaN
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10
-         *  @playerversion AIR 1.5
-         *  @productversion Flex 4.5
-         */
-        public function get sourceWidth():Number
-        {
-            return imageWidth;
-        }
-
-        //----------------------------------
-        //  trustedSource
-        //----------------------------------
-
-        private var _trustedSource:Boolean = true;
-
-        /**
-         *  A read-only flag denoting whether the currently loaded
-         *  content is considered loaded form a source whose security
-         *  policy allows for cross domain image access.  When false,
-         *  advanced bitmap operations such as high quality scaling,
-         *  tiling, etc. are not permitted.  This flag is set once an
-         *  image has been fully loaded.
-         *
-         *  @default true
-         *
-         *  @langversion 4.0
-         *  @playerversion Flash 9
-         *  @playerversion AIR 1.5
-         *  @productversion Flex 4.5
-         */
-        public function get trustedSource():Boolean
-        {
-            return _trustedSource;
-        }
-
-        //----------------------------------
-        //  verticalAlign
-        //----------------------------------
-
-        /**
-         *  @private
-         */
-        private var _verticalAlign:String = VerticalAlign.MIDDLE;
-
-        [Inspectable(category="General", enumeration="top,bottom,middle", defaultValue="middle")]
-
-        /**
-         *  The vertical alignment of the content when it does not have
-         *  a one-to-one aspect ratio and scaleMode is set to
-         *  BitmapScaleMode.LETTERBOX.
-         *
-         *
Can be one of VerticalAlign.TOP ("top"),
-         *  VerticalAlign.BOTTOM ("bottom"), or
-         *  VerticalAlign.MIDDLE ("middle").

-         *
-         *
This property is only applicable when scaleMode is set to
-         *  to BitmapFillMode.SCALE ("scale").

-         *
-         *  @default VerticalAlign.MIDDLE
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10
-         *  @playerversion AIR 1.5
-         *  @productversion Flex 4.5
-         */
-        public function get verticalAlign():String
-        {
-            return _verticalAlign;
-        }
-
-        /**
-         *  @private
-         */
-        public function set verticalAlign(value:String):void
-        {
-            if (value == _verticalAlign)
-                return;
-
-            _verticalAlign = value;
-            invalidateDisplayList();
-        }
-
-        /**
-         *  @private
-         */
-        private function getVerticalAlignValue():Number
-        {
-            if (_verticalAlign == VerticalAlign.TOP)
-                return 0;
-            else if (_verticalAlign == VerticalAlign.BOTTOM)
-                return 1;
-            else
-                return 0.5;
-        }
-
-        //--------------------------------------------------------------------------
-        //
-        //  GraphicElement Overrides
-        //
-        //--------------------------------------------------------------------------
-
-        /**
-         *  @inheritDoc
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10
-         *  @playerversion AIR 1.5
-         *  @productversion Flex 4
-         */
-        override protected function commitProperties():void
-        {
-            validateSource();
-            super.commitProperties();
-        }
-
-        /**
-         *  @inheritDoc
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10
-         *  @playerversion AIR 1.5
-         *  @productversion Flex 4
-         */
-        override protected function measure():void
-        {
-            if (loadedContent)
-            {
-                // Return size of our loaded image content.
-                measuredWidth = imageWidth;
-                measuredHeight = imageHeight;
-            }
-            else if (_bitmapData)
-            {
-                // Return size of our bitmap data.
-                measuredWidth = _bitmapData.width;
-                measuredHeight = _bitmapData.height;
-            }
-            else
-            {
-                // If we are loading new content we keep the old measured width/height to avoid
-                // sizing to 0,0 for a frame unnecessarily. Otherwise we fall back to 0 unless
-                // a preliminaryWidth/Height is set.
-                var usePreviousSize:Boolean = !(_source == null || _source == "" || loadFailed);
-                var previousWidth:Number = usePreviousSize ? measuredWidth : 0;
-                var previousHeight:Number = usePreviousSize ? measuredHeight : 0;
-
-                measuredWidth = !isNaN(_preliminaryWidth) && (previousWidth == 0) ?
-                    _preliminaryWidth : previousWidth;
-                measuredHeight = !isNaN(_preliminaryHeight) && (previousHeight == 0) ?
-                    _preliminaryHeight : previousHeight;
-
-                if (parent)
-                    parent.dispatchEvent(new FlexEvent(FlexEvent.MEASURED_SIZE_PRELIMINARY, true, true));
-
-                return;
-            }
-
-            // Consider aspectRatio
-            if (maintainAspectRatio && measuredWidth > 0 && measuredHeight > 0)
-            {
-                if(!isNaN(explicitWidth) && isNaN(explicitHeight) &&
-                    isNaN(percentHeight))
+                if ((!isNaN(percentWidth) && isNaN(percentHeight) && isNaN(explicitHeight)) ||
+                    (!isNaN(percentHeight) && isNaN(percentWidth) && isNaN(explicitWidth)))
                 {
-                    measuredHeight = explicitWidth/measuredWidth * measuredHeight;
-                }
-                else if (!isNaN(explicitHeight) && isNaN(explicitWidth) &&
-                    isNaN(percentWidth))
-                {
-                    measuredWidth = explicitHeight/measuredHeight * measuredWidth;
-                }
-                else if (!isNaN(percentWidth) && isNaN(explicitHeight) &&
-                    isNaN(percentHeight) && width > 0)
-                {
-                    measuredHeight = width/measuredWidth * measuredHeight;
-                }
-                else if (!isNaN(percentHeight) && isNaN(explicitWidth) &&
-                    isNaN(percentWidth) && height > 0)
-                {
-                    measuredWidth = height/measuredHeight * measuredWidth;
+                    if (aspectRatio != imageAspectRatio)
+                    {
+                        invalidateSize();
+                        return;
+                    }
                 }
             }
-        }
-
-        /**
-         *  @inheritDoc
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10
-         *  @playerversion AIR 1.5
-         *  @productversion Flex 4
-         */
-        override protected function updateDisplayList(unscaledWidth:Number,
-                                                      unscaledHeight:Number):void
-        {
-            super.updateDisplayList(unscaledWidth, unscaledHeight);
-
-            var adjustedHeight:Number = unscaledHeight;
-            var adjustedWidth:Number = unscaledWidth;
-
-            // Consider aspectRatio
-            if (maintainAspectRatio)
-            {
-                var aspectRatio:Number = unscaledWidth/unscaledHeight;
-                var imageAspectRatio:Number = imageWidth/imageHeight;
-                if (!isNaN(imageAspectRatio))
-                {
-                    if (imageAspectRatio > aspectRatio)
-                        adjustedHeight = unscaledWidth / imageAspectRatio;
-                    else
-                        adjustedWidth = unscaledHeight * imageAspectRatio;
-
-                    if ((!isNaN(percentWidth) && isNaN(percentHeight) && isNaN(explicitHeight)) ||
-                        (!isNaN(percentHeight) && isNaN(percentWidth) && isNaN(explicitWidth)))
-                    {
-                        if (aspectRatio != imageAspectRatio)
-                        {
-                            invalidateSize();
-                            return;
-                        }
-                    }
-                }
-            }
-
-            if (!_bitmapData || !drawnDisplayObject || !(drawnDisplayObject is Sprite))
-            {
-                if (loadedContent)
+        }
+
+        if (!_bitmapData || !drawnDisplayObject || !(drawnDisplayObject is Sprite))
+        {
+            if (loadedContent)
+            {
+                // We are hosting a display object so let's scale, align, and clip
+                // as necessary.
+
+                if (_fillMode == BitmapFillMode.SCALE)
                 {
-                    // We are hosting a display object so let's scale, align, and clip
-                    // as necessary.
-
-                    if (_fillMode == BitmapFillMode.SCALE)
-                    {
-                        loadedContent.width = adjustedWidth;
-                        loadedContent.height = adjustedHeight;
-                    }
-
-                    loadedContent.y = loadedContent.x = 0;
-
-                    // Align our loaded content as necessary if our width
-                    // and/or height is larger than our content height.
-                    if (maintainAspectRatio || _fillMode == BitmapFillMode.CLIP)
-                    {
-                        var contentWidth:Number = (_fillMode == BitmapFillMode.CLIP) ?
-                            imageWidth : adjustedWidth;
-                        var contentHeight:Number = (_fillMode == BitmapFillMode.CLIP) ?
-                            imageHeight : adjustedHeight;
-
-                        if (unscaledHeight > contentHeight)
-                            loadedContent.y = Math.floor((unscaledHeight - contentHeight)
-                                * getVerticalAlignValue());
-
-                        if (unscaledWidth > contentWidth)
-                            loadedContent.x = Math.floor((unscaledWidth - contentWidth)
-                                * getHorizontalAlignValue());
-                    }
-
-                    // Setup clip rect if appropriate.
-                    loadedContent.scrollRect = (_fillMode == BitmapFillMode.CLIP) ?
-                        new Rectangle(0, 0, unscaledWidth, unscaledHeight) : null;
-
-                }
-                return;
-            }
-
-            // The base GraphicElement class has cleared the graphics for us.
-            var g:Graphics = Sprite(drawnDisplayObject).graphics;
-
-            g.lineStyle();
-            var repeatBitmap:Boolean = false;
-            var fillScaleX:Number = 1;
-            var fillScaleY:Number = 1;
-            var roundedDrawX:Number = Math.round(drawX);
-            var roundedDrawY:Number = Math.round(drawY);
-            var fillWidth:Number = adjustedWidth;
-            var fillHeight:Number = adjustedHeight;
-
-            switch(_fillMode)
-            {
-                case BitmapFillMode.REPEAT:
-                    if (_bitmapData)
-                    {
-                        repeatBitmap = true;
-                    }
-                    break;
-
-                case BitmapFillMode.SCALE:
-                    if (_bitmapData)
-                    {
-                        fillScaleX = adjustedWidth / _bitmapData.width;
-                        fillScaleY = adjustedHeight / _bitmapData.height;
-                    }
-                    break;
-
-                case BitmapFillMode.CLIP:
-                    if (_bitmapData)
-                    {
-                        fillWidth = Math.min(adjustedWidth, _bitmapData.width);
-                        fillHeight = Math.min(adjustedHeight, _bitmapData.height);
-                    }
-                    break;
-            }
-
-            // If no scaleGrid is defined or if fillMode != SCALE, just draw
-            // the entire rect
-            if (_fillMode != BitmapFillMode.SCALE ||
-                isNaN(_scaleGridTop) ||
-                isNaN(_scaleGridBottom) ||
-                isNaN(_scaleGridLeft) ||
-                isNaN(_scaleGridRight))
-            {
-                var sampledScale:Boolean = _smooth &&
-                    (_smoothingQuality == BitmapSmoothingQuality.HIGH) &&
-                    (_fillMode == BitmapFillMode.SCALE);
-
-                var b:BitmapData = sampledScale ? resample(_bitmapData, fillWidth, fillHeight) : _bitmapData;
-
-                if (sampledScale && _fillMode == BitmapFillMode.SCALE)
-                {
-                    fillScaleX = adjustedWidth / b.width;
-                    fillScaleY = adjustedHeight / b.height;
+                    loadedContent.width = adjustedWidth;
+                    loadedContent.height = adjustedHeight;
                 }

-                var offsetX:Number = 0;
-                var offsetY:Number = 0;
+                loadedContent.y = loadedContent.x = 0;

-                // Align our bitmap content as necessary if our width
+                // Align our loaded content as necessary if our width
                 // and/or height is larger than our content height.
                 if (maintainAspectRatio || _fillMode == BitmapFillMode.CLIP)
                 {
-                    var cHeight:Number = b.height * fillScaleX;
-                    var cWidth:Number = b.width * fillScaleY;
+                    var contentWidth:Number = (_fillMode == BitmapFillMode.CLIP) ?
+                        imageWidth : adjustedWidth;
+                    var contentHeight:Number = (_fillMode == BitmapFillMode.CLIP) ?
+                        imageHeight : adjustedHeight;

-                    if (unscaledHeight > cHeight)
-                        roundedDrawY = roundedDrawY + Math.floor((unscaledHeight - cHeight)
+                    if (unscaledHeight > contentHeight)
+                        loadedContent.y = Math.floor((unscaledHeight - contentHeight)
                             * getVerticalAlignValue());

-                    if (unscaledWidth > cWidth)
-                        roundedDrawX = roundedDrawX + Math.floor((unscaledWidth - cWidth)
+                    if (unscaledWidth > contentWidth)
+                        loadedContent.x = Math.floor((unscaledWidth - contentWidth)
                             * getHorizontalAlignValue());
+                }
+
+                // Setup clip rect if appropriate.
+                loadedContent.scrollRect = (_fillMode == BitmapFillMode.CLIP) ?
+                    new Rectangle(0, 0, unscaledWidth, unscaledHeight) : null;
+
+            }
+            return;
+        }
+
+        // The base GraphicElement class has cleared the graphics for us.
+        var g:Graphics = Sprite(drawnDisplayObject).graphics;
+
+        g.lineStyle();
+        var repeatBitmap:Boolean = false;
+        var fillScaleX:Number = 1;
+        var fillScaleY:Number = 1;
+        var roundedDrawX:Number = Math.round(drawX);
+        var roundedDrawY:Number = Math.round(drawY);
+        var fillWidth:Number = adjustedWidth;
+        var fillHeight:Number = adjustedHeight;
+
+        switch(_fillMode)
+        {
+            case BitmapFillMode.REPEAT:
+                if (_bitmapData)
+                {
+                    repeatBitmap = true;
+                }
+                break;
+
+            case BitmapFillMode.SCALE:
+                if (_bitmapData)
+                {
+                    fillScaleX = adjustedWidth / _bitmapData.width;
+                    fillScaleY = adjustedHeight / _bitmapData.height;
                 }
+                break;
+
+            case BitmapFillMode.CLIP:
+                if (_bitmapData)
+                {
+                    fillWidth = Math.min(adjustedWidth, _bitmapData.width);
+                    fillHeight = Math.min(adjustedHeight, _bitmapData.height);
+                }
+                break;
+        }
+
+        // If no scaleGrid is defined or if fillMode != SCALE, just draw
+        // the entire rect
+        if (_fillMode != BitmapFillMode.SCALE ||
+            isNaN(_scaleGridTop) ||
+            isNaN(_scaleGridBottom) ||
+            isNaN(_scaleGridLeft) ||
+            isNaN(_scaleGridRight))
+        {
+            var sampledScale:Boolean = _smooth &&
+                (_smoothingQuality == BitmapSmoothingQuality.HIGH) &&
+                (_fillMode == BitmapFillMode.SCALE);
+
+            var b:BitmapData = sampledScale ? resample(_bitmapData, fillWidth, fillHeight) : _bitmapData;
+
+            if (sampledScale && _fillMode == BitmapFillMode.SCALE)
+            {
+                fillScaleX = adjustedWidth / b.width;
+                fillScaleY = adjustedHeight / b.height;
+            }
+
+            var offsetX:Number = 0;
+            var offsetY:Number = 0;
+
+            // Align our bitmap content as necessary if our width
+            // and/or height is larger than our content height.
+            if (maintainAspectRatio || _fillMode == BitmapFillMode.CLIP)
+            {
+                var cHeight:Number = b.height * fillScaleX;
+                var cWidth:Number = b.width * fillScaleY;

-                matrix.identity();
-                if (!(sampledScale && maintainAspectRatio))
-                    matrix.scale(fillScaleX, fillScaleY);
-                matrix.translate(roundedDrawX, roundedDrawY);
-                g.beginBitmapFill(b, matrix, repeatBitmap, _smooth);
-                g.drawRect(roundedDrawX, roundedDrawY, fillWidth, fillHeight);
-                g.endFill();
+                if (unscaledHeight > cHeight)
+                    roundedDrawY = roundedDrawY + Math.floor((unscaledHeight - cHeight)
+                        * getVerticalAlignValue());
+
+                if (unscaledWidth > cWidth)
+                    roundedDrawX = roundedDrawX + Math.floor((unscaledWidth - cWidth)
+                        * getHorizontalAlignValue());
+            }
+
+            matrix.identity();
+            if (!(sampledScale && maintainAspectRatio))
+                matrix.scale(fillScaleX, fillScaleY);
+            matrix.translate(roundedDrawX, roundedDrawY);
+            g.beginBitmapFill(b, matrix, repeatBitmap, _smooth);
+            g.drawRect(roundedDrawX, roundedDrawY, fillWidth, fillHeight);
+            g.endFill();
+        }
+        else
+        {
+            // If we have scaleGrid, we draw 9 sections, each with a different scale factor based
+            // on the grid region.
+
+            if (cachedSourceGrid == null)
+            {
+                // Generate the 16 points of the source (unscaled) grid
+                cachedSourceGrid = [];
+                cachedSourceGrid.push([new Point(0, 0), new Point(_scaleGridLeft, 0),
+                    new Point(_scaleGridRight, 0), new Point(_bitmapData.width, 0)]);
+                cachedSourceGrid.push([new Point(0, _scaleGridTop), new Point(_scaleGridLeft, _scaleGridTop),
+                    new Point(_scaleGridRight, _scaleGridTop), new Point(_bitmapData.width, _scaleGridTop)]);
+                cachedSourceGrid.push([new Point(0, _scaleGridBottom), new Point(_scaleGridLeft, _scaleGridBottom),
+                    new Point(_scaleGridRight, _scaleGridBottom), new Point(_bitmapData.width, _scaleGridBottom)]);
+                cachedSourceGrid.push([new Point(0, _bitmapData.height), new Point(_scaleGridLeft, _bitmapData.height),
+                    new Point(_scaleGridRight, _bitmapData.height), new Point(_bitmapData.width, _bitmapData.height)]);
+            }
+
+            if (cachedDestGrid == null ||
+                previousUnscaledWidth != unscaledWidth ||
+                previousUnscaledHeight != unscaledHeight)
+            {
+                // Generate teh 16 points of the destination (scaled) grid
+                var destScaleGridBottom:Number = unscaledHeight - (_bitmapData.height - _scaleGridBottom);
+                var destScaleGridRight:Number = unscaledWidth - (_bitmapData.width - _scaleGridRight);
+                cachedDestGrid = [];
+                cachedDestGrid.push([new Point(0, 0), new Point(_scaleGridLeft, 0),
+                    new Point(destScaleGridRight, 0), new Point(unscaledWidth, 0)]);
+                cachedDestGrid.push([new Point(0, _scaleGridTop), new Point(_scaleGridLeft, _scaleGridTop),
+                    new Point(destScaleGridRight, _scaleGridTop), new Point(unscaledWidth, _scaleGridTop)]);
+                cachedDestGrid.push([new Point(0, destScaleGridBottom), new Point(_scaleGridLeft, destScaleGridBottom),
+                    new Point(destScaleGridRight, destScaleGridBottom), new Point(unscaledWidth, destScaleGridBottom)]);
+                cachedDestGrid.push([new Point(0, unscaledHeight), new Point(_scaleGridLeft, unscaledHeight),
+                    new Point(destScaleGridRight, unscaledHeight), new Point(unscaledWidth, unscaledHeight)]);
+            }
+
+            var sourceSection:Rectangle = new Rectangle();
+            var destSection:Rectangle = new Rectangle();
+
+            // Iterate over the columns and rows. We draw each of the nine sections at a calculated
+            // scale and translation.
+            for (var rowIndex:int=0; rowIndex < 3; rowIndex++)
+            {
+                for (var colIndex:int = 0; colIndex < 3; colIndex++)
+                {
+                    // Create the source and destination rectangles for the current section
+                    sourceSection.topLeft = cachedSourceGrid[rowIndex][colIndex];
+                    sourceSection.bottomRight = cachedSourceGrid[rowIndex+1][colIndex+1];
+
+                    destSection.topLeft = cachedDestGrid[rowIndex][colIndex];
+                    destSection.bottomRight = cachedDestGrid[rowIndex+1][colIndex+1];
+
+                    matrix.identity();
+                    // Scale the bitmap by the ratio between the source and destination dimensions
+                    matrix.scale(destSection.width / sourceSection.width, destSection.height / sourceSection.height);
+                    // Translate based on the difference between the source and destination coordinates,
+                    // making sure to account for the new scale.
+                    matrix.translate(destSection.x - sourceSection.x * matrix.a, destSection.y - sourceSection.y * matrix.d);
+                    matrix.translate(roundedDrawX, roundedDrawY);
+
+                    // Draw the bitmap for the current section
+                    g.beginBitmapFill(_bitmapData, matrix);
+                    g.drawRect(destSection.x + roundedDrawX, destSection.y + roundedDrawY, destSection.width, destSection.height);
+                    g.endFill();
+                }
+            }
+        }
+
+        previousUnscaledWidth = unscaledWidth;
+        previousUnscaledHeight = unscaledHeight;
+    }
+
+    /**
+     *  @private
+     */
+    override protected function get needsDisplayObject():Boolean
+    {
+        // If we are hosting untrusted content the hosted loader becomes
+        // our display object.
+        return !trustedSource || super.needsDisplayObject;
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Utility function that sets the underlying bitmapData property.
+     */
+    protected function setBitmapData(bitmapData:BitmapData,
+                                     internallyCreated:Boolean = false):void
+    {
+        // Clear previous bitmapData
+        clearBitmapData();
+
+        // Reset imageWidth/Height, as we aren't
+        // loading external content so no reason to
+        // cache our existing image width and height.
+        imageWidth = imageHeight = NaN;
+
+        // Clear any currently loading content.
+        clearLoadingContent();
+
+        if (bitmapData)
+        {
+            bitmapDataCreated = internallyCreated;
+
+            _bitmapData = bitmapData;
+
+            imageWidth = bitmapData.width;
+            imageHeight = bitmapData.height;
+
+            // Flush the cached scale grid points
+            cachedSourceGrid = null;
+            cachedDestGrid = null;
+
+            // Dispatch ready event
+            dispatchEvent(new FlexEvent(FlexEvent.READY));
+        }
+
+        invalidateSize();
+        invalidateDisplayList();
+    }
+
+    /**
+     *  @private
+     *  Utility method which analyzes our source and either acquires the
+     *  associated bitmap data immediately or queues up a remote request
+     *  as necessary.
+     */
+    mx_internal function applySource():void
+    {
+        var value:Object = _source;
+        var bitmapData:BitmapData;
+        var tmpSprite:DisplayObject;
+
+        // Clear the previous scaleGrid properties
+        _scaleGridLeft = NaN;
+        _scaleGridRight = NaN;
+        _scaleGridTop = NaN;
+        _scaleGridBottom = NaN;
+        var currentBitmapCreated:Boolean = false;
+
+        // Reset byte counts and _trustedSource
+        _bytesLoaded = NaN;
+        _bytesTotal = NaN;
+        _trustedSource = true;
+
+        // We'll need to reconsider display object sharing.
+        invalidateDisplayObjectSharing();
+        invalidateDisplayList();
+
+        // Remove any previously hosted content prior to loading
+        // new content (if applicable).
+        if (_clearOnLoad)
+            removePreviousContent();
+
+        if (value is Class)
+        {
+            var cls:Class = Class(value);
+            value = new cls();
+            currentBitmapCreated = true;
+        }
+        else if (value is String || value is URLRequest)
+        {
+            loadExternal(value);
+        }
+        else if (value is ByteArray)
+        {
+            loadFromBytes(value as ByteArray);
+        }
+
+        if (value is BitmapData)
+        {
+            bitmapData = value as BitmapData;
+        }
+        else if (value is Bitmap)
+        {
+            bitmapData = value.bitmapData;
+        }
+        else if (value is DisplayObject)
+        {
+            tmpSprite = value as DisplayObject;
+
+            if ((tmpSprite.width == 0 || tmpSprite.height == 0) && !tmpSprite.stage )
+            {
+                // If our source DisplayObject has yet to be assigned a stage,
+                // and doesn't have valid bounds, it is not ready to be captured,
+                // so we defer bitmap capture until it is added to the display list.
+                tmpSprite.addEventListener(Event.ADDED_TO_STAGE, source_addedToStageHandler);
+                return;
+            }
+        }
+        else if (value == null)
+        {
+            // This will set source to null
+        }
+        else
+        {
+            // We're loading external content or we
+            // we have an unsupported source value.
+            return;
+        }
+
+        if (!bitmapData && tmpSprite)
+        {
+            // We must ensure any IInvalidating sources
+            // are properly validated before capturing.
+            if (tmpSprite is IInvalidating)
+                IInvalidating(tmpSprite).validateNow();
+
+            // Return immediately if our input source has 0 bounds else
+            // our BitmapData constructor will RTE.
+            if (tmpSprite.width == 0 || tmpSprite.height == 0)
+                return;
+
+            bitmapData = new BitmapData(tmpSprite.width, tmpSprite.height, true, 0);
+            bitmapData.draw(tmpSprite, new Matrix(), tmpSprite.transform.colorTransform);
+            currentBitmapCreated = true;
+
+            if (tmpSprite.scale9Grid)
+            {
+                _scaleGridLeft = tmpSprite.scale9Grid.left;
+                _scaleGridRight = tmpSprite.scale9Grid.right;
+                _scaleGridTop = tmpSprite.scale9Grid.top;
+                _scaleGridBottom = tmpSprite.scale9Grid.bottom;
+            }
+        }
+
+        // Remove any previously hosted content prior to assigning
+        // new bitmap data (if we haven't already previously).
+        if (!_clearOnLoad)
+            removePreviousContent();
+
+        setBitmapData(bitmapData, currentBitmapCreated);
+    }
+
+    /**
+     *  @private
+     */
+    mx_internal function loadExternal(source:Object):void
+    {
+        // Ensure we handle unicode characters properly.
+        if (source is String)
+        {
+           var url:String = source as String;
+           source = LoaderUtil.OSToPlayerURI(url, LoaderUtil.isLocal(url));
+        }
+
+        if (contentLoader)
+        {
+            // We defer our load request to the configured content loader.
+            var contentRequest:ContentRequest = contentLoader.load(source, contentLoaderGrouping);
+
+            if (contentRequest.complete)
+            {
+                // No need to attach listeners as we've received a fully complete
+                // request result.
+                contentComplete(contentRequest.content);
             }
             else
-            {
-                // If we have scaleGrid, we draw 9 sections, each with a different scale factor based
-                // on the grid region.
+            {
+                // Attach load-event listeners to our ContentRequest instance.
+                loadingContent = contentRequest;
+                attachLoadingListeners();
+            }
+        }
+        else
+        {
+            var loader:Loader = new Loader();
+            var loaderContext:LoaderContext = new LoaderContext();
+
+            // Attach load-event listeners to our LoaderInfo instance.
+            loadingContent = loader.contentLoaderInfo;
+            attachLoadingListeners();
+
+            try
+            {
+                loaderContext.checkPolicyFile = true;
+                var urlRequest:URLRequest = source is URLRequest ?
+                    source as URLRequest : new URLRequest(source as String);
+                loader.load(urlRequest, loaderContext);
+            }
+            catch (error:SecurityError)
+            {
+                handleSecurityError(error);
+            }
+        }
+    }
+
+    /**
+     *  @private
+     */
+    mx_internal function loadFromBytes(source:ByteArray):void
+    {
+        var loader:Loader = new Loader();
+        var loaderContext:LoaderContext = new LoaderContext();
+        loadingContent = loader.contentLoaderInfo;
+        attachLoadingListeners();
+
+        try
+        {
+            loader.loadBytes(source as ByteArray, loaderContext);
+        }
+        catch (error:SecurityError)
+        {
+            handleSecurityError(error);
+        }
+    }
+
+    /**
+     * @private
+     * Utility function used for higher quality image scaling. Essentially we
+     * simply step down our bitmap size by half resulting in a much higher result
+     * though taking potentially multiple passes to accomplish.
+     */
+    protected static function resample(bitmapData:BitmapData, newWidth:uint,
+                                       newHeight:uint):BitmapData
+    {
+        var finalScale:Number = Math.max(newWidth/bitmapData.width,
+            newHeight/bitmapData.height);
+
+        var finalData:BitmapData = bitmapData;
+
+        if (finalScale > 1)
+        {
+            finalData = new BitmapData(bitmapData.width * finalScale,
+                bitmapData.height * finalScale, true, 0);
+
+            finalData.draw(bitmapData, new Matrix(finalScale, 0, 0,
+                finalScale), null, null, null, true);
+
+            return finalData;
+        }
+
+        var drop:Number = .5;
+        var initialScale:Number = finalScale;
+
+        while (initialScale/drop < 1)
+            initialScale /= drop;
+
+        var w:Number = Math.floor(bitmapData.width * initialScale);
+        var h:Number = Math.floor(bitmapData.height * initialScale);
+        var bd:BitmapData = new BitmapData(w, h, bitmapData.transparent, 0);
+
+        bd.draw(finalData, new Matrix(initialScale, 0, 0, initialScale),
+            null, null, null, true);
+        finalData = bd;
+
+        for (var scale:Number = initialScale * drop;
+            Math.round(scale * 1000) >= Math.round(finalScale * 1000);
+            scale *= drop)
+        {
+            w = Math.floor(bitmapData.width * scale);
+            h = Math.floor(bitmapData.height * scale);
+            bd = new BitmapData(w, h, bitmapData.transparent, 0);
+
+            bd.draw(finalData, new Matrix(drop, 0, 0, drop), null, null, null, true);
+            finalData.dispose();
+            finalData = bd;
+        }
+
+        return finalData;
+    }
+
+    /**
+     * @private
+     * Invoked upon completion of a load request.
+     */
+    protected function contentComplete(content:Object):void
+    {
+        if (content is LoaderInfo)
+        {
+            // Clear any previous bitmap data or loader instance.
+            setBitmapData(null);
+            removePreviousContent();
+
+            var loaderInfo:LoaderInfo = content as LoaderInfo;
+
+            if (loaderInfo.childAllowsParent)
+            {
+                // For trusted content we adopt the loaded BitmapData.
+                var image:Bitmap = Bitmap(loaderInfo.content);
+                setBitmapData(image.bitmapData);
+            }
+            else
+            {
+                // For untrusted content we must host the acquired Loader
+                // instance directly as our DisplayObject.
+                displayObjectSharingMode = DisplayObjectSharingMode.OWNS_UNSHARED_OBJECT;
+                invalidateDisplayObjectSharing();

-                if (cachedSourceGrid == null)
-                {
-                    // Generate the 16 points of the source (unscaled) grid
-                    cachedSourceGrid = [];
-                    cachedSourceGrid.push([new Point(0, 0), new Point(_scaleGridLeft, 0),
-                        new Point(_scaleGridRight, 0), new Point(_bitmapData.width, 0)]);
-                    cachedSourceGrid.push([new Point(0, _scaleGridTop), new Point(_scaleGridLeft, _scaleGridTop),
-                        new Point(_scaleGridRight, _scaleGridTop), new Point(_bitmapData.width, _scaleGridTop)]);
-                    cachedSourceGrid.push([new Point(0, _scaleGridBottom), new Point(_scaleGridLeft, _scaleGridBottom),
-                        new Point(_scaleGridRight, _scaleGridBottom), new Point(_bitmapData.width, _scaleGridBottom)]);
-                    cachedSourceGrid.push([new Point(0, _bitmapData.height), new Point(_scaleGridLeft, _bitmapData.height),
-                        new Point(_scaleGridRight, _bitmapData.height), new Point(_bitmapData.width, _bitmapData.height)]);
-                }
+                // Create a content holder to use as our display object.
+                var contentHolder:Sprite = new Sprite();
+                setDisplayObject(contentHolder);
+                loadedContent = loaderInfo.loader;
+                contentHolder.addChild(loadedContent);

-                if (cachedDestGrid == null ||
-                    previousUnscaledWidth != unscaledWidth ||
-                    previousUnscaledHeight != unscaledHeight)
-                {
-                    // Generate teh 16 points of the destination (scaled) grid
-                    var destScaleGridBottom:Number = unscaledHeight - (_bitmapData.height - _scaleGridBottom);
-                    var destScaleGridRight:Number = unscaledWidth - (_bitmapData.width - _scaleGridRight);
-                    cachedDestGrid = [];
-                    cachedDestGrid.push([new Point(0, 0), new Point(_scaleGridLeft, 0),
-                        new Point(destScaleGridRight, 0), new Point(unscaledWidth, 0)]);
-                    cachedDestGrid.push([new Point(0, _scaleGridTop), new Point(_scaleGridLeft, _scaleGridTop),
-                        new Point(destScaleGridRight, _scaleGridTop), new Point(unscaledWidth, _scaleGridTop)]);
-                    cachedDestGrid.push([new Point(0, destScaleGridBottom), new Point(_scaleGridLeft, destScaleGridBottom),
-                        new Point(destScaleGridRight, destScaleGridBottom), new Point(unscaledWidth, destScaleGridBottom)]);
-                    cachedDestGrid.push([new Point(0, unscaledHeight), new Point(_scaleGridLeft, unscaledHeight),
-                        new Point(destScaleGridRight, unscaledHeight), new Point(unscaledWidth, unscaledHeight)]);
-                }
+                // Retain our source image width and height.
+                imageWidth = loaderInfo.width;
+                imageHeight = loaderInfo.height ;

-                var sourceSection:Rectangle = new Rectangle();
-                var destSection:Rectangle = new Rectangle();
+                // Update
+                invalidateSize();
+                invalidateDisplayList();

-                // Iterate over the columns and rows. We draw each of the nine sections at a calculated
-                // scale and translation.
-                for (var rowIndex:int=0; rowIndex < 3; rowIndex++)
-                {
-                    for (var colIndex:int = 0; colIndex < 3; colIndex++)
-                    {
-                        // Create the source and destination rectangles for the current section
-                        sourceSection.topLeft = cachedSourceGrid[rowIndex][colIndex];
-                        sourceSection.bottomRight = cachedSourceGrid[rowIndex+1][colIndex+1];
-
-                        destSection.topLeft = cachedDestGrid[rowIndex][colIndex];
-                        destSection.bottomRight = cachedDestGrid[rowIndex+1][colIndex+1];
-
-                        matrix.identity();
-                        // Scale the bitmap by the ratio between the source and destination dimensions
-                        matrix.scale(destSection.width / sourceSection.width, destSection.height / sourceSection.height);
-                        // Translate based on the difference between the source and destination coordinates,
-                        // making sure to account for the new scale.
-                        matrix.translate(destSection.x - sourceSection.x * matrix.a, destSection.y - sourceSection.y * matrix.d);
-                        matrix.translate(roundedDrawX, roundedDrawY);
-
-                        // Draw the bitmap for the current section
-                        g.beginBitmapFill(_bitmapData, matrix);
-                        g.drawRect(destSection.x + roundedDrawX, destSection.y + roundedDrawY, destSection.width, destSection.height);
-                        g.endFill();
-                    }
-                }
-            }
-
-            previousUnscaledWidth = unscaledWidth;
-            previousUnscaledHeight = unscaledHeight;
-        }
-
-        /**
-         *  @private
-         */
-        override protected function get needsDisplayObject():Boolean
-        {
-            // If we are hosting untrusted content the hosted loader becomes
-            // our display object.
-            return !trustedSource || super.needsDisplayObject;
-        }
-
-        //--------------------------------------------------------------------------
-        //
-        //  Methods
-        //
-        //--------------------------------------------------------------------------
-
-        /**
-         *  @private
-         *  Utility function that sets the underlying bitmapData property.
-         */
-        protected function setBitmapData(bitmapData:BitmapData,
-                                         internallyCreated:Boolean = false):void
-        {
-            // Clear previous bitmapData
-            clearBitmapData();
-
-            // Reset imageWidth/Height, as we aren't
-            // loading external content so no reason to
-            // cache our existing image width and height.
-            imageWidth = imageHeight = NaN;
-
-            // Clear any currently loading content.
-            clearLoadingContent();
-
-            if (bitmapData)
-            {
-                bitmapDataCreated = internallyCreated;
-
-                _bitmapData = bitmapData;
-
-                imageWidth = bitmapData.width;
-                imageHeight = bitmapData.height;
-
-                // Flush the cached scale grid points
-                cachedSourceGrid = null;
-                cachedDestGrid = null;
+                // Denote that we are hosting an untrusted image and as such some
+                // features requiring access to the bitmap data will no longer
+                // function.
+                _trustedSource = false;

                 // Dispatch ready event
-                dispatchEvent(new FlexEvent(FlexEvent.READY));
+                dispatchEvent(new FlexEvent(FlexEvent.READY));
             }
-
-            invalidateSize();
-            invalidateDisplayList();
-        }
-
-        /**
-         *  @private
-         *  Utility method which analyzes our source and either acquires the
-         *  associated bitmap data immediately or queues up a remote request
-         *  as necessary.
-         */
-        mx_internal function applySource():void
-        {
-            var value:Object = _source;
-            var bitmapData:BitmapData;
-            var tmpSprite:DisplayObject;
-
-            // Clear the previous scaleGrid properties
-            _scaleGridLeft = NaN;
-            _scaleGridRight = NaN;
-            _scaleGridTop = NaN;
-            _scaleGridBottom = NaN;
-            var currentBitmapCreated:Boolean = false;
-
-            // Reset byte counts and _trustedSource
-            _bytesLoaded = NaN;
-            _bytesTotal = NaN;
-            _trustedSource = true;
-
-            // We'll need to reconsider display object sharing.
+        }
+        else
+        {
+            if (content is BitmapData)
+                setBitmapData(content as BitmapData);
+        }
+    }
+
+    /**
+     * @private
+     * Returns true if are to consider aspect ratio while scaling.
+     */
+    private function get maintainAspectRatio():Boolean
+    {
+        return (_scaleMode == BitmapScaleMode.LETTERBOX && _fillMode == BitmapFillMode.SCALE);
+    }
+
+    /**
+     * @private
+     * Removes any previously loaded content prior to loading new.
+     */
+    private function removePreviousContent():void
+    {
+        if (loadedContent && loadedContent.parent)
+        {
+            displayObjectSharingMode = DisplayObjectSharingMode.USES_SHARED_OBJECT;
             invalidateDisplayObjectSharing();
-            invalidateDisplayList();
-
-            // Remove any previously hosted content prior to loading
-            // new content (if applicable).
-            if (_clearOnLoad)
-                removePreviousContent();
-
-            if (value is Class)
-            {
-                var cls:Class = Class(value);
-                value = new cls();
-                currentBitmapCreated = true;
+            loadedContent.parent.removeChild(loadedContent);
+            loadedContent = null;
+            setDisplayObject(null);
+            imageWidth = imageHeight = NaN;
+        }
+        else if (drawnDisplayObject)
+        {
+            Sprite(drawnDisplayObject).graphics.clear();
+            clearBitmapData();
+        }
+    }
+
+    /**
+     *  @private
+     */
+    private function clearLoadingContent():void
+    {
+        if (loadingContent is LoaderInfo && LoaderInfo(loadingContent).loader)
+        {
+            try
+            {
+                LoaderInfo(loadingContent).loader.close();
             }
-            else if (value is String || value is URLRequest)
-            {
-                loadExternal(value);
+            catch (e:Error)
+            {
+                // Ignore
             }
-            else if (value is ByteArray)
-            {
-                loadFromBytes(value as ByteArray);
+        }
+
+        removeLoadingListeners();
+        loadingContent = null;
+    }
+
+    /**
+     *  @private
+     */
+    private function clearBitmapData():void
+    {
+        if (_bitmapData)
+        {
+            // Dispose the bitmap if we created it
+            if (bitmapDataCreated)
+                _bitmapData.dispose();
+            _bitmapData = null;
+        }
+    }
+
+    /**
+     *  @private
+     */
+    private function attachLoadingListeners():void
+    {
+        if (loadingContent)
+        {
+            loadingContent.addEventListener(Event.COMPLETE,
+                loader_completeHandler, false, 0, true);
+            loadingContent.addEventListener(IOErrorEvent.IO_ERROR,
+                loader_ioErrorHandler, false, 0, true);
+            loadingContent.addEventListener(ProgressEvent.PROGRESS,
+                loader_progressHandler, false, 0, true);
+            loadingContent.addEventListener(SecurityErrorEvent.SECURITY_ERROR,
+                loader_securityErrorHandler, false, 0, true);
+            loadingContent.addEventListener(HTTPStatusEvent.HTTP_STATUS,
+                dispatchEvent, false, 0, true);
+        }
+    }
+
+    /**
+     *  @private
+     */
+    private function removeLoadingListeners():void
+    {
+        if (loadingContent)
+        {
+            loadingContent.removeEventListener(Event.COMPLETE,
+                loader_completeHandler);
+            loadingContent.removeEventListener(IOErrorEvent.IO_ERROR,
+                loader_ioErrorHandler);
+            loadingContent.removeEventListener(ProgressEvent.PROGRESS,
+                loader_progressHandler);
+            loadingContent.removeEventListener(SecurityErrorEvent.SECURITY_ERROR,
+                loader_securityErrorHandler);
+            loadingContent.removeEventListener(HTTPStatusEvent.HTTP_STATUS,
+                dispatchEvent);
+        }
+    }
+
+
+    /**
+     *  @private
+     *  Utility method which is invoked to initiate loading of our
+     *  source.
+     */
+    mx_internal function validateSource():void
+    {
+        if (sourceInvalid || contentLoaderInvalid)
+        {
+            applySource();
+            sourceInvalid = false;
+            contentLoaderInvalid = false;
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Event handlers
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    mx_internal function loader_completeHandler(event:Event):void
+    {
+        try
+        {
+            var loaderInfo:LoaderInfo = (event.target is ContentRequest) ?
+                event.target.content as LoaderInfo : event.target as LoaderInfo;
+
+            if (loaderInfo.bytesLoaded)
+            {
+                _bytesLoaded = _bytesTotal;
+                contentComplete(loaderInfo);
             }
-
-            if (value is BitmapData)
-            {
-                bitmapData = value as BitmapData;
-            }
-            else if (value is Bitmap)
-            {
-                bitmapData = value.bitmapData;
-            }
-            else if (value is DisplayObject)
-            {
-                tmpSprite = value as DisplayObject;
-
-                if ((tmpSprite.width == 0 || tmpSprite.height == 0) && !tmpSprite.stage )
-                {
-                    // If our source DisplayObject has yet to be assigned a stage,
-                    // and doesn't have valid bounds, it is not ready to be captured,
-                    // so we defer bitmap capture until it is added to the display list.
-                    tmpSprite.addEventListener(Event.ADDED_TO_STAGE, source_addedToStageHandler);
-                    return;
-                }
-            }
-            else if (value == null)
-            {
-                // This will set source to null
-            }
-            else
-            {
-                // We're loading external content or we
-                // we have an unsupported source value.
-                return;
-            }
-
-            if (!bitmapData && tmpSprite)
-            {
-                // We must ensure any IInvalidating sources
-                // are properly validated before capturing.
-                if (tmpSprite is IInvalidating)
-                    IInvalidating(tmpSprite).validateNow();
-
-                // Return immediately if our input source has 0 bounds else
-                // our BitmapData constructor will RTE.
-                if (tmpSprite.width == 0 || tmpSprite.height == 0)
-                    return;
-
-                bitmapData = new BitmapData(tmpSprite.width, tmpSprite.height, true, 0);
-                bitmapData.draw(tmpSprite, new Matrix(), tmpSprite.transform.colorTransform);
-                currentBitmapCreated = true;
-
-                if (tmpSprite.scale9Grid)
-                {
-                    _scaleGridLeft = tmpSprite.scale9Grid.left;
-                    _scaleGridRight = tmpSprite.scale9Grid.right;
-                    _scaleGridTop = tmpSprite.scale9Grid.top;
-                    _scaleGridBottom = tmpSprite.scale9Grid.bottom;
-                }
-            }
-
-            // Remove any previously hosted content prior to assigning
-            // new bitmap data (if we haven't already previously).
-            if (!_clearOnLoad)
-                removePreviousContent();
-
-            setBitmapData(bitmapData, currentBitmapCreated);
-        }
-
-        /**
-         *  @private
-         */
-        mx_internal function loadExternal(source:Object):void
-        {
-            if (contentLoader)
-            {
-                // We defer our load request to the configured content loader.
-                var contentRequest:ContentRequest = contentLoader.load(source, contentLoaderGrouping);
-
-                if (contentRequest.complete)
-                {
-                    // No need to attach listeners as we've received a fully complete
-                    // request result.
-                    contentComplete(contentRequest.content);
-                }
-                else
-                {
-                    // Attach load-event listeners to our ContentRequest instance.
-                    loadingContent = contentRequest;
-                    attachLoadingListeners();
-                }
-            }
-            else
-            {
-                var loader:Loader = new Loader();
-                var loaderContext:LoaderContext = new LoaderContext();
-
-                // Attach load-event listeners to our LoaderInfo instance.
-                loadingContent = loader.contentLoaderInfo;
-                attachLoadingListeners();
-
-                try
-                {
-                    loaderContext.checkPolicyFile = true;
-                    var urlRequest:URLRequest = source is URLRequest ?
-                        source as URLRequest : new URLRequest(source as String);
-                    loader.load(urlRequest, loaderContext);
-                }
-                catch (error:SecurityError)
-                {
-                    handleSecurityError(error);
-                }
-            }
-        }
-
-        /**
-         *  @private
-         */
-        mx_internal function loadFromBytes(source:ByteArray):void
-        {
-            var loader:Loader = new Loader();
-            var loaderContext:LoaderContext = new LoaderContext();
-            loadingContent = loader.contentLoaderInfo;
-            attachLoadingListeners();
-
-            try
-            {
-                loader.loadBytes(source as ByteArray, loaderContext);
-            }
-            catch (error:SecurityError)
-            {
-                handleSecurityError(error);
-            }
-        }
-
-        /**
-         * @private
-         * Utility function used for higher quality image scaling. Essentially we
-         * simply step down our bitmap size by half resulting in a much higher result
-         * though taking potentially multiple passes to accomplish.
-         */
-        protected static function resample(bitmapData:BitmapData, newWidth:uint,
-                                           newHeight:uint):BitmapData
-        {
-            var finalScale:Number = Math.max(newWidth/bitmapData.width,
-                newHeight/bitmapData.height);
-
-            var finalData:BitmapData = bitmapData;
-
-            if (finalScale > 1)
-            {
-                finalData = new BitmapData(bitmapData.width * finalScale,
-                    bitmapData.height * finalScale, true, 0);
-
-                finalData.draw(bitmapData, new Matrix(finalScale, 0, 0,
-                    finalScale), null, null, null, true);
-
-                return finalData;
-            }
-
-            var drop:Number = .5;
-            var initialScale:Number = finalScale;
-
-            while (initialScale/drop < 1)
-                initialScale /= drop;
-
-            var w:Number = Math.floor(bitmapData.width * initialScale);
-            var h:Number = Math.floor(bitmapData.height * initialScale);
-            var bd:BitmapData = new BitmapData(w, h, bitmapData.transparent, 0);
-
-            bd.draw(finalData, new Matrix(initialScale, 0, 0, initialScale),
-                null, null, null, true);
-            finalData = bd;
-
-            for (var scale:Number = initialScale * drop;
-                Math.round(scale * 1000) >= Math.round(finalScale * 1000);
-                scale *= drop)
-            {
-                w = Math.floor(bitmapData.width * scale);
-                h = Math.floor(bitmapData.height * scale);
-                bd = new BitmapData(w, h, bitmapData.transparent, 0);
-
-                bd.draw(finalData, new Matrix(drop, 0, 0, drop), null, null, null, true);
-                finalData.dispose();
-                finalData = bd;
-            }
-
-            return finalData;
-        }
-
-        /**
-         * @private
-         * Invoked upon completion of a load request.
-         */
-        protected function contentComplete(content:Object):void
-        {
-            if (content is LoaderInfo)
-            {
-                // Clear any previous bitmap data or loader instance.
-                setBitmapData(null);
-                removePreviousContent();
-
-                var loaderInfo:LoaderInfo = content as LoaderInfo;
-
-                if (loaderInfo.childAllowsParent)
-                {
-                    // For trusted content we adopt the loaded BitmapData.
-                    var image:Bitmap = Bitmap(loaderInfo.content);
-                    setBitmapData(image.bitmapData);
-                }
-                else
-                {
-                    // For untrusted content we must host the acquired Loader
-                    // instance directly as our DisplayObject.
-                    displayObjectSharingMode = DisplayObjectSharingMode.OWNS_UNSHARED_OBJECT;
-                    invalidateDisplayObjectSharing();
-
-                    // Create a content holder to use as our display object.
-                    var contentHolder:Sprite = new Sprite();
-                    setDisplayObject(contentHolder);
-                    loadedContent = loaderInfo.loader;
-                    contentHolder.addChild(loadedContent);
-
-                    // Retain our source image width and height.
-                    imageWidth = loaderInfo.width;
-                    imageHeight = loaderInfo.height ;
-
-                    // Update
-                    invalidateSize();
-                    invalidateDisplayList();
-
-                    // Denote that we are hosting an untrusted image and as such some
-                    // features requiring access to the bitmap data will no longer
-                    // function.
-                    _trustedSource = false;
-
-                    // Dispatch ready event
-                    dispatchEvent(new FlexEvent(FlexEvent.READY));
-                }
-            }
-            else
-            {
-                if (content is BitmapData)
-                    setBitmapData(content as BitmapData);
-            }
-        }
-
-        /**
-         * @private
-         * Returns true if are to consider aspect ratio while scaling.
-         */
-        private function get maintainAspectRatio():Boolean
-        {
-            return (_scaleMode == BitmapScaleMode.LETTERBOX && _fillMode == BitmapFillMode.SCALE);
-        }
-
-        /**
-         * @private
-         * Removes any previously loaded content prior to loading new.
-         */
-        private function removePreviousContent():void
-        {
-            if (loadedContent && loadedContent.parent)
-            {
-                displayObjectSharingMode = DisplayObjectSharingMode.USES_SHARED_OBJECT;
-                invalidateDisplayObjectSharing();
-                loadedContent.parent.removeChild(loadedContent);
-                loadedContent = null;
-                setDisplayObject(null);
-                imageWidth = imageHeight = NaN;
-            }
-            else if (drawnDisplayObject)
-            {
-                Sprite(drawnDisplayObject).graphics.clear();
-                clearBitmapData();
-            }
-        }
-
-        /**
-         *  @private
-         */
-        private function clearLoadingContent():void
-        {
-            if (loadingContent is LoaderInfo && LoaderInfo(loadingContent).loader)
-            {
-                try
-                {
-                    LoaderInfo(loadingContent).loader.close();
-                }
-                catch (e:Error)
-                {
-                    // Ignore
-                }
-            }
-
-            removeLoadingListeners();
-            loadingContent = null;
-        }
-
-        /**
-         *  @private
-         */
-        private function clearBitmapData():void
-        {
-            if (_bitmapData)
-            {
-                // Dispose the bitmap if we created it
-                if (bitmapDataCreated)
-                    _bitmapData.dispose();
-                _bitmapData = null;
-            }
-        }
-
-        /**
-         *  @private
-         */
-        private function attachLoadingListeners():void
-        {
-            if (loadingContent)
-            {
-                loadingContent.addEventListener(Event.COMPLETE,
-                    loader_completeHandler, false, 0, true);
-                loadingContent.addEventListener(IOErrorEvent.IO_ERROR,
-                    loader_ioErrorHandler, false, 0, true);
-                loadingContent.addEventListener(ProgressEvent.PROGRESS,
-                    loader_progressHandler, false, 0, true);
-                loadingContent.addEventListener(SecurityErrorEvent.SECURITY_ERROR,
-                    loader_securityErrorHandler, false, 0, true);
-                loadingContent.addEventListener(HTTPStatusEvent.HTTP_STATUS,
-                    dispatchEvent, false, 0, true);
-            }
-        }
-
-        /**
-         *  @private
-         */
-        private function removeLoadingListeners():void
-        {
-            if (loadingContent)
-            {
-                loadingContent.removeEventListener(Event.COMPLETE,
-                    loader_completeHandler);
-                loadingContent.removeEventListener(IOErrorEvent.IO_ERROR,
-                    loader_ioErrorHandler);
-                loadingContent.removeEventListener(ProgressEvent.PROGRESS,
-                    loader_progressHandler);
-                loadingContent.removeEventListener(SecurityErrorEvent.SECURITY_ERROR,
-                    loader_securityErrorHandler);
-                loadingContent.removeEventListener(HTTPStatusEvent.HTTP_STATUS,
-                    dispatchEvent);
-            }
-        }
-
-
-        /**
-         *  @private
-         *  Utility method which is invoked to initiate loading of our
-         *  source.
-         */
-        mx_internal function validateSource():void
-        {
-            if (sourceInvalid || contentLoaderInvalid)
-            {
-                applySource();
-                sourceInvalid = false;
-                contentLoaderInvalid = false;
-            }
-        }
-
-        //--------------------------------------------------------------------------
-        //
-        //  Event handlers
-        //
-        //--------------------------------------------------------------------------
-
-        /**
-         *  @private
-         */
-        mx_internal function loader_completeHandler(event:Event):void
-        {
-            try
-            {
-                var loaderInfo:LoaderInfo = (event.target is ContentRequest) ?
-                    event.target.content as LoaderInfo : event.target as LoaderInfo;
-
-                if (loaderInfo.bytesLoaded)
-                {
-                    _bytesLoaded = _bytesTotal;
-                    contentComplete(loaderInfo);
-                }
-            }
-            catch (error:SecurityError)
-            {
-                handleSecurityError(error);
-            }
-
-            dispatchEvent(event);
-
-            if (parent)
-                parent.dispatchEvent(new FlexEvent(FlexEvent.MEASURED_SIZE_FINAL, true, true));
-
-            // Remove any event listeners from load-event dispatcher.
-            clearLoadingContent();
-        }
-
-        /**
-         *  @private
-         */
-        private function loader_ioErrorHandler(error:IOErrorEvent):void
-        {
-            // forward the event, only in the case of a listener, else
-            // an RTE will occur.
-            if (hasEventListener(error.type))
-                dispatchEvent(error);
-
-            // clear any current image and remove any event listeners from
-            // load-event  dispatcher.
-            setBitmapData(null);
-            loadFailed = true;
-        }
-
-        /**
-         *  @private
-         */
-        private function loader_securityErrorHandler(error:SecurityErrorEvent):void
-        {
+        }
+        catch (error:SecurityError)
+        {
+            handleSecurityError(error);
+        }
+
+        dispatchEvent(event);
+
+        if (parent)
+            parent.dispatchEvent(new FlexEvent(FlexEvent.MEASURED_SIZE_FINAL, true, true));
+
+        // Remove any event listeners from load-event dispatcher.
+        clearLoadingContent();
+    }
+
+    /**
+     *  @private
+     */
+    private function loader_ioErrorHandler(error:IOErrorEvent):void
+    {
+        // forward the event, only in the case of a listener, else
+        // an RTE will occur.
+        if (hasEventListener(error.type))
             dispatchEvent(error);
-
-            // clear any current image and remove any event listeners from
-            // load-event  dispatcher.
-            setBitmapData(null);
-            loadFailed = true;
-        }
-
-        /**
-         *  @private
-         */
-        private function loader_progressHandler(progressEvent:ProgressEvent):void
-        {
-            _bytesLoaded = progressEvent.bytesLoaded;
-            _bytesTotal = progressEvent.bytesTotal;
-
-            // forward the event
-            dispatchEvent(progressEvent);
-        }
-
-        /**
-         *  @private
-         */
-        private function handleSecurityError(error:SecurityError):void
-        {
-            dispatchEvent(new SecurityErrorEvent(SecurityErrorEvent.SECURITY_ERROR,
-                false, false, error.message));
-
-            // clear any current image and remove any event listeners from
-            // load-event  dispatcher.
-            setBitmapData(null);
-            loadFailed = true;
-        }
-
-        /**
-         *  @private
-         *  Used for deferral of bitmap capture when an assigned source
-         *  has yet to be added to the stage.
-         */
-        private function source_addedToStageHandler(event:Event):void
-        {
-            removeAddedToStageHandler(event.target);
-            applySource();
-        }
-
-        /**
-         *  @private
-         */
-        private function removeAddedToStageHandler(target:Object):void
-        {
-            if (target && target is DisplayObject)
-                target.removeEventListener(Event.ADDED_TO_STAGE, source_addedToStageHandler);
-        }
-    }
+
+        // clear any current image and remove any event listeners from
+        // load-event  dispatcher.
+        setBitmapData(null);
+        loadFailed = true;
+    }
+
+    /**
+     *  @private
+     */
+    private function loader_securityErrorHandler(error:SecurityErrorEvent):void
+    {
+        dispatchEvent(error);
+
+        // clear any current image and remove any event listeners from
+        // load-event  dispatcher.
+        setBitmapData(null);
+        loadFailed = true;
+    }
+
+    /**
+     *  @private
+     */
+    private function loader_progressHandler(progressEvent:ProgressEvent):void
+    {
+        _bytesLoaded = progressEvent.bytesLoaded;
+        _bytesTotal = progressEvent.bytesTotal;
+
+        // forward the event
+        dispatchEvent(progressEvent);
+    }
+
+    /**
+     *  @private
+     */
+    private function handleSecurityError(error:SecurityError):void
+    {
+        dispatchEvent(new SecurityErrorEvent(SecurityErrorEvent.SECURITY_ERROR,
+            false, false, error.message));
+
+        // clear any current image and remove any event listeners from
+        // load-event  dispatcher.
+        setBitmapData(null);
+        loadFailed = true;
+    }
+
+    /**
+     *  @private
+     *  Used for deferral of bitmap capture when an assigned source
+     *  has yet to be added to the stage.
+     */
+    private function source_addedToStageHandler(event:Event):void
+    {
+        removeAddedToStageHandler(event.target);
+        applySource();
+    }
+
+    /**
+     *  @private
+     */
+    private function removeAddedToStageHandler(target:Object):void
+    {
+        if (target && target is DisplayObject)
+            target.removeEventListener(Event.ADDED_TO_STAGE, source_addedToStageHandler);
+    }
+}
 }