////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

package spark.components
{
import flash.display.DisplayObject;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
import flash.events.TimerEvent;
import flash.net.URLRequest;
import flash.utils.Timer;

import mx.controls.listClasses.*;
import mx.core.DPIClassification;
import mx.core.FlexGlobals;
import mx.core.mx_internal;
import mx.graphics.BitmapFillMode;
import mx.graphics.BitmapScaleMode;
import mx.styles.CSSStyleDeclaration;
import mx.utils.DensityUtil;

import spark.components.supportClasses.StyleableTextField;
import spark.core.ContentCache;
import spark.core.DisplayObjectSharingMode;
import spark.core.IContentLoader;
import spark.core.IGraphicElement;
import spark.core.IGraphicElementContainer;
import spark.core.ISharedDisplayObject;
import spark.primitives.BitmapImage;
import spark.utils.MultiDPIBitmapSource;

use namespace mx_internal;

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

include "../styles/metadata/GapStyles.as"

/**
 *  The delay value before attempting to load the 
 *  icon's source if it has not been cached already.
 * 
 *  <p>The reason a delay is useful is while scrolling around, you 
 *  don't necessarily want the image to load up immediately.  Instead, 
 *  you should wait a certain delay period to make sure the user actually 
 *  wants to see this item renderer.</p>
 * 
 *  @default 500
 *  
 *  @langversion 3.0
 *  @playerversion AIR 2.5
 *  @productversion Flex 4.5
 */
[Style(name="iconDelay", type="Number", format="Time", inherit="no")]

/**
 *  Name of the CSS Style declaration to use for the styles for the
 *  message component.
 * 
 *  @default iconItemRendererMessageStyle
 *  
 *  @langversion 3.0
 *  @playerversion AIR 2.5
 *  @productversion Flex 4.5
 */
[Style(name="messageStyleName", type="String", inherit="no")]

/**
 *  The IconItemRenderer class is a performant item 
 *  renderer optimized for mobile devices.  
 *  It displays four optional parts for each item in the 
 *  list-based control: 
 *
 *  <ul>
 *    <li>An icon on the left defined by the <code>iconField</code> or 
 *      <code>iconFunction</code> property.</li>
 *    <li>A single-line text label next to the icon defined by the 
 *      <code>labelField</code> or <code>labelFunction</code> property.</li>
 *    <li>A multi-line message below the text label defined by the 
 *      <code>messageField</code> or <code>messageFunction</code> property.</li>
 *    <li>A decorator icon on the right defined by the 
 *      <code>decorator</code> property.</li>
 *  </ul>
 *
 *  <p>To apply CSS styles to the single-line text label, such as font size and color, 
 *  set the styles on the IconItemRenderer class. 
 *  To set styles on the multi-line message, use the <code>messageStyleNameM</code> style property. 
 *  The following example sets the text styles for both the text label and message:</p>
 *
 *  <pre>
 *     &lt;fx:Style&gt;
 *         .myFontStyle { 
 *             fontSize: 15;
 *             color: #9933FF;
 *         }
 *  
 *     &lt;/fx:Style&gt;
 *     
 *     &lt;s:List id="myList"
 *         width="100%" height="100%"
 *         labelField="firstName"&gt;
 *         &lt;s:itemRenderer&gt;
 *             &lt;fx:Component&gt;
 *                 &lt;s:IconItemRenderer messageStyleName="myFontStyle" fontSize="25"
 *                     labelField="firstName"
 *                     messageField="lastName" 
 *                     decorator="&#64;Embed(source='assets/logo_small.jpg')"/&gt;
 *             &lt;/fx:Component&gt;
 *         &lt;/s:itemRenderer&gt;
 *         &lt;s:ArrayCollection&gt;
 *             &lt;fx:Object firstName="Dave" lastName="Duncam" company="Adobe" phone="413-555-1212"/&gt;
 *             &lt;fx:Object firstName="Sally" lastName="Smith" company="Acme" phone="617-555-1491"/&gt;
 *             &lt;fx:Object firstName="Jim" lastName="Jackson" company="Beta" phone="413-555-2345"/&gt;
 *             &lt;fx:Object firstName="Mary" lastName="Moore" company="Gamma" phone="617-555-1899"/&gt;
 *         &lt;/s:ArrayCollection&gt;
 *     &lt;/s:List&gt;
 *  </pre>
 *
 *  @mxml
 *  
 *  <p>The <code>&lt;s:IconItemRenderer&gt;</code> tag inherits all of the tag 
 *  attributes of its superclass and adds the following tag attributes:</p>
 *  
 *  <pre>
 *  &lt;s:IconItemRenderer
 *   <strong>Properties</strong>
 *    decorator=""
 *    iconContentLoader="<i>See property description</i>"
 *    iconField="null"
 *    iconFillMode=""scale
 *    iconFunction="null"
 *    iconHeight="NaN"
 *    iconPlaceholder="null"
 *    iconScaleMode="stretch"
 *    iconWidth="NaN"
 *    label=""
 *    labelField="null"
 *    labelFunction="null"
 *    messageField="null"
 *    messageFunction="null"
 * 
 *   <strong>Common Styles</strong>
 *    horizontalGap="8"
 *    iconDelay="500"
 *    messageStyleName="iconItemRendererMessageStyle"
 *    verticalGap="6"
 *  &gt;
 *  </pre>
 *
 *  @see spark.components.List
 *  @see mx.core.IDataRenderer
 *  @see spark.components.IItemRenderer
 *  @see spark.components.supportClasses.ItemRenderer
 *  @see spark.components.LabelItemRenderer
 *  @includeExample examples/IconItemRendererExample.mxml -noswf
 *  
 *  @langversion 3.0
 *  @playerversion AIR 2.5
 *  @productversion Flex 4.5
 */
public class IconItemRenderer extends LabelItemRenderer 
    implements IGraphicElementContainer, ISharedDisplayObject
{
    
    //--------------------------------------------------------------------------
    //
    //  Class constants
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     *  Static icon image cache.  This is the default for iconContentLoader.
     */
    mx_internal static var _imageCache:ContentCache;
    
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------
    
    /**
     *  Constructor.
     *  
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function IconItemRenderer()
    {
        super();
        
        if (_imageCache == null) {
            _imageCache = new ContentCache();
            _imageCache.enableCaching = true;
            _imageCache.maxCacheEntries = 100;
        }
        
        // set default messageDisplay width
        switch (applicationDPI)
        {
			case DPIClassification.DPI_640:
			{
				oldUnscaledWidth = 1280;
				break;
			}
			case DPIClassification.DPI_480:
			{
				oldUnscaledWidth = 960;
				break;
			}
            case DPIClassification.DPI_320:
            {
                oldUnscaledWidth = 640;
                break;
            }
			case DPIClassification.DPI_240:
			{
				oldUnscaledWidth = 480;
				break;
			}
			case DPIClassification.DPI_120:
			{
				oldUnscaledWidth = 240;
				break;
			}
            default:
            {
                // default PPI160
                oldUnscaledWidth = 320;
                break;
            }
        }
    }
    
    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     *  Stores the text of the label component.  This is calculated in 
     *  commitProperties() based on labelFunction, labelField, and label.
     * 
     *  <p>We can't just use labelDisplay.text because it may contain 
     *  a truncated value.</p>
     */
    mx_internal var labelText:String = "";
    
    /**
     *  @private
     *  Stores the text of the message component.  This is calculated in 
     *  commitProperties() based on messageField and messageFunction.
     * 
     *  <p>We can't just use messageDisplay.text because it may contain 
     *  a truncated value (Technically we don't truncate message's text 
     *  at the moment because it's multi-line text, but in the future 
     *  we may not do that, and this feels more consistent with 
     *  how we deal with labels, so we still keep this "extra"
     *  variable around even though technically it's not needed).</p>
     */
    mx_internal var messageText:String = "";
    
    /**
     *  @private
     *  Since iconDisplay is a GraphicElement, we have to call its lifecycle methods 
     *  directly.
     */
    private var iconNeedsValidateProperties:Boolean = false;
    
    /**
     *  @private
     *  Since iconDisplay is a GraphicElement, we have to call its lifecycle methods 
     *  directly.
     */
    private var iconNeedsValidateSize:Boolean = false;
    
    /**
     *  @private
     *  Since iconDisplay is a GraphicElement, we have to call help assign 
     *  its display object
     */
    private var iconNeedsDisplayObjectAssignment:Boolean = false;
    
    /**
     *  @private
     *  Timer, used to delay setting the source on the icon.
     */
    private var iconSetterDelayTimer:Timer;
    
    /**
     *  @private
     *  The source to set iconDisplay to, after waiting an appropriate delay period
     */
    private var iconSourceToLoad:Object;
    
    /**
     *  @private
     *  The width of the component on the previous layout manager 
     *  pass.  This gets set in updateDisplayList() and used in measure() on 
     *  the next layout pass.  This is so our "guessed width" in measure() 
     *  will be as accurate as possible since messageDisplay is multiline and 
     *  the messageDisplay height is dependent on the width.
     * 
     *  In the constructor, this is actually set based on the DPI.
     */
    mx_internal var oldUnscaledWidth:Number;
    
    /**
     *  @private
     *  Since decoratorDisplay is a GraphicElement, we have to call its lifecycle methods 
     *  directly.
     */
    private var decoratorNeedsValidateProperties:Boolean = false;
    
    /**
     *  @private
     *  Since decoratorDisplay is a GraphicElement, we have to call its lifecycle methods 
     *  directly.
     */
    private var decoratorNeedsValidateSize:Boolean = false;
    
    /**
     *  @private
     *  Since decoratorDisplay is a GraphicElement, we have to call help assign 
     *  its display object
     */
    private var decoratorNeedsDisplayObjectAssignment:Boolean = false;
    
    //--------------------------------------------------------------------------
    //
    //  Public Properties: Overridden
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    override public function set data(value:Object):void
    {
        super.data = value;
        
        iconChanged = true;
        labelChanged = true;
        messageChanged = true;
        
        invalidateProperties();
    }
    
    /**
     *  <p>If <code>labelFunction</code> = <code>labelField</code> = null,
     *  then use the <code>label</code> property that gets 
     *  pushed in from the list control. 
     *  However if <code>labelField</code> is explicitly set to 
     *  <code>""</code> (the empty string), then no label appears.</p>
     * 
     *  @inheritDoc
     * 
     *  @see spark.components.IconItemRenderer#labelField
     *  @see spark.components.IconItemRenderer#labelFunction
     *  @see spark.components.IItemRenderer#label
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5   
     */
    override public function set label(value:String):void
    {
        if (value == label)
            return;
        
        super.label = value;
        
        labelChanged = true;
        invalidateProperties();
    }
    
    //--------------------------------------------------------------------------
    //
    //  Public Properties
    //
    //--------------------------------------------------------------------------
    
    //----------------------------------
    //  iconContentLoader
    //----------------------------------
    
    /**
     *  @private 
     */ 
    private var _iconContentLoader:IContentLoader = _imageCache;
    
    
    /**
     *  Optional custom image loader, such as an image cache or queue, to
     *  associate with content loader client.
     * 
     *  <p>The default value is a static content cache defined on IconItemRenderer
     *  that allows up to 100 entries.</p>
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5   
     */
    public function get iconContentLoader():IContentLoader
    {
        return _iconContentLoader;
    }
    
    /**
     *  @private
     */ 
    public function set iconContentLoader(value:IContentLoader):void
    {
        if (value == _iconContentLoader)
            return;
        
        _iconContentLoader = value;
        
        if (iconDisplay)
            iconDisplay.contentLoader = _iconContentLoader;
    }
    
    //----------------------------------
    //  decorator
    //----------------------------------
    
    /**
     *  @private 
     */ 
    private var _decorator:Object;
    
    /**
     *  @private 
     */ 
    private var decoratorChanged:Boolean;
    
    /**
     *  @private
     *  The class to use when instantiating the decorator for IconItemRenderer.
     *  This class must extend spark.primitives.BitmapImage.
     *  This property was added for Design View so they can set this to a special
     *  subclass of BitmapImage that knows how to load and resolve resources in Design View.
     */
    mx_internal var decoratorDisplayClass:Class = BitmapImage;
    
    /**
     *  The display object component used to 
     *  display the decorator for this item renderer.
     *
     *  @default null
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */ 
    protected var decoratorDisplay:BitmapImage;
    
    /**
     *  The decorator icon that appears on the right side 
     *  of this item renderer.
     * 
     *  <p>The decorator icon ignores the <code>verticalAlign</code> style
     *  and is always centered vertically.</p>
     *
     *  <p>The decorator icon is expected to be an embedded asset.  There can
     *  be performance degradation if using external assets.</p>
     *
     *  @default "" 
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5   
     */
    public function get decorator():Object
    {
        return _decorator;
    }
    
    /**
     *  @private
     */ 
    public function set decorator(value:Object):void
    {
        if (value == _decorator)
            return;
        
        _decorator = value;
        
        decoratorChanged = true;
        invalidateProperties();
    }
    
    //----------------------------------
    //  labelField
    //----------------------------------
    
    /**
     *  @private
     */
    private var _labelField:String = null;
    
    /**
     *  @private
     */
    private var labelFieldOrFunctionChanged:Boolean;
    
    /**
     *  @private
     */
    private var labelChanged:Boolean; 
    
    /**
     *  The name of the field in the data provider items to display 
     *  as the label. 
     *  The <code>labelFunction</code> property overrides this property.
     * 
     *  <p>If <code>labelFunction</code> = <code>labelField</code> = null,
     *  then use the <code>label</code> property that gets 
     *  pushed in from the list-based control.  
     *  However if <code>labelField</code> is explicitly set to 
     *  <code>""</code> (the empty string),
     *  then no label appears.</p>
     * 
     *  @see spark.components.IconItemRenderer#labelFunction
     *  @see spark.components.IItemRenderer#label
     *
     *  @default null
     *  
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function get labelField():String
    {
        return _labelField;
    }
    
    /**
     *  @private
     */
    public function set labelField(value:String):void
    {
        if (value == _labelField)
            return;
            
        _labelField = value;
        labelFieldOrFunctionChanged = true;
        labelChanged = true;
        
        invalidateProperties();
    }
    
    //----------------------------------
    //  labelFunction
    //----------------------------------
    
    /**
     *  @private
     */
    private var _labelFunction:Function; 
    
    /**
     *  A user-supplied function to run on each item to determine its label.  
     *  The <code>labelFunction</code> property overrides 
     *  the <code>labelField</code> property.
     *
     *  <p>You can supply a <code>labelFunction</code> that finds the 
     *  appropriate fields and returns a displayable string. The 
     *  <code>labelFunction</code> is also good for handling formatting and 
     *  localization.</p>
     *
     *  <p>The label function takes a single argument which is the item in 
     *  the data provider and returns a String.</p>
     *  <pre>
     *  myLabelFunction(item:Object):String</pre>
     * 
     *  <p>If <code>labelFunction</code> = <code>labelField</code> = null,
     *  then use the <code>label</code> property that gets 
     *  pushed in from the list-based control.  
     *  However if <code>labelField</code> is explicitly set to 
     *  <code>""</code> (the empty string),
     *  then no label appears.</p>
     * 
     *  @see spark.components.IconItemRenderer#labelFunction
     *  @see spark.components.IItemRenderer#label
     *
     *  @default null
     *  
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function get labelFunction():Function
    {
        return _labelFunction;
    }
    
    /**
     *  @private
     */
    public function set labelFunction(value:Function):void
    {
        if (value == _labelFunction)
            return;
            
        _labelFunction = value;
        labelFieldOrFunctionChanged = true;
        labelChanged = true;
        
        invalidateProperties(); 
    }
    
    //----------------------------------
    //  iconField
    //----------------------------------
    
    /**
     *  @private 
     */ 
    private var _iconField:String;
    
    /**
     *  @private 
     */ 
    private var iconFieldOrFunctionChanged:Boolean;
    
    /**
     *  @private 
     */ 
    private var iconChanged:Boolean;
    
    /**
     *  @private
     *  The class to use when instantiating the icon for IconItemRenderer.
     *  This class must extend spark.primitives.BitmapImage.
     *  This property was added for Design View so they can set this to a special
     *  subclass of BitmapImage that knows how to load and resolve resources in Design View.
     */
    mx_internal var iconDisplayClass:Class = BitmapImage;
    
    /**
     *  The bitmap image component used to 
     *  display the icon data of the item renderer.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    protected var iconDisplay:BitmapImage;
    
    /**
     *  The name of the field in the data item to display as the icon. 
     *  By default <code>iconField</code> is <code>null</code>, and the item renderer 
     *  does not display an icon.
     *
     *  @default null
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function get iconField():String
    {
        return _iconField;
    }
    
    /**
     *  @private
     */ 
    public function set iconField(value:String):void
    {
        if (value == _iconField)
            return;
        
        _iconField = value;
        iconFieldOrFunctionChanged = true;
        iconChanged = true;
        
        invalidateProperties();
    }
    
    //----------------------------------
    //  iconFillMode
    //----------------------------------
    
    /**
     *  @private 
     */ 
    private var _iconFillMode:String = BitmapFillMode.SCALE;
    
    [Inspectable(category="General", enumeration="clip,repeat,scale", defaultValue="scale")]
    
    /**
     *  @copy spark.primitives.BitmapImage#fillMode
     *
     *  @default <code>mx.graphics.BitmapFillMode.SCALE</code>
     *
     *  @see mx.graphics.BitmapFillMode
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function get iconFillMode():String
    {
        return _iconFillMode;
    }
    
    /**
     *  @private
     */ 
    public function set iconFillMode(value:String):void
    {
        if (value == _iconFillMode)
            return;
        
        _iconFillMode = value;
        
        if (iconDisplay)
            iconDisplay.fillMode = _iconFillMode;
    }
    
    //----------------------------------
    //  iconFunction
    //----------------------------------
    
    /**
     *  @private 
     */ 
    private var _iconFunction:Function;
    
    /**
     *  A user-supplied function to run on each item to determine its icon.  
     *  The <code>iconFunction</code> property overrides 
     *  the <code>iconField</code> property.
     *
     *  <p>You can supply an <code>iconFunction</code> that finds the 
     *  appropriate fields and returns a valid URL or object to be used as 
     *  the icon.</p>
     *
     *  <p>The icon function takes a single argument which is the item in 
     *  the data provider and returns an Object that gets passed to a 
     *  <code>spark.primitives.BitmapImage</code> object as the <code>source</code>
     *  property.  Icon function can return a valid URL pointing to an image 
     *  or a Class file that represents an image.  To see what other types 
     *  of objects can be returned from the icon 
     *  function, see the <code>BitmapImage</code>'s documentation</p>
     *  <pre>
     *  myIconFunction(item:Object):Object</pre>
     *
     *  @default null
     * 
     *  @see spark.primitives.BitmapImage#source
     *  
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function get iconFunction():Function
    {
        return _iconFunction;
    }
    
    /**
     *  @private
     */ 
    public function set iconFunction(value:Function):void
    {
        if (value == _iconFunction)
            return;
        
        _iconFunction = value;
        iconFieldOrFunctionChanged = true;
        iconChanged = true;
        
        invalidateProperties();
    }
    
    //----------------------------------
    //  iconHeight
    //----------------------------------
    
    /**
     *  @private 
     */ 
    private var _iconHeight:Number;
    
    /**
     *  The height of the icon.  If unspecified, the 
     *  intrinsic height of the image is used.
     *
     *  @default NaN
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function get iconHeight():Number
    {
        return _iconHeight;
    }
    
    /**
     *  @private
     */ 
    public function set iconHeight(value:Number):void
    {
        if (value == _iconHeight)
            return;
        
        _iconHeight = value;
        
        if (iconDisplay)
            iconDisplay.explicitHeight = _iconHeight;
        
        invalidateSize();
        invalidateDisplayList();
    }
    
    //----------------------------------
    //  iconPlaceholder
    //----------------------------------
    
    /**
     *  @private 
     */ 
    private var _iconPlaceholder:Object;
    
    /**
     *  The icon asset to use while an externally loaded asset is
     *  being downloaded.
     * 
     *  <p>This asset should be an embedded image and not an externally 
     *  loaded image.</p>
     *
     *  @default null
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function get iconPlaceholder():Object
    {
        return _iconPlaceholder;
    }
    
    /**
     *  @private
     */ 
    public function set iconPlaceholder(value:Object):void
    {
        if (value == _iconPlaceholder)
            return;
        
        _iconPlaceholder = value;
        
        iconChanged = true;
        invalidateProperties();
        
        // clear clearOnLoad if necessary
        if (iconDisplay)
            iconDisplay.clearOnLoad = (iconPlaceholder == null);
    }
    
    //----------------------------------
    //  iconScaleMode
    //----------------------------------
    
    /**
     *  @private 
     */ 
    private var _iconScaleMode:String = BitmapScaleMode.STRETCH;
    
    [Inspectable(category="General", enumeration="stretch,letterbox", defaultValue="stretch")]
    
    /**
     *  @copy spark.primitives.BitmapImage#scaleMode
     *
     *  @default <code>mx.graphics.BitmapScaleMode.STRETCH</code>
     *
     *  @see mx.graphics.BitmapScaleMode
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function get iconScaleMode():String
    {
        return _iconScaleMode;
    }
    
    /**
     *  @private
     */ 
    public function set iconScaleMode(value:String):void
    {
        if (value == _iconScaleMode)
            return;
        
        _iconScaleMode = value;
        
        if (iconDisplay)
            iconDisplay.scaleMode = _iconScaleMode;
    }
    
    //----------------------------------
    //  iconWidth
    //----------------------------------
    
    /**
     *  @private 
     */ 
    private var _iconWidth:Number;
    
    /**
     *  The width of the icon.  If unspecified, the 
     *  intrinsic width of the image is used.
     *
     *  @default NaN
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function get iconWidth():Number
    {
        return _iconWidth;
    }
    
    /**
     *  @private
     */ 
    public function set iconWidth(value:Number):void
    {
        if (value == _iconWidth)
            return;
        
        _iconWidth = value;
        
        if (iconDisplay)
            iconDisplay.explicitWidth = _iconWidth;
        
        invalidateSize();
        invalidateDisplayList();
    }
    
    //----------------------------------
    //  messageField
    //----------------------------------
    
    /**
     *  @private
     */
    private var _messageField:String;
    
    /**
     *  The text component used to 
     *  display the message data of the item renderer.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    protected var messageDisplay:StyleableTextField;
    
    /**
     *  @private
     */
    private var messageFieldOrFunctionChanged:Boolean;
    
    /**
     *  @private
     */
    private var messageChanged:Boolean;
    
    /**
     *  The name of the field in the data items to display 
     *  as the message. 
     *  The <code>messageFunction</code> property overrides this property.
     *
     *  <p>Use the <code>messageStyleName</code> style to control the 
     *  appearance of the text.</p>
     *
     *  @default null
     *  
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function get messageField():String
    {
        return _messageField;
    }
    
    /**
     *  @private
     */
    public function set messageField(value:String):void
    {
        if (value == _messageField)
            return;
        
        _messageField = value;
        messageFieldOrFunctionChanged = true;
        messageChanged = true;
        
        invalidateProperties();
    }
    
    //----------------------------------
    //  messageFunction
    //----------------------------------
    
    /**
     *  @private
     */
    private var _messageFunction:Function;
    
    /**
     *  A user-supplied function to run on each item to determine its message.  
     *  The <code>messageFunction</code> property overrides 
     *  the <code>messageField</code> property.
     *
     *  <p>You can supply a <code>messageFunction</code> that finds the 
     *  appropriate fields and returns a displayable string. The 
     *  <code>messageFunction</code> is also good for handling formatting and 
     *  localization.</p>
     *
     *  <p>The message function takes a single argument which is the item in 
     *  the data provider and returns a String.</p>
     *  <pre>
     *  myMessageFunction(item:Object):String</pre>
     *
     *  @default null
     *  
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function get messageFunction():Function
    {
        return _messageFunction;
    }
    
    /**
     *  @private
     */
    public function set messageFunction(value:Function):void
    {
        if (value == _messageFunction)
            return;
        
        _messageFunction = value;
        messageFieldOrFunctionChanged = true;
        messageChanged = true;
        
        invalidateProperties(); 
    }
    
    //----------------------------------
    //  redrawRequested
    //----------------------------------
    
    /**
     *  @private
     */
    private var _redrawRequested:Boolean = false;
    
    /**
     *  @inheritDoc
     * 
     *  <p>We implement this as part of ISharedDisplayObject so the iconDisplay 
     *  can share our display object.</p>
     *  
     *  @langversion 3.0
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get redrawRequested():Boolean
    {
        return _redrawRequested;
    }
    
    /**
     *  @private
     */
    public function set redrawRequested(value:Boolean):void
    {
        _redrawRequested = value;
    }
    
    //--------------------------------------------------------------------------
    //
    //  IGraphicElementContainer
    //
    //--------------------------------------------------------------------------
    
    /**
     *  Notify the host that an element layer has changed.
     *
     *  The <code>IGraphicElementHost</code> must re-evaluates the sequences of 
     *  graphic elements with shared DisplayObjects and may need to re-assign the 
     *  DisplayObjects and redraw the sequences as a result. 
     * 
     *  Typically the host will perform this in its 
     *  <code>validateProperties()</code> method.
     *
     *  @param element The element that has changed size.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function invalidateGraphicElementSharing(element:IGraphicElement):void
    {
        // since the only graphic elements are hooked up to drawing with the background,
        // just invalidate display list
        if (element == iconDisplay)
            iconNeedsDisplayObjectAssignment = true;
        else if (element == decoratorDisplay)
            decoratorNeedsDisplayObjectAssignment = true;
        invalidateProperties();
    }
    
    /**
     *  Notify the host component that an element changed and needs to validate properties.
     * 
     *  The <code>IGraphicElementHost</code> must call the <code>validateProperties()</code>
     *  method on the IGraphicElement to give it a chance to commit its properties.
     * 
     *  Typically the host will validate the elements' properties in its
     *  <code>validateProperties()</code> method.
     *
     *  @param element The element that has changed.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function invalidateGraphicElementProperties(element:IGraphicElement):void
    {
        if (element == iconDisplay)
            iconNeedsValidateProperties = true;
        else if (element == decoratorDisplay)
            decoratorNeedsValidateProperties = true;
        invalidateProperties();
    }
    
    /**
     *  Notify the host component that an element size has changed.
     * 
     *  The <code>IGraphicElementHost</code> must call the <code>validateSize()</code>
     *  method on the IGraphicElement to give it a chance to validate its size.
     * 
     *  Typically the host will validate the elements' size in its
     *  <code>validateSize()</code> method.
     *
     *  @param element The element that has changed size.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function invalidateGraphicElementSize(element:IGraphicElement):void
    {
        if (element == iconDisplay)
            iconNeedsValidateSize = true;
        else if (element == decoratorDisplay)
            decoratorNeedsValidateSize = true;
        invalidateSize();
    }
    
    /**
     *  Notify the host component that an element has changed and needs to be redrawn.
     * 
     *  The <code>IGraphicElementHost</code> must call the <code>validateDisplayList()</code>
     *  method on the IGraphicElement to give it a chance to redraw.
     * 
     *  Typically the host will validate the elements' display lists in its
     *  <code>validateDisplayList()</code> method.
     *
     *  @param element The element that has changed.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function invalidateGraphicElementDisplayList(element:IGraphicElement):void
    {
        if (element.displayObject is ISharedDisplayObject)
            ISharedDisplayObject(element.displayObject).redrawRequested = true;
        
        invalidateDisplayList();
    }
    
    //--------------------------------------------------------------------------
    //
    //  Overridden methods: UIComponent
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    override protected function createChildren():void
    {
        super.createChildren();
        
        // create any children you need in here
        
        // iconDisplay, messageDisplay, and decoratorDisplay are created in 
        // commitProperties() since they are dependent on 
        // other properties and we don't always create them
        // labelText just uses labelElement to display its data
    }
    
    /**
     *  @private
     */
    override public function styleChanged(styleName:String):void
    {
        var allStyles:Boolean = !styleName || styleName == "styleName";
        
        super.styleChanged(styleName);
        
        // if message styles may have changed, let's null out the old 
        // value and notify messageDisplay
        if (allStyles || styleName == "messageStyleName")
        {
            if (messageDisplay)
            {
                var messageStyleName:String = getStyle("messageStyleName");
                if (messageStyleName)
                {
                    var styleDecl:CSSStyleDeclaration =
                        styleManager.getMergedStyleDeclaration("." + messageStyleName);
                    
                    if (styleDecl)
                    {
                        messageDisplay.styleDeclaration = styleDecl;
                        messageDisplay.styleChanged("styleName");
                    }
                }
            }
        }
    }
    
    /**
     *  @private
     */
    override protected function commitProperties():void
    {
        super.commitProperties();
        
        if (decoratorChanged)
        {
            decoratorChanged = false;
            
            // let's see if we need to create or remove it
            if (decorator && !decoratorDisplay)
            {
                createDecoratorDisplay();
            }
            else if (!decorator && decoratorDisplay)
            {
                destroyDecoratorDisplay();
            }

            // if we have a decorator display and decoratorChanged was 
            // set to true, then we should make sure we're pointing to 
            // the right decorator source to display.
            if (decoratorDisplay)
                decoratorDisplay.source = decorator;
			            
            
            invalidateSize();
            invalidateDisplayList();
        }
        
        if (iconFieldOrFunctionChanged)
        {
            iconFieldOrFunctionChanged = false;
            
            // let's see if we need to create or remove it
            if ((iconField || (iconFunction != null)) && !iconDisplay)
            {
                createIconDisplay();
                
                if (iconDisplay)
                    attachLoadingListenersToIconDisplay();
            }
            else if (!(iconField || (iconFunction != null)) && iconDisplay)
            {
                destroyIconDisplay();
            }
            
            invalidateSize();
            invalidateDisplayList();
        }
        
        if (messageFieldOrFunctionChanged)
        {
            messageFieldOrFunctionChanged = false;
            
            // let's see if we need to create or remove it
            if ((messageField || (messageFunction != null)) && !messageDisplay)
            {
                createMessageDisplay();
            }
            else if (!(messageField || (messageFunction != null)) && messageDisplay)
            {
                destroyMessageDisplay();
            }
            
            invalidateSize();
            invalidateDisplayList();
        }
        
        // label is created in super.createChildren()
        
        if (iconChanged)
        {
            iconChanged = false;
            
            // we set the icon after a delay for performance benefits and 
            // so we can cancel the load if we're scrolling fast
            // we still grab the source here so we can make sure we don't
            // cancel a load when the data is reset (if the source is the same)
            // if icon, try setting that
            
            if (iconFunction != null)
            {
                setIconDisplaySource(iconFunction(data));
            }
            else if (iconField)
            {
                try
                {
                    if (iconField in data && data[iconField] != null)
                        setIconDisplaySource(data[iconField]);
                    else
                        setIconDisplaySource(null);
                }
                catch(e:Error)
                {
                    setIconDisplaySource(null);
                }
            }
        }
        
        if (messageChanged)
        {
            messageChanged = false;
            
            if (messageFunction != null)
            {
                messageText = messageFunction(data);
                messageDisplay.text = messageText;
            }
            else if (messageField)
            {
                try
                {
                    if (messageField in data && data[messageField] != null)
                    {
                        messageText = data[messageField];
                        messageDisplay.text = messageText;
                    }
                    else
                    {
                        messageText = "";
                        messageDisplay.text = messageText;
                    }
                }
                catch(e:Error)
                {
                    messageText = "";
                    messageDisplay.text = messageText;
                }
            }
        }
        
        if (labelChanged)
        {
            labelChanged = false;
            
            // if label, try setting that
            if (labelFunction != null)
            {
                labelText = labelFunction(data);
                if (!labelDisplay)
                    createLabelDisplay();
                labelDisplay.text = labelText;
            }
            else if (labelField) // if labelField is not null or "", then this is a user-set value
            {
                try
                {
                    if (labelField in data && data[labelField] != null)
                    {
                        labelText = data[labelField];
                        if (!labelDisplay)
                            createLabelDisplay();
                        labelDisplay.text = labelText;
                    }
                    else
                    {
                        labelText = "";
                        if (!labelDisplay)
                            createLabelDisplay();
                        labelDisplay.text = labelText;
                    }
                }
                catch(e:Error)
                {
                    labelText = "";
                    if (!labelDisplay)
                        createLabelDisplay();
                    labelDisplay.text = labelText;
                }
            }
            else if (label && labelField === null) // if there's a label and labelField === null, then show label
            {
                labelText = label;
                if (!labelDisplay)
                    createLabelDisplay();
                labelDisplay.text = labelText;
            }
            else // if labelField === ""
            {
                // get rid of labelDisplay if present
                if (labelDisplay)
                    destroyLabelDisplay();
            }
            
            invalidateSize();
            invalidateDisplayList();
        }
        
        if (iconNeedsDisplayObjectAssignment)
        {
            iconNeedsDisplayObjectAssignment = false;
            assignDisplayObject(iconDisplay);
        }
        
        if (decoratorNeedsDisplayObjectAssignment)
        {
            decoratorNeedsDisplayObjectAssignment = false;
            assignDisplayObject(decoratorDisplay);
        }
    }
    
    /**
     *  @private
     */
    override public function validateProperties():void
    {
        super.validateProperties();
        
        // Since IGraphicElement is not ILayoutManagerClient, we need to make sure we
        // validate properties of the elements
        if (iconNeedsValidateProperties)
        {
            iconNeedsValidateProperties = false;
            if (iconDisplay)
                iconDisplay.validateProperties();
        }
        
        if (decoratorNeedsValidateProperties)
        {
            decoratorNeedsValidateProperties = false;
            if (decoratorDisplay)
                decoratorDisplay.validateProperties();
        }
    }
    
    /**
     *  @private
     */
    private function assignDisplayObject(bitmapImage:BitmapImage):void
    {
        if (bitmapImage)
        {
            // try using this display object first
            if (bitmapImage.setSharedDisplayObject(this))
            {
                bitmapImage.displayObjectSharingMode = DisplayObjectSharingMode.USES_SHARED_OBJECT;
            }
            else
            {
                // if we can't use this as the display object, then let's see if 
                // the icon already has and owns a display object
                var ownsDisplayObject:Boolean = (bitmapImage.displayObjectSharingMode != DisplayObjectSharingMode.USES_SHARED_OBJECT);
                
                // If the element doesn't have a DisplayObject or it doesn't own
                // the DisplayObject it currently has, then create a new one
                var displayObject:DisplayObject = bitmapImage.displayObject;
                if (!ownsDisplayObject || !displayObject)
                    displayObject = bitmapImage.createDisplayObject();
                
                // Add the display object as a child
                // Check displayObject for null, some graphic elements
                // may choose not to create a DisplayObject during this pass.
                if (displayObject)
                    addChild(displayObject);
                
                bitmapImage.displayObjectSharingMode = DisplayObjectSharingMode.OWNS_UNSHARED_OBJECT;
            }
        }        
    }
    
    /**
     *  @private
     *  Creates the <code>messageDisplay</code> component.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */ 
    protected function createMessageDisplay():void
    {
        messageDisplay = StyleableTextField(createInFontContext(StyleableTextField));
        messageDisplay.styleName = this;
        messageDisplay.editable = false;
        messageDisplay.selectable = false;
        messageDisplay.multiline = true;
        messageDisplay.wordWrap = true;
        
        var messageStyleName:String = getStyle("messageStyleName");
        if (messageStyleName)
        {
            var styleDecl:CSSStyleDeclaration =
                styleManager.getMergedStyleDeclaration("." + messageStyleName);
            
            if (styleDecl)
                messageDisplay.styleDeclaration = styleDecl;
        }
        
        addChild(messageDisplay);
    }
    
    /**
     *  @private
     *  Destroys the messageDisplay component.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */ 
    protected function destroyMessageDisplay():void
    {
        removeChild(messageDisplay);
        messageDisplay = null;
    }
    
    /**
     *  @private
     *  Creates the iconDisplay component.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */ 
    protected function createIconDisplay():void
    {
        iconDisplay = new iconDisplayClass();
        
        iconDisplay.contentLoader = iconContentLoader;
        iconDisplay.fillMode = iconFillMode;
        iconDisplay.scaleMode = iconScaleMode;
        
        if (!isNaN(iconWidth))
            iconDisplay.explicitWidth = iconWidth;
        if (!isNaN(iconHeight))
            iconDisplay.explicitHeight = iconHeight;
        
        iconDisplay.parentChanged(this);
        
        iconNeedsDisplayObjectAssignment = true;
    }
    
    /**
     *  @private
     *  Destroys the iconDisplay component.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */ 
    protected function destroyIconDisplay():void
    {
        // need to remove the display object
        var oldDisplayObject:DisplayObject = iconDisplay.displayObject;
        if (oldDisplayObject)
        { 
            // If the element created the display object
            if (iconDisplay.displayObjectSharingMode != DisplayObjectSharingMode.USES_SHARED_OBJECT &&
                oldDisplayObject.parent == this)
            {
                removeChild(oldDisplayObject);
            }
        }
        
        iconDisplay.parentChanged(null);
        iconDisplay = null;
    }
    
    /**
     *  @private
     *  Creates the decoratorDisplay component.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */ 
    protected function createDecoratorDisplay():void
    {
        decoratorDisplay = new decoratorDisplayClass();
        decoratorDisplay.parentChanged(this);
        
        decoratorNeedsDisplayObjectAssignment = true;
    }
    
    /**
     *  @private
     *  Destroys the decoratorDisplay component.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */ 
    protected function destroyDecoratorDisplay():void
    {
        // need to remove the display object
        var oldDisplayObject:DisplayObject = decoratorDisplay.displayObject;
        if (oldDisplayObject)
        { 
            // If the element created the display object
            if (decoratorDisplay.displayObjectSharingMode != DisplayObjectSharingMode.USES_SHARED_OBJECT &&
                oldDisplayObject.parent == this)
            {
                removeChild(oldDisplayObject);
            }
        }
        
        decoratorDisplay.parentChanged(null);
        decoratorDisplay = null;
    }
    
    /**
     *  @private
     */
    private function attachLoadingListenersToIconDisplay():void
    {
        if (iconDisplay)
        {
            iconDisplay.addEventListener(IOErrorEvent.IO_ERROR, iconDisplay_loadErrorHandler, false, 0, true);
            iconDisplay.addEventListener(SecurityErrorEvent.SECURITY_ERROR, iconDisplay_loadErrorHandler, false, 0, true);
        }
    }
    
    /**
     *  @private
     *  Method is called when an IOError or SecurityError is dispatched
     *  while trying to load the icon display.  The default implementation
     *  sets the iconDisplay's source to the iconPlaceholder.
     */ 
    mx_internal function iconDisplay_loadErrorHandler(event:Event):void
    {
        iconDisplay.source = iconPlaceholder;
    }
    
    /**
     *  @private
     */
    private function loadExternalImage(source:Object, iconDelay:Number):void
    {
        // set iconDisplay's source now to either iconPlaceholder 
        // or null (if no iconPlaceholder).  this is so we don't display the old 
        // data while we're loading.
        iconDisplay.source = iconPlaceholder;
        
        // while we're loading,if iconPlaceholder is set, 
        // we'll keep that image up while we're loading
        // the external content
        iconDisplay.clearOnLoad = (iconPlaceholder == null);

        if (iconDelay > 0)
        {
            // set what we're gonna load and start the timer
            iconSourceToLoad = source;
            
            if (!iconSetterDelayTimer)
            {
                iconSetterDelayTimer = new Timer(iconDelay, 1);
                iconSetterDelayTimer.addEventListener(TimerEvent.TIMER_COMPLETE, iconSetterDelayTimer_timerCompleteHandler);
            }
            
            iconSetterDelayTimer.start();
        }
        else // iconDelay == 0
        {
            // load up the image immediately
            
            // need to call validateProperties because we need this iconPlaceholder
            // to actually get loaded up since we set iconDisplay.source to a remote 
            // image on the next line.  BitmapImage doesn't actually attempt to load 
            // up the image (even if it's a locally embedded asset) until commitProperties()
            iconDisplay.validateProperties();
            
            iconDisplay.source = source;
        }
    }
    
    /**
     *  @private
     */
    private function stopLoadingExternalImage():void
    {
        // stop any asynch operation:
        if (iconSetterDelayTimer)
        {
            iconSourceToLoad = null
            iconSetterDelayTimer.stop();
            iconSetterDelayTimer.reset();
        }
    }
    
    /**
     *  @private
     */
    private function setIconDisplaySource(source:Object):void
    {
        var iconDelay:Number = getStyle("iconDelay");
        
        // if not a string or URL request (or null), load it up immediately
        var isExternalSource:Boolean = (source is String || source is URLRequest);
        if (!isExternalSource)
        {
            // get the icon source to find out if it is external or not
            if (source is MultiDPIBitmapSource)
            {
                var multiSource:Object = MultiDPIBitmapSource(source).getMultiSource();  
                isExternalSource = (multiSource is String || multiSource is URLRequest);
            }
        }        
        
        // if null or embedded asset do it synchronously
        if (!isExternalSource)
        {
            stopLoadingExternalImage();

            // load it up
            iconDisplay.source = source;
            
            return;
        }
        
        // if it's the same source, don't cancel this load--let it continue 
        if (iconSourceToLoad == source)
            return;
        
        // At this point, we know we can cancel the old asynch operation 
        // since we're not going to use it anymore
        stopLoadingExternalImage();
        
        // we know we're loading external content, check the cache first:
        var contentCache:ContentCache = iconContentLoader as ContentCache;
        if (contentCache)
        {
            if (contentCache.getCacheEntry(source))
            {
                // We know we have this item cached (or atleast have attempted 
                // to load this item and cache it).  Because we're not sure whether 
                // this item has finished loading or not, let's set the icon's 
                // source to the placeholder (or null) first so that we can make sure
                // we don't leave in a stale image while the load is still happening.
                iconDisplay.source = iconPlaceholder;
                
                // while we're loading,if iconPlaceholder is set, 
                // we'll keep that image up while we're loading
                // the external content
                iconDisplay.clearOnLoad = (iconPlaceholder == null);
                
                // need to call validateProperties because we need this iconPlaceholder
                // to actually get loaded up since we set iconDisplay.source to a remote 
                // image on the next line.  BitmapImage doesn't actually attempt to load 
                // up the image (even if it's a locally embedded asset) until commitProperties()
                iconDisplay.validateProperties();
                
                // now attempt to load up our other image (or grab it from the cache
                // if the load had finished already)
                iconDisplay.source = source;
                
                return;
            }
        }
        
        // otherwise, we need to load an external asset and use a Timer
        loadExternalImage(source, iconDelay);
    }
    
    /**
     *  @private
     */
    private function iconSetterDelayTimer_timerCompleteHandler(event:TimerEvent):void
    {
        // if we're off-screen, don't do anything
        // when we get re-included, our data will be reset as well
        if (!includeInLayout)
        {
            iconSourceToLoad = null;
            return;
        }
        
        if (iconDisplay)
            iconDisplay.source = iconSourceToLoad;
        
        iconSourceToLoad = null;
    }
    
    /**
     *  @private
     */
    override public function validateSize(recursive:Boolean = false):void
    {
        // Since IGraphicElement is not ILayoutManagerClient, we need to make sure we
        // validate sizes of the elements, even in cases where recursive==false.
        
        // Validate element size
        if (iconNeedsValidateSize)
        {
            iconNeedsValidateSize = false;
            if (iconDisplay)
                iconDisplay.validateSize();
        }
        
        if (decoratorNeedsValidateSize)
        {
            decoratorNeedsValidateSize = false;
            if (decoratorDisplay)
                decoratorDisplay.validateSize();
        }
        
        super.validateSize(recursive);
    }
        
    /**
     *  @private
     */
    override protected function measure():void
    {
        // don't call super.measure() because there's no need to do the work that's
        // in there--we do it all in here.
        //super.measure();
        
        // start them at 0, then go through icon, label, and decorator
        // and add to these
        var myMeasuredWidth:Number = 0;
        var myMeasuredHeight:Number = 0;
        var myMeasuredMinWidth:Number = 0;
        var myMeasuredMinHeight:Number = 0;
        
        // calculate padding and horizontal gap
        // verticalGap is already handled above when there's a label
        // and a message since that's the only place verticalGap matters.
        // if we handled verticalGap here, it might add it to the icon if 
        // the icon was the tallest item.
        var numHorizontalSections:int = 0;
        if (iconDisplay)
            numHorizontalSections++;
        
        if (decoratorDisplay)
            numHorizontalSections++;
        
        if (labelDisplay || messageDisplay)
            numHorizontalSections++;
        
        var paddingAndGapWidth:Number = getStyle("paddingLeft") + getStyle("paddingRight");
        if (numHorizontalSections > 0)
            paddingAndGapWidth += (getStyle("horizontalGap") * (numHorizontalSections - 1));
        
        var hasLabel:Boolean = labelDisplay && labelDisplay.text != "";
        var hasMessage:Boolean = messageDisplay && messageDisplay.text != "";

        var verticalGap:Number = (hasLabel && hasMessage) ? getStyle("verticalGap") : 0;
        var paddingHeight:Number = getStyle("paddingTop") + getStyle("paddingBottom");
        
        // Icon is on left
        var myIconWidth:Number = 0;
        var myIconHeight:Number = 0;
        if (iconDisplay)
        {
            myIconWidth = (isNaN(iconWidth) ? getElementPreferredWidth(iconDisplay) : iconWidth);
            myIconHeight = (isNaN(iconHeight) ? getElementPreferredHeight(iconDisplay) : iconHeight);
            
            myMeasuredWidth += myIconWidth;
            myMeasuredMinWidth += myIconWidth;
            myMeasuredHeight = Math.max(myMeasuredHeight, myIconHeight);
            myMeasuredMinHeight = Math.max(myMeasuredMinHeight, myIconHeight);
        }
        
        // Decorator is up next
        var decoratorWidth:Number = 0;
        var decoratorHeight:Number = 0;
        
        if (decoratorDisplay)
        {
            decoratorWidth = getElementPreferredWidth(decoratorDisplay);
            decoratorHeight = getElementPreferredHeight(decoratorDisplay);
            
            myMeasuredWidth += decoratorWidth;
            myMeasuredMinWidth += decoratorWidth;
            myMeasuredHeight = Math.max(myMeasuredHeight, decoratorHeight);
            myMeasuredMinHeight = Math.max(myMeasuredHeight, decoratorHeight);
        }
        
        // Text is aligned next to icon
        var labelWidth:Number = 0;
        var labelHeight:Number = 0;
        var messageWidth:Number = 0;
        var messageHeight:Number = 0;
        
        if (hasLabel)
        {
            // reset text if it was truncated before.
            if (labelDisplay.isTruncated)
                labelDisplay.text = labelText;
            
            labelWidth = getElementPreferredWidth(labelDisplay);
            labelHeight = getElementPreferredHeight(labelDisplay);
        }
        
        if (hasMessage)
        {
            // now we need to measure messageDisplay's height.  Unfortunately, this is tricky and 
            // is dependent on messageDisplay's width.  
            // Use the old unscaledWidth width as an estimte for the new one.  
            // If we are wrong, we'll find out in updateDisplayList()
            
            var messageDisplayEstimatedWidth:Number = oldUnscaledWidth - paddingAndGapWidth - myIconWidth - decoratorWidth;
            
            setElementSize(messageDisplay, messageDisplayEstimatedWidth, NaN);
            
            messageWidth = getElementPreferredWidth(messageDisplay);
            messageHeight = getElementPreferredHeight(messageDisplay);
        }
        
        myMeasuredWidth += Math.max(labelWidth, messageWidth);
        myMeasuredHeight = Math.max(myMeasuredHeight, labelHeight + messageHeight + verticalGap);
        
        myMeasuredWidth += paddingAndGapWidth;
        myMeasuredMinWidth += paddingAndGapWidth;
        
        // verticalGap handled in label and message
        myMeasuredHeight += paddingHeight;
        myMeasuredMinHeight += paddingHeight;
        
        // now set the local variables to the member variables.
        measuredWidth = myMeasuredWidth
        measuredHeight = myMeasuredHeight;
        
        measuredMinWidth = myMeasuredMinWidth;
        measuredMinHeight = myMeasuredMinHeight;
    }
    
    /**
     *  @private
     *  If we invalidate display list, we need to redraw any graphic elements sharing 
     *  our display object since we call graphics.clear() in super.updateDisplayList()
     */
    override public function invalidateDisplayList():void
    {
        redrawRequested = true;
        super.invalidateDisplayList();
    }
    
    /**
     *  @private
     */
    override public function validateDisplayList():void
    {
        super.validateDisplayList();
        
        // Since IGraphicElement is not ILayoutManagerClient, we need to make sure we
        // validate properties of the elements
        
        // see if we have an icon that needs to be validated
        if (iconDisplay && 
            iconDisplay.displayObject is ISharedDisplayObject && 
            ISharedDisplayObject(iconDisplay.displayObject).redrawRequested)
        {
            ISharedDisplayObject(iconDisplay.displayObject).redrawRequested = false;
            iconDisplay.validateDisplayList();
            // if decoratorDisplay is also using this displayObject than validate
            // decoratorDisplay as well
            if (decoratorDisplay && 
                decoratorDisplay.displayObject is ISharedDisplayObject && 
                decoratorDisplay.displayObject == iconDisplay.displayObject)
                decoratorDisplay.validateDisplayList();
        }
        
        // check just for decoratorDisplay in case it has a different displayObject
        // than iconDisplay
        if (decoratorDisplay && 
            decoratorDisplay.displayObject is ISharedDisplayObject && 
            ISharedDisplayObject(decoratorDisplay.displayObject).redrawRequested)
        {
            ISharedDisplayObject(decoratorDisplay.displayObject).redrawRequested = false;
            decoratorDisplay.validateDisplayList();
        }
    }
    
    /**
     *  @private
     */
    override protected function layoutContents(unscaledWidth:Number,
                                               unscaledHeight:Number):void
    {
        // no need to call super.layoutContents() since we're changing how it happens here
        
        // start laying out our children now
        var iconWidth:Number = 0;
        var iconHeight:Number = 0;
        var decoratorWidth:Number = 0;
        var decoratorHeight:Number = 0;

        var hasLabel:Boolean = labelDisplay && labelDisplay.text != "";
        var hasMessage:Boolean = messageDisplay && messageDisplay.text != "";

        var paddingLeft:Number   = getStyle("paddingLeft");
        var paddingRight:Number  = getStyle("paddingRight");
        var paddingTop:Number    = getStyle("paddingTop");
        var paddingBottom:Number = getStyle("paddingBottom");
        var horizontalGap:Number = getStyle("horizontalGap");
        var verticalAlign:String = getStyle("verticalAlign");
        var verticalGap:Number   = (hasLabel && hasMessage) ? getStyle("verticalGap") : 0;

        var vAlign:Number;
        if (verticalAlign == "top")
            vAlign = 0;
        else if (verticalAlign == "bottom")
            vAlign = 1;
        else // if (verticalAlign == "middle")
            vAlign = 0.5;
        // made "middle" last even though it's most likely so it is the default and if someone 
        // types "center", then it will still vertically center itself.

        var viewWidth:Number  = unscaledWidth  - paddingLeft - paddingRight;
        var viewHeight:Number = unscaledHeight - paddingTop  - paddingBottom;
        
        // icon is on the left
        if (iconDisplay)
        {
            // set the icon's position and size
            setElementSize(iconDisplay, this.iconWidth, this.iconHeight);
            
            iconWidth = iconDisplay.getLayoutBoundsWidth();
            iconHeight = iconDisplay.getLayoutBoundsHeight();
            
            // use vAlign to position the icon.
            var iconDisplayY:Number = Math.round(vAlign * (viewHeight - iconHeight)) + paddingTop;
            setElementPosition(iconDisplay, paddingLeft, iconDisplayY);
        }
        
        // decorator is aligned next to icon
        if (decoratorDisplay)
        {
            decoratorWidth = getElementPreferredWidth(decoratorDisplay);
            decoratorHeight = getElementPreferredHeight(decoratorDisplay);

            setElementSize(decoratorDisplay, decoratorWidth, decoratorHeight);

            // decorator is always right aligned, vertically centered
            var decoratorY:Number = Math.round(0.5 * (viewHeight - decoratorHeight)) + paddingTop;
            setElementPosition(decoratorDisplay, unscaledWidth - paddingRight - decoratorWidth, decoratorY);
        }

        // Figure out how much space we have for label and message as well as the 
        // starting left position
        var labelComponentsViewWidth:Number = viewWidth - iconWidth - decoratorWidth;
        
        // don't forget the extra gap padding if these elements exist
        if (iconDisplay)
            labelComponentsViewWidth -= horizontalGap;
        if (decoratorDisplay)
            labelComponentsViewWidth -= horizontalGap;
        
        var labelComponentsX:Number = paddingLeft;
        if (iconDisplay)
            labelComponentsX += iconWidth + horizontalGap;
        
        // calculte the natural height for the label
        var labelTextHeight:Number = 0;
        
        if (hasLabel)
        {
            // reset text if it was truncated before.
            if (labelDisplay.isTruncated)
                labelDisplay.text = labelText;
            
            // commit styles to make sure it uses updated look
            labelDisplay.commitStyles();
            
            labelTextHeight = getElementPreferredHeight(labelDisplay);
        }
        
        if (hasMessage)
        {
            // commit styles to make sure it uses updated look
            messageDisplay.commitStyles();
        }

        // now size and position the elements, 3 different configurations we care about:
        // 1) label and message
        // 2) label only
        // 3) message only

        // label display goes on top
        // message display goes below

        var labelWidth:Number = 0;
        var labelHeight:Number = 0;
        var messageWidth:Number = 0;
        var messageHeight:Number = 0;

        if (hasLabel)
        {
            // handle labelDisplay.  it can only be 1 line
            
            // width of label takes up rest of space
            // height only takes up what it needs so we can properly place the message
            // and make sure verticalAlign is operating on a correct value.
            labelWidth = Math.max(labelComponentsViewWidth, 0);
            labelHeight = labelTextHeight;

            if (labelWidth == 0)
                setElementSize(labelDisplay, NaN, 0);
            else
                setElementSize(labelDisplay, labelWidth, labelHeight);
            
            // attempt to truncate text
            labelDisplay.truncateToFit();
        }

        if (hasMessage)
        {
            // handle message...because the text is multi-line, measuring and layout 
            // can be somewhat tricky
            messageWidth = Math.max(labelComponentsViewWidth, 0);
            
            // We get called with unscaledWidth = 0 a few times...
            // rather than deal with this case normally, 
            // we can just special-case it later to do something smarter
            if (messageWidth == 0)
            {
                // if unscaledWidth is 0, we want to make sure messageDisplay is invisible.
                // we could set messageDisplay's width to 0, but that would cause an extra 
                // layout pass because of the text reflow logic.  Because of that, we 
                // can just set its height to 0.
                setElementSize(messageDisplay, NaN, 0);
            }
            else
            {
                // grab old textDisplay height before resizing it
                var oldPreferredMessageHeight:Number = getElementPreferredHeight(messageDisplay);
                
                // keep track of oldUnscaledWidth so we have a good guess as to the width 
                // of the messageDisplay on the next measure() pass
                oldUnscaledWidth = unscaledWidth;
                
                // set the width of messageDisplay to messageWidth.
                // set the height to oldMessageHeight.  If the height's actually wrong, 
                // we'll invalidateSize() and go through this layout pass again anyways
                setElementSize(messageDisplay, messageWidth, oldPreferredMessageHeight);
                
                // grab new messageDisplay height after the messageDisplay has taken its final width
                var newPreferredMessageHeight:Number = getElementPreferredHeight(messageDisplay);
                
                // if the resize caused the messageDisplay's height to change (because of 
                // text reflow), then we need to remeasure ourselves with our new width
                if (oldPreferredMessageHeight != newPreferredMessageHeight)
                    invalidateSize();
    
                messageHeight = newPreferredMessageHeight;
            }
            
            // since it's multi-line, no need to truncate
            //if (messageDisplay.isTruncated)
            //    messageDisplay.text = messageText;
            //messageDisplay.truncateToFit();
        }
        else
        {
            if (messageDisplay)
                setElementSize(messageDisplay, 0, 0);
        }
        
        // Position the text components now that we know all heights so we can respect verticalAlign style
        var totalHeight:Number = 0;
        var labelComponentsY:Number = 0; 

        // Heights used in our alignment calculations.  We only care about the "real" ascent 
        var labelAlignmentHeight:Number = 0; 
        var messageAlignmentHeight:Number = 0; 
        
        if (hasLabel)
            labelAlignmentHeight = getElementPreferredHeight(labelDisplay);
        if (hasMessage)
            messageAlignmentHeight = getElementPreferredHeight(messageDisplay);

        totalHeight = labelAlignmentHeight + messageAlignmentHeight + verticalGap;          
        labelComponentsY = Math.round(vAlign * (viewHeight - totalHeight)) + paddingTop;

        if (labelDisplay)
            setElementPosition(labelDisplay, labelComponentsX, labelComponentsY);
        
        if (messageDisplay)
        {
            var messageY:Number = labelComponentsY + labelAlignmentHeight + verticalGap;
            setElementPosition(messageDisplay, labelComponentsX, messageY);
        }
    }
    
}
    
}