////////////////////////////////////////////////////////////////////////////////
//
//  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.layouts
{
import flash.events.Event;
import flash.geom.Point;
import flash.geom.Rectangle;

import mx.containers.utilityClasses.Flex;
import mx.core.FlexVersion;
import mx.core.ILayoutElement;
import mx.core.IVisualElement;
import mx.core.mx_internal;
import mx.events.PropertyChangeEvent;

import spark.components.DataGroup;
import spark.components.supportClasses.GroupBase;
import spark.core.NavigationUnit;
import spark.layouts.supportClasses.DropLocation;
import spark.layouts.supportClasses.LayoutBase;
import spark.layouts.supportClasses.LayoutElementHelper;
import spark.layouts.supportClasses.LinearLayoutVector;

use namespace mx_internal;

/**
 *  The HorizontalLayout class arranges the layout elements in a horizontal sequence,
 *  left to right, with optional gaps between the elements and optional padding
 *  around the elements.
 *
 *  <p>The horizontal position of the elements is determined by arranging them
 *  in a horizontal sequence, left to right, taking into account the padding
 *  before the first element and the gaps between the elements.</p>
 *
 *  <p>The vertical position of the elements is determined by the layout's 
 *  <code>verticalAlign</code> property.</p>
 *
 *  <p>During the execution of the <code>measure()</code> method, 
 *  the default size of the container is calculated by
 *  accumulating the preferred sizes of the elements, including gaps and padding.
 *  When the <code>requestedColumnCount</code> property is set to a value other than -1, 
 *  only the space for that many elements
 *  is measured, starting from the first element.</p>
 *
 *  <p>During the execution of the <code>updateDisplayList()</code> method, 
 *  the width of each element is calculated
 *  according to the following rules, listed in their respective order of
 *  precedence (element's minimum width and maximum width are always respected):</p>
 *  <ul>
 *    <li>If <code>variableColumnWidth</code> is <code>false</code>, 
 *    then set the element's width to the
 *    value of the <code>columnWidth</code> property.</li>
 *
 *    <li>If the element's <code>percentWidth</code> is set, then calculate the element's
 *    width by distributing the available container width between all
 *    elements with <code>percentWidth</code> setting. 
 *    The available container width
 *    is equal to the container width minus the gaps, the padding and the
 *    space occupied by the rest of the elements. The element's <code>precentWidth</code>
 *    property is ignored when the layout is virtualized.</li>
 *
 *    <li>Set the element's width to its preferred width.</li>
 *  </ul>
 *
 *  <p>The height of each element is calculated according to the following rules,
 *  listed in their respective order of precedence (element's minimum height and
 *  maximum height are always respected):</p>
 *  <ul>
 *    <li>If the <code>verticalAlign</code> property is <code>"justify"</code>,
 *   then set the element's height to the container height.</li>
 *
 *    <li>If the <code>verticalAlign</code> property is <code>"contentJustify"</code>, 
 *    then set the element's height to the maximum between the container's height 
 *    and all elements' preferred height.</li>
 *
 *    <li>If the element's <code>percentHeight</code> property is set, 
 *    then calculate the element's height as a percentage of the container's height.</li>
 *
 *    <li>Set the element's height to its preferred height.</li>
 *  </ul>
 *
 *  @mxml 
 *  <p>The <code>&lt;s:HorizontalLayout&gt;</code> tag inherits all of the tag 
 *  attributes of its superclass and adds the following tag attributes:</p>
 *
 *  <pre>
 *  &lt;s:HorizontalLayout 
 *    <strong>Properties</strong>
 *    columnWidth="<i>calculated</i>"
 *    gap="6"
 *    paddingBottom="0"
 *    paddingLeft="0"
 *    paddingRight="0"
 *    paddingTop="0"
 *    requestedColumnCount="-1"
 *    requestedMaxColumnCount="-1"
 *    requestedMinColumnCount="-1"
 *    variableColumnWidth="true"
 *    verticalAlign="top"
 *  /&gt;
 *  </pre>
 *
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
public class HorizontalLayout extends LayoutBase
{
    include "../core/Version.as";

    /**
     *  @private
     *  Cached column widths, max row height for virtual layout.   Not used unless
     *  useVirtualLayout=true.   See updateLLV(), resetCachedVirtualLayoutState(),
     *  etc.
     */
    private var llv:LinearLayoutVector;
    
    //--------------------------------------------------------------------------
    //
    //  Class methods
    //
    //--------------------------------------------------------------------------
    
    private static function calculatePercentHeight(layoutElement:ILayoutElement, height:Number):Number
    {
        var percentHeight:Number;
        if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_6)
        {
            percentHeight = LayoutElementHelper.pinBetween(Math.round(layoutElement.percentHeight * 0.01 * height),
                                                           layoutElement.getMinBoundsHeight(),
                                                           layoutElement.getMaxBoundsHeight() );
            return percentHeight < height ? percentHeight : height;
        }
        else
        {
            percentHeight = LayoutElementHelper.pinBetween(Math.min(Math.round(layoutElement.percentHeight * 0.01 * height), height),
                                                           layoutElement.getMinBoundsHeight(),
                                                           layoutElement.getMaxBoundsHeight() );
            return percentHeight;
        }
    }

    private static function sizeLayoutElement(layoutElement:ILayoutElement, height:Number, 
                                              verticalAlign:String, restrictedHeight:Number, 
                                              width:Number, variableColumnWidth:Boolean, 
                                              columnWidth:Number):void
    {
        var newHeight:Number = NaN;
        
        // if verticalAlign is "justify" or "contentJustify", 
        // restrict the height to restrictedHeight.  Otherwise, 
        // size it normally
        if (verticalAlign == VerticalAlign.JUSTIFY ||
            verticalAlign == VerticalAlign.CONTENT_JUSTIFY)
        {
            newHeight = restrictedHeight;
        }
        else
        {
            if (!isNaN(layoutElement.percentHeight))
               newHeight = calculatePercentHeight(layoutElement, height);   
        }
        
        if (variableColumnWidth)
            layoutElement.setLayoutBoundsSize(width, newHeight);
        else
            layoutElement.setLayoutBoundsSize(columnWidth, newHeight);
    }
        
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     *  Constructor. 
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */    
    public function HorizontalLayout():void
    {
        super();

        // Don't drag-scroll in the vertical direction
        dragScrollRegionSizeVertical = 0;
    }
    
    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------
    
    //----------------------------------
    //  alignmentBaseline
    //----------------------------------
    
    /**
     *  @private
     *  Storage for the alignmentBaseline property.
     */
    private var _alignmentBaseline:Object = "maxAscent:0";

    /**
     *  @private
     *
     *  The base line of the layout, in pixels. 
     *
     *  The base line is the virtual horizontal line to which layout elements' text is aligned,
     *  it is relative to the top edge of the container plus any <code>paddingTop</code>.
     *
     *  The base line can be specified as either an explicit number, or as a numberical offset from
     *  the computed maximum of the elements' text ascent by using the "maxAscent:offset" syntax.
     *
     *  Note that <code>alignmentBaseline</code> has an effect only when <code>verticalAlign</code>
     *  is set to "baseline".
     *
     *  @default "maxAscent:0"
     *  @see #verticalAlign 
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    mx_internal function get alignmentBaseline():Object
    {
        return _alignmentBaseline;
    }

    /**
     *  @private
     */
    mx_internal function set alignmentBaseline(value:Object):void
    {
        if (_alignmentBaseline == value) 
            return;
        
        _alignmentBaseline = value;
        invalidateTargetSizeAndDisplayList();
    }

    //----------------------------------
    //  gap
    //----------------------------------

    private var _gap:int = 6;

    [Inspectable(category="General")]

    /**
     *  The horizontal space between layout elements, in pixels.
     * 
     *  Note that the gap is only applied between layout elements, so if there's
     *  just one element, the gap has no effect on the layout.
     * 
     *  @default 6
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */    
    public function get gap():int
    {
        return _gap;
    }

    /**
     *  @private
     */
    public function set gap(value:int):void
    {
        if (_gap == value) 
            return;
    
        _gap = value;
        invalidateTargetSizeAndDisplayList();
    }
    
    //----------------------------------
    //  columnCount
    //----------------------------------

    private var _columnCount:int = -1;
    
    [Bindable("propertyChange")]
    [Inspectable(category="General")]

    /**
     *  Returns the current number of elements in view.
     * 
     *  @default -1
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get columnCount():int
    {
        return _columnCount;
    }

    /**
     *  @private
     * 
     *  Sets the <code>columnCount</code> property and dispatches
     *  a PropertyChangeEvent.
     */
    private function setColumnCount(value:int):void
    {
        if (_columnCount == value)
            return;
        var oldValue:int = _columnCount;
        _columnCount = value;
        dispatchEvent(PropertyChangeEvent.createUpdateEvent(this, "columnCount", oldValue, value));
    }
        
    //----------------------------------
    //  paddingLeft
    //----------------------------------

    private var _paddingLeft:Number = 0;
    
    [Inspectable(category="General")]

    /**
     *  Number of pixels between the container's left edge
     *  and the left edge of the first layout element.
     * 
     *  @default 0
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get paddingLeft():Number
    {
        return _paddingLeft;
    }

    /**
     *  @private
     */
    public function set paddingLeft(value:Number):void
    {
        if (_paddingLeft == value)
            return;
                               
        _paddingLeft = value;
        invalidateTargetSizeAndDisplayList();
    }    
    
    //----------------------------------
    //  paddingRight
    //----------------------------------

    private var _paddingRight:Number = 0;
    
    [Inspectable(category="General")]

    /**
     *  Number of pixels between the container's right edge
     *  and the right edge of the last layout element.
     * 
     *  @default 0
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get paddingRight():Number
    {
        return _paddingRight;
    }

    /**
     *  @private
     */
    public function set paddingRight(value:Number):void
    {
        if (_paddingRight == value)
            return;
                               
        _paddingRight = value;
        invalidateTargetSizeAndDisplayList();
    }    
    
    //----------------------------------
    //  paddingTop
    //----------------------------------

    private var _paddingTop:Number = 0;
    
    [Inspectable(category="General")]

    /**
     *  The minimum number of pixels between the container's top edge and
     *  the top of all the container's layout elements. 
     * 
     *  @default 0
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get paddingTop():Number
    {
        return _paddingTop;
    }

    /**
     *  @private
     */
    public function set paddingTop(value:Number):void
    {
        if (_paddingTop == value)
            return;
                               
        _paddingTop = value;
        invalidateTargetSizeAndDisplayList();
    }    
    
    //----------------------------------
    //  paddingBottom
    //----------------------------------

    private var _paddingBottom:Number = 0;
    
    [Inspectable(category="General")]

    /**
     *  The minimum number of pixels between the container's bottom edge and
     *  the bottom of all the container's layout elements. 
     * 
     *  @default 0
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get paddingBottom():Number
    {
        return _paddingBottom;
    }

    /**
     *  @private
     */
    public function set paddingBottom(value:Number):void
    {
        if (_paddingBottom == value)
            return;
                               
        _paddingBottom = value;
        invalidateTargetSizeAndDisplayList();
    }    

    //----------------------------------
    //  requestedMaxColumnCount
    //----------------------------------
    
    private var _requestedMaxColumnCount:int = -1;
    
    [Inspectable(category="General", minValue="-1")]
    
    /**
     *  The measured width of this layout is large enough to display 
     *  at most <code>requestedMaxColumnCount</code> layout elements. 
     * 
     *  <p>If <code>requestedColumnCount</code> is set, then
     *  this property has no effect.</p>
     *
     *  <p>If the actual size of the container using this layout has been explicitly set,
     *  then this property has no effect.</p>
     * 
     *  @default -1
     *  @see #requestedColumnCount
     *  @see #requestedMinColumnCount
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function get requestedMaxColumnCount():int
    {
        return _requestedMaxColumnCount;
    }
    
    /**
     *  @private
     */
    public function set requestedMaxColumnCount(value:int):void
    {
        if (_requestedMaxColumnCount == value)
            return;
        
        _requestedMaxColumnCount = value;
        
        if (target)
            target.invalidateSize();
    }   
    
    //----------------------------------
    //  requestedMinColumnCount
    //----------------------------------
    
    private var _requestedMinColumnCount:int = -1;
    
    [Inspectable(category="General", minValue="-1")]
    
    /**
     *  The measured width of this layout is large enough to display 
     *  at least <code>requestedMinColumnCount</code> layout elements. 
     * 
     *  <p>If <code>requestedColumnCount</code> is set, then
     *  this property has no effect.</p>
     *
     *  <p>If the actual size of the container using this layout has been explicitly set,
     *  then this property has no effect.</p>
     * 
     *  @default -1
     *  @see #requestedColumnCount
     *  @see #requestedMaxColumnCount
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function get requestedMinColumnCount():int
    {
        return _requestedMinColumnCount;
    }

    /**
     *  @private
     */
    public function set requestedMinColumnCount(value:int):void
    {
        if (_requestedMinColumnCount == value)
            return;

        _requestedMinColumnCount = value;

        if (target)
            target.invalidateSize();
    }   

    //----------------------------------
    //  requestedColumnCount
    //----------------------------------

    private var _requestedColumnCount:int = -1;
    
    [Inspectable(category="General", minValue="-1")]

    /**
     *  The measured size of this layout is wide enough to display 
     *  the first <code>requestedColumnCount</code> layout elements. 
     *  If <code>requestedColumnCount</code> is -1, then the measured
     *  size will be big enough for all of the layout elements.
     * 
     *  <p>If the actual size of the container using this layout has been explicitly set,
     *  then this property has no effect.</p>
     * 
     *  @default -1
     *  @see #requestedMinColumnCount
     *  @see #requestedMaxColumnCount
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get requestedColumnCount():int
    {
        return _requestedColumnCount;
    }

    /**
     *  @private
     */
    public function set requestedColumnCount(value:int):void
    {
        if (_requestedColumnCount == value)
            return;
                               
        _requestedColumnCount = value;
        
        if (target)
            target.invalidateSize();
    }    
    
    //----------------------------------
    //  columnWidth
    //----------------------------------
    
    private var _columnWidth:Number;

    [Inspectable(category="General", minValue="0.0")]

    /**
     *  If the <code>variableColumnWidth</code> property is <code>false</code>, 
     *  then this property specifies the actual width of each layout element, in pixels.
     * 
     *  <p>If the <code>variableColumnWidth</code> property is <code>true</code>, 
     *  the default, then this property has no effect.</p>
     * 
     *  <p>The default value of this property is the preferred width
     *  of the item specified by the <code>typicalLayoutElement</code> property.</p>
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get columnWidth():Number
    {
        if (!isNaN(_columnWidth))
            return _columnWidth;
        else 
        {
            var elt:ILayoutElement = typicalLayoutElement
            return (elt) ? elt.getPreferredBoundsWidth() : 0;
        }
    }

    /**
     *  @private
     */
    public function set columnWidth(value:Number):void
    {
        if (_columnWidth == value)
            return;
            
        _columnWidth = value;
        invalidateTargetSizeAndDisplayList();
    }

    //----------------------------------
    //  variableColumnWidth
    //----------------------------------

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

    [Inspectable(category="General", enumeration="true,false")]

    /**
     *  If <code>true</code>, specifies that layout elements are to be allocated their
     *  preferred width.
     *
     *  <p>Setting this property to <code>false</code> specifies fixed width columns.
     *  The actual width of each layout element is 
     *  the value of the <code>columnWidth</code> property, and the layout ignores  
     *  a layout elements' <code>percentWidth</code> property.</p>
     * 
     *  @default true
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get variableColumnWidth():Boolean
    {
        return _variableColumnWidth;
    }

    /**
     *  @private
     */
    public function set variableColumnWidth(value:Boolean):void
    {
        if (value == _variableColumnWidth) return;
        
        _variableColumnWidth = value;
        invalidateTargetSizeAndDisplayList();
    }
    
    //----------------------------------
    //  firstIndexInView
    //----------------------------------

    /**
     *  @private
     */
    private var _firstIndexInView:int = -1;

    [Inspectable(category="General")]
    [Bindable("indexInViewChanged")]    

    /**
     *  The index of the first column that is part of the layout and within
     *  the layout target's scroll rectangle, or -1 if nothing has been displayed yet.
     * 
     *  Note that the column may only be partially in view.
     * 
     *  @see lastIndexInView
     *  @see fractionOfElementInView
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get firstIndexInView():int
    {
        return _firstIndexInView;
    }
    
    
    //----------------------------------
    //  lastIndexInView
    //----------------------------------

    /**
     *  @private
     */
    private var _lastIndexInView:int = -1;
    
    [Inspectable(category="General")]
    [Bindable("indexInViewChanged")]    

    /**
     *  The index of the last column that is part of the layout and within
     *  the layout target's scroll rectangle, or -1 if nothing has been displayed yet.
     * 
     *  Note that the column may only be partially in view.
     * 
     *  @see firstIndexInView
     *  @see fractionOfElementInView
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get lastIndexInView():int
    {
        return _lastIndexInView;
    }
    
    //----------------------------------
    //  horizontalAlign
    //----------------------------------
    
    /**
     *  @private
     */
    private var _horizontalAlign:String = HorizontalAlign.LEFT;
    
    [Inspectable(category="General", enumeration="left,right,center", defaultValue="left")]
    
    /** 
     *  The horizontal alignment of the content relative to the container's width.
     *  If the value is <code>"left"</code>, <code>"right"</code>, or <code>"center"</code> then the 
     *  layout element is aligned relative to the container's <code>contentWidth</code> property.
     *
     *  <p>This property has no effect when <code>clipAndEnableScrolling</code> is true
     *  and the <code>contentWidth</code> is greater than the container's width.</p>
     *
     *  <p>This property does not affect the layout's measured size.</p>
     *  
     *  @default "left"
     *  
     *  @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;
        
        var layoutTarget:GroupBase = target;
        if (layoutTarget)
            layoutTarget.invalidateDisplayList();
    }
    
    //----------------------------------
    //  verticalAlign
    //----------------------------------

    /**
     *  @private
     */
    private var _verticalAlign:String = VerticalAlign.TOP;

    [Inspectable(category="General", enumeration="top,bottom,middle,justify,contentJustify,baseline", defaultValue="top")]

    /** 
     *  The vertical alignment of layout elements.
     * 
     *  <p>If the value is <code>"bottom"</code>, <code>"middle"</code>, 
     *  or <code>"top"</code> then the layout elements are aligned relative 
     *  to the container's <code>contentHeight</code> property.</p>
     * 
     *  <p>If the value is <code>"contentJustify"</code> then the actual
     *  height of the layout element is set to 
     *  the container's <code>contentHeight</code> property. 
     *  The content height of the container is the height of the largest layout element. 
     *  If all layout elements are smaller than the height of the container, 
     *  then set the height of all the layout elements to the height of the container.</p>
     * 
     *  <p>If the value is <code>"justify"</code> then the actual height
     *  of the layout elements is set to the container's height.</p>
     *
     *  <p>If the value is <code>"baseline"</code> then the elements are positioned
     *  such that their text is aligned to the maximum of the elements' text ascent.</p>
     * 
     *  @default "top"
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get verticalAlign():String
    {
        return _verticalAlign;
    }

    /**
     *  @private
     */
    public function set verticalAlign(value:String):void
    {
        if (value == _verticalAlign) 
            return;

        var oldValue:String = _verticalAlign;
        _verticalAlign = value;

        // "baseline" affects the measured size
        if (oldValue == VerticalAlign.BASELINE ||
            value    == VerticalAlign.BASELINE)
        {
            invalidateTargetSizeAndDisplayList();
        }
        else
        {
            var layoutTarget:GroupBase = target;
            if (layoutTarget)
                layoutTarget.invalidateDisplayList();
        }
    }

    /**
     *  @private
     * 
     *  Sets the <code>firstIndexInView</code> and <code>lastIndexInView</code>
     *  properties and dispatches a <code>"indexInViewChanged"</code>
     *  event.  
     * 
     *  @param firstIndex The new value for firstIndexInView.
     *  @param lastIndex The new value for lastIndexInView.
     * 
     *  @see firstIndexInView
     *  @see lastIndexInview
     */
    private function setIndexInView(firstIndex:int, lastIndex:int):void
    {
        if ((_firstIndexInView == firstIndex) && (_lastIndexInView == lastIndex))
            return;
            
        _firstIndexInView = firstIndex;
        _lastIndexInView = lastIndex;
        dispatchEvent(new Event("indexInViewChanged"));
    }
    
    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    override public function set clipAndEnableScrolling(value:Boolean):void
    {
        super.clipAndEnableScrolling = value;
        var hAlign:String = horizontalAlign;
        if (hAlign == HorizontalAlign.CENTER || hAlign == HorizontalAlign.RIGHT)
        {
            var g:GroupBase = target;
            if (g)
                g.invalidateDisplayList();
        }
    }

    /**
     * @private
     */
    override public function clearVirtualLayoutCache():void
    {
        llv = null;

        var g:GroupBase = GroupBase(target);
        if (!g)
            return;
        
        target.invalidateSize();
        target.invalidateDisplayList();
    }     

    /**
     *  @private
     */
    override public function getElementBounds(index:int):Rectangle
    {
        if (!useVirtualLayout)
            return super.getElementBounds(index);

        var g:GroupBase = GroupBase(target);
        if (!g || (index < 0) || (index >= g.numElements) || !llv) 
            return null;

		// We need a valid LLV for this function
		updateLLV(g);
		
        return llv.getBounds(index);
    }    
    
    /**
     *  Returns 1.0 if the specified index is completely in view, 0.0 if
     *  it's not, or a value between 0.0 and 1.0 that represents the percentage 
     *  of the if the index that is partially in view.
     * 
     *  <p>An index is "in view" if the corresponding non-null layout element is 
     *  within the horizontal limits of the container's <code>scrollRect</code>
     *  and included in the layout.</p>
     *  
     *  <p>If the specified index is partially within the view, the 
     *  returned value is the percentage of the corresponding
     *  layout element that's visible.</p>
     *
     *  @param index The index of the column.
     * 
     *  @return The percentage of the specified element that's in view.
     *  Returns 0.0 if the specified index is invalid or if it corresponds to
     *  null element, or a ILayoutElement for which 
     *  the <code>includeInLayout</code> property is <code>false</code>.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function fractionOfElementInView(index:int):Number
    {
        var g:GroupBase = target;
        if (!g)
            return 0.0;
                
        if ((index < 0) || (index >= g.numElements))
            return 0.0;
               
        if (!clipAndEnableScrolling)
            return 1.0;
               
        var r0:int = firstIndexInView;  
        var r1:int = lastIndexInView;
        
        // index is outside the "in view" or visible range
        if ((r0 == -1) || (r1 == -1) || (index < r0) || (index > r1))
            return 0.0;

        // within the visible index range, but not first or last            
        if ((index > r0) && (index < r1))
            return 1.0;

        // get the layout element's X and Width
        var eltX:Number;
        var eltWidth:Number;
        if (useVirtualLayout)
        {
            if (!llv)
                return 0.0;
            eltX = llv.start(index);
            eltWidth = llv.getMajorSize(index);
        }
        else 
        {
            var elt:ILayoutElement = g.getElementAt(index);
            if (!elt || !elt.includeInLayout)
                return 0.0;
            eltX = elt.getLayoutBoundsX();
            eltWidth = elt.getLayoutBoundsWidth();
        }
            
        // index is either the first or last column in the scrollRect
        // and potentially partially visible.
        //   x0,x1 - scrollRect left,right edges
        //   ix0, ix1 - layout element left,right edges
        var x0:Number = g.horizontalScrollPosition; 
        var x1:Number = x0 + g.width;
        var ix0:Number = eltX;
        var ix1:Number = ix0 + eltWidth;
        if (ix0 >= ix1)  // element has 0 or negative height
            return 1.0;
        if ((ix0 >= x0) && (ix1 <= x1))
            return 1.0;
        return (Math.min(x1, ix1) - Math.max(x0, ix0)) / (ix1 - ix0);
    }

    /**
     *  @private
     * 
     *  Binary search for the first layout element that contains y.  
     * 
     *  This function considers both the element's actual bounds and 
     *  the gap that follows it to be part of the element.  The search 
     *  covers index i0 through i1 (inclusive).
     * 
     *  This function is intended for variable height elements.
     * 
     *  Returns the index of the element that contains x, or -1.
     */
    private static function findIndexAt(x:Number, gap:int, g:GroupBase, i0:int, i1:int):int
    {
        var index:int = (i0 + i1) / 2;
        var element:ILayoutElement = g.getElementAt(index);        
        var elementX:Number = element.getLayoutBoundsX();
        // TBD: deal with null element, includeInLayout false.
        if ((x >= elementX) && (x < elementX + element.getLayoutBoundsWidth() + gap))
            return index;
        else if (i0 == i1)
            return -1;
        else if (x < elementX)
            return findIndexAt(x, gap, g, i0, Math.max(i0, index-1));
        else 
            return findIndexAt(x, gap, g, Math.min(index+1, i1), i1);
    }  
    
    /**
     *  @private
     * 
     *  Returns the index of the first non-null includeInLayout element, 
     *  beginning with the element at index i.  
     * 
     *  Returns -1 if no such element can be found.
     */
    private static function findLayoutElementIndex(g:GroupBase, i:int, dir:int):int
    {
        var n:int = g.numElements;
        while((i >= 0) && (i < n))
        {
           var element:ILayoutElement = g.getElementAt(i);
           if (element && element.includeInLayout)
           {
               return i;      
           }
           i += dir;
        }
        return -1;
    } 
    
    /**
     *  @private
     * 
     *  Updates the first,lastIndexInView properties per the new
     *  scroll position.
     *  
     *  @see setIndexInView
     */
    override protected function scrollPositionChanged():void
    {
        super.scrollPositionChanged();
        
        var g:GroupBase = target;
        if (!g)
            return;     

        var n:int = g.numElements - 1;
        if (n < 0) 
        {
            setIndexInView(-1, -1);
            return;
        }
        
        var scrollR:Rectangle = getScrollRect();
        if (!scrollR)
        {
            setIndexInView(0, n);
            return;    
        }
        
        // We're going to use findIndexAt to find the index of 
        // the elements that overlap the left and right edges of the scrollRect.
        // Values that are exactly equal to scrollRect.right aren't actually
        // rendered, since the left,right interval is only half open.
        // To account for that we back away from the right edge by a
        // hopefully infinitesimal amount.
     
        var x0:Number = scrollR.left;
        var x1:Number = scrollR.right - .0001;
        if (x1 <= x0)
        {
            setIndexInView(-1, -1);
            return;
        }

        if (useVirtualLayout && !llv)
        {
            setIndexInView(-1, -1);
            return;
        }

        var i0:int;
        var i1:int;
        if (useVirtualLayout)
        {
            i0 = llv.indexOf(x0);
            i1 = llv.indexOf(x1);
        }
        else
        {
            i0 = findIndexAt(x0 + gap, gap, g, 0, n);
            i1 = findIndexAt(x1, gap, g, 0, n);
        }

        // Special case: no element overlaps x0, is index 0 visible?
        if (i0 == -1)
        {   
            var index0:int = findLayoutElementIndex(g, 0, +1);
            if (index0 != -1)
            {
                var element0:ILayoutElement = g.getElementAt(index0); 
                var element0X:Number = element0.getLayoutBoundsX();
                var element0Width:Number = element0.getLayoutBoundsWidth();                 
                if ((element0X < x1) && ((element0X + element0Width) > x0))
                    i0 = index0;
            }
        }

        // Special case: no element overlaps y1, is index n visible?
        if (i1 == -1)
        {
            var index1:int = findLayoutElementIndex(g, n, -1);
            if (index1 != -1)
            {
                var element1:ILayoutElement = g.getElementAt(index1); 
                var element1X:Number = element1.getLayoutBoundsX();
                var element1Width:Number = element1.getLayoutBoundsWidth();                 
                if ((element1X < x1) && ((element1X + element1Width) > x0))
                    i1 = index1;
            }
        }   

        if (useVirtualLayout)
        {
            var firstElement:ILayoutElement = g.getElementAt(_firstIndexInView);
            var lastElement:ILayoutElement = g.getElementAt(_lastIndexInView);
            var scrollRect:Rectangle = getScrollRect();
            
            /* If the scrollRect is within the bounds of the elements, we do
            not need to call invalidateDisplayList(). This considerably speeds
            up small scrolls. */
            if (!firstElement || !lastElement || 
                scrollRect.left < firstElement.getLayoutBoundsX() || 
                scrollRect.right >= (lastElement.getLayoutBoundsX() + lastElement.getLayoutBoundsWidth()))
            {
                g.invalidateDisplayList();
            }
        }
                
        setIndexInView(i0, i1);
    }

    /**
     *  @private
     * 
     *  Returns the actual position/size Rectangle of the first partially 
     *  visible or not-visible, non-null includeInLayout element, beginning
     *  with the element at index i, searching in direction dir (dir must
     *  be +1 or -1).   The last argument is the GroupBase scrollRect, it's
     *  guaranteed to be non-null.
     * 
     *  Returns null if no such element can be found.
     */
    private function findLayoutElementBounds(g:GroupBase, i:int, dir:int, r:Rectangle):Rectangle
    {
        var n:int = g.numElements;

        if (fractionOfElementInView(i) >= 1)
        {
            // Special case: if we hit the first/last element, 
            // then return the area of the padding so that we
            // can scroll all the way to the start/end.
            i += dir;
            if (i < 0)
                return new Rectangle(0, 0, paddingLeft, 0);
            if (i >= n)
                return new Rectangle(getElementBounds(n-1).right, 0, paddingRight, 0);
        }

        while((i >= 0) && (i < n))
        {
           var elementR:Rectangle = getElementBounds(i);
           // Special case: if the scrollRect r _only_ contains
           // elementR, then if we're searching left (dir == -1),
           // and elementR's left edge is visible, then try again
           // with i-1.   Likewise for dir == +1.
           if (elementR)
           {
               var overlapsLeft:Boolean = (dir == -1) && (elementR.left == r.left) && (elementR.right >= r.right);
               var overlapsRight:Boolean = (dir == +1) && (elementR.right == r.right) && (elementR.left <= r.left);
               if (!(overlapsLeft || overlapsRight))             
                   return elementR;               
           }
           i += dir;
        }
        return null;
    }

    /**
     *  @private 
     */
    override protected function getElementBoundsLeftOfScrollRect(scrollRect:Rectangle):Rectangle
    {
        return findLayoutElementBounds(target, firstIndexInView, -1, scrollRect);
    } 

    /**
     *  @private 
     */
    override protected function getElementBoundsRightOfScrollRect(scrollRect:Rectangle):Rectangle
    {
        return findLayoutElementBounds(target, lastIndexInView, +1, scrollRect);
    } 

    /**
     *  @private
     *  Fills in the result with preferred and min sizes of the element.
     */
    private function getElementWidth(element:ILayoutElement, fixedColumnWidth:Number, result:SizesAndLimit):void
    {
        // Calculate preferred width first, as it's being used to calculate min width
        var elementPreferredWidth:Number = isNaN(fixedColumnWidth) ? Math.ceil(element.getPreferredBoundsWidth()) :
                                                                     fixedColumnWidth;
        // Calculate min width
        var flexibleWidth:Boolean = !isNaN(element.percentWidth);
        var elementMinWidth:Number = flexibleWidth ? Math.ceil(element.getMinBoundsWidth()) : 
                                                     elementPreferredWidth;
        result.preferredSize = elementPreferredWidth;
        result.minSize = elementMinWidth;
    }
    
    /**
     *  @private
     *  Fills in the result with preferred and min sizes of the element.
     */
    private function getElementHeight(element:ILayoutElement, justify:Boolean, result:SizesAndLimit):void
    {
        // Calculate preferred height first, as it's being used to calculate min height below
        var elementPreferredHeight:Number = Math.ceil(element.getPreferredBoundsHeight());
        
        // Calculate min height
        var flexibleHeight:Boolean = !isNaN(element.percentHeight) || justify;
        var elementMinHeight:Number = flexibleHeight ? Math.ceil(element.getMinBoundsHeight()) : 
                                                       elementPreferredHeight;
        result.preferredSize = elementPreferredHeight;
        result.minSize = elementMinHeight;
    }

    /**
     *  @private
     *  Returns [baselineTop, baselineBottom, baselineBottomMin],
     *  where baselineTop is the portion of the elements above the common baseline
     *  and the baselineBottom is the portion of the elements below the common baseline.
     */
    private function calculateBaselineTopBottom(calculateBottom:Boolean):Array
    {
        var baselineOffset:Number = 0;
        var baselineTop:Number = 0;
        var baselineBottom:Number = 0;
        var baselineBottomMin:Number = 0;

        var calculateTop:Boolean;
        var temp:Array = LayoutElementHelper.parseConstraintExp(alignmentBaseline);
        if (temp.length == 2 && temp[1] == "maxAscent")
        {
            baselineOffset = Number(temp[0]);
            calculateTop = true;
        }
        else
        {
            calculateTop = false;
            baselineTop = Number(temp[0]);
            
            // If someone sets the explicit baseline to NaN, then
            // still calculate from the elements
            if (isNaN(baselineTop))
            {
                baselineTop = 0;
                calculateTop = true;
            }
        }

        var count:int = target.numElements;
        for (var i:int = 0; i < count; i++)
        {
            var element:ILayoutElement = target.getElementAt(i);
            if (!element || !element.includeInLayout)
                continue;

            var elementBaseline:Number = element.baseline as Number;
            if (isNaN(elementBaseline))
                elementBaseline = 0;

            var baselinePosition:Number = element.baselinePosition;

            // The portion of the current element that's above the baseline
            var elementBaselineTop:Number = baselinePosition - elementBaseline;

            if (calculateTop)
                baselineTop = Math.max(elementBaselineTop, baselineTop);

            if (calculateBottom)
            {
                // The portion of the current element that's below the baseline
                var elementHeight:Number = element.getPreferredBoundsHeight();
                var elementBaselineBottom:Number = elementHeight - elementBaselineTop;
                
                // Calculate bottom based on min height if the element has flexible height
                var elementBaselineBottomMin:Number = elementBaselineBottom; 
                if (!isNaN(element.percentHeight))
                    elementBaselineBottomMin = element.getMinBoundsHeight() - elementBaselineTop;
    
                baselineBottom = Math.max(elementBaselineBottom, baselineBottom);
            }
        }

        // If ascent was specified, add the offset
        if (calculateTop)
            baselineTop += baselineOffset;

        return [baselineTop, baselineBottom, baselineBottomMin];
    }

    /**
     *  @private
     *  @return columns to measure based on elements in layout and any requested/min/max rowCount settings. 
     */
    private function getColumsToMeasure(numElementsInLayout:int):int
    {
        var columnsToMeasure:int;
        if (requestedColumnCount != -1)
            columnsToMeasure = requestedColumnCount;
        else
        {
            columnsToMeasure = numElementsInLayout;
            if (requestedMaxColumnCount != -1)
                columnsToMeasure = Math.min(requestedMaxColumnCount, columnsToMeasure);
            if (requestedMinColumnCount != -1)
                columnsToMeasure = Math.max(requestedMinColumnCount, columnsToMeasure);
        }
        return columnsToMeasure;
    }
    
    /**
     *  @private
     * 
     *  Compute exact values for measuredWidth,Height and  measuredMinWidth,Height.
     *  
     *  Measure each of the layout elements.  If requestedColumnCount >= 0 we 
     *  consider the height and width of as many layout elements, padding with 
     *  typicalLayoutElement if needed, starting with index 0. We then only 
     *  consider the height of the elements remaining.
     * 
     *  If requestedColumnCount is -1, we consider width/height of each element.
     */
    private function measureReal(layoutTarget:GroupBase):void
    {
        var size:SizesAndLimit          = new SizesAndLimit();
        var alignToBaseline:Boolean     = verticalAlign == VerticalAlign.BASELINE;
        var justify:Boolean             = verticalAlign == VerticalAlign.JUSTIFY;
        var numElements:int             = layoutTarget.numElements;     // How many elements there are in the target
        var numElementsInLayout:int     = numElements;                  // How many elements have includeInLayout == true, start off with numElements.
        var requestedColumnCount:int    = this.requestedColumnCount;
        var columnsMeasured:int         = 0;                            // How many columns have been measured
        
        var preferredHeight:Number      = 0; // sum of the elt preferred heights
        var preferredWidth:Number       = 0; // max of the elt preferred widths
        var minHeight:Number            = 0; // sum of the elt minimum heights
        var minWidth:Number             = 0; // max of the elt minimum widths
        
        var fixedColumnWidth:Number = NaN;
        if (!variableColumnWidth)
            fixedColumnWidth = columnWidth;  // may query typicalLayoutElement, elt at index=0
        
        // Get the numElementsInLayout clamped to requested min/max
        var columnsToMeasure:int = getColumsToMeasure(numElementsInLayout);
        var element:ILayoutElement;
        for (var i:int = 0; i < numElements; i++)
        {
            element = layoutTarget.getElementAt(i);
            if (!element || !element.includeInLayout)
            {
                numElementsInLayout--;
                continue;
            }

            if (!alignToBaseline)
            {
                // Consider the height of each element, inclusive of those outside
                // the requestedColumnCount range.
                getElementHeight(element, justify, size);
                preferredHeight = Math.max(preferredHeight, size.preferredSize);
                minHeight = Math.max(minHeight, size.minSize);
            }
            
            // Can we measure the width of this column?
            if (columnsMeasured < columnsToMeasure)
            {
                getElementWidth(element, fixedColumnWidth, size);
                preferredWidth += size.preferredSize;
                minWidth += size.minSize;
                columnsMeasured++;
            }
        }
        
        // Calculate the total number of columns to measure again, since numElementsInLayout may have changed
        columnsToMeasure = getColumsToMeasure(numElementsInLayout);

        // Do we need to measure more columns?
        if (columnsMeasured < columnsToMeasure)
        {
            // Use the typical element
            element = typicalLayoutElement;
            if (element)
            {
                if (!alignToBaseline)
                {
                    // Height
                    getElementHeight(element, justify, size);
                    preferredHeight = Math.max(preferredHeight, size.preferredSize);
                    minHeight = Math.max(minHeight, size.minSize);
                }
    
                // Width
                getElementWidth(element, fixedColumnWidth, size);
                preferredWidth += size.preferredSize * (columnsToMeasure - columnsMeasured);
                minWidth += size.minSize * (columnsToMeasure - columnsMeasured);
                columnsMeasured = columnsToMeasure;
            }
        }

        if (alignToBaseline)
        {
            var result:Array = calculateBaselineTopBottom(true /*calculateBottom*/);
            var top:Number = result[0];
            var bottom:Number = result[1];
            var bottomMin:Number = result[2];
            
            preferredHeight = Math.ceil(top + bottom);
            minHeight = Math.ceil(top + bottomMin);
        }

        // Add gaps
        if (columnsMeasured > 1)
        { 
            var hgap:Number = gap * (columnsMeasured - 1);
            preferredWidth += hgap;
            minWidth += hgap;
        }
        
        var hPadding:Number = paddingLeft + paddingRight;
        var vPadding:Number = paddingTop + paddingBottom;
        
        layoutTarget.measuredHeight = preferredHeight + vPadding;
        layoutTarget.measuredWidth = preferredWidth + hPadding;
        layoutTarget.measuredMinHeight = minHeight + vPadding;
        layoutTarget.measuredMinWidth  = minWidth + hPadding;
    }

    /**
     *  @private
     * 
     *  Syncs the LinearLayoutVector llv with typicalLayoutElement and
     *  the target's numElements.  Calling this function accounts
     *  for the possibility that the typicalLayoutElement has changed, or
     *  something that its preferred size depends on has changed.
     */
    private function updateLLV(layoutTarget:GroupBase):void
    {
        if (!llv)
        {
            llv = new LinearLayoutVector(LinearLayoutVector.HORIZONTAL)
            // Virtualization defaults for cases
            // where there are no items and no typical item.
            // The llv defaults are the width/height of a Spark Button skin.
            llv.defaultMinorSize = 22;
            llv.defaultMajorSize = 71;
        }

        var typicalElt:ILayoutElement = typicalLayoutElement;
        if (typicalElt)
        {
            var typicalWidth:Number = typicalElt.getPreferredBoundsWidth();
            var typicalHeight:Number = typicalElt.getPreferredBoundsHeight();
            llv.defaultMinorSize = typicalHeight;
            llv.defaultMajorSize = typicalWidth;
        }
        
        if (!isNaN(_columnWidth))
            llv.defaultMajorSize = _columnWidth;
        
        if (layoutTarget)
            llv.length = layoutTarget.numElements;        

        llv.gap = gap;
        llv.majorAxisOffset = paddingLeft;
    }

    /**
     *  @private
     */
     override public function elementAdded(index:int):void
     {
         if ((index >= 0) && useVirtualLayout && llv)
            llv.insert(index);  // insert index parameter is uint
     }

    /**
     *  @private
     */
     override public function elementRemoved(index:int):void
     {
        if ((index >= 0) && useVirtualLayout && llv)
            llv.remove(index);  // remove index parameter is uint
     }     

    /**
     *  @private
     * 
     *  Compute potentially approximate values for measuredWidth,Height and 
     *  measuredMinWidth,Height.
     * 
     *  This method does not get layout elements from the target except
     *  as a side effect of calling typicalLayoutElement.
     * 
     *  If variableColumnWidth="false" then all dimensions are based on 
     *  typicalLayoutElement and the sizes already cached in llv.  The 
     *  llv's defaultMajorSize, minorSize, and minMinorSize 
     *  are based on typicalLayoutElement.
     */
    private function measureVirtual(layoutTarget:GroupBase):void
    {
        var eltCount:int = layoutTarget.numElements;
        var measuredEltCount:int = getColumsToMeasure(eltCount);
        
        var hPadding:Number = paddingLeft + paddingRight;
        var vPadding:Number = paddingTop + paddingBottom;
        
        if (measuredEltCount <= 0)
        {
            layoutTarget.measuredWidth = layoutTarget.measuredMinWidth = hPadding;
            layoutTarget.measuredHeight = layoutTarget.measuredMinHeight = vPadding;
            return;
        }        
        
        updateLLV(layoutTarget);     
        if (variableColumnWidth)
        {
            // Special case: fewer elements than requestedColumnCount, so temporarily
            // make llv.length == requestedColumnCount.
            var oldLength:int = -1;
            if (measuredEltCount > llv.length)
            {
                oldLength = llv.length;
                llv.length = measuredEltCount;
            }

            // paddingRight is already taken into account as the majorAxisOffset of the llv 
            // Measured size according to the cached actual size:
            var measuredWidth:Number = llv.end(measuredEltCount - 1) + paddingRight;
            
            // For the live ItemRenderers use the preferred size
            // instead of the cached actual size:
            var dataGroupTarget:DataGroup = layoutTarget as DataGroup;
            if (dataGroupTarget)
            {
                var indices:Vector.<int> = dataGroupTarget.getItemIndicesInView();
                for each (var i:int in indices)
                {
                    var element:ILayoutElement = dataGroupTarget.getElementAt(i);
                    if (element)
                    {
                        measuredWidth -= llv.getMajorSize(i);
                        measuredWidth += element.getPreferredBoundsWidth();
                    }
                }
            }
            
            layoutTarget.measuredWidth = measuredWidth;
            
            if (oldLength != -1)
                llv.length = oldLength;
        }
        else
        {
            var hgap:Number = (measuredEltCount > 1) ? (measuredEltCount - 1) * gap : 0;
            layoutTarget.measuredWidth = (measuredEltCount * columnWidth) + hgap + hPadding;
        }
        layoutTarget.measuredHeight = llv.minorSize + vPadding;

        layoutTarget.measuredMinWidth = layoutTarget.measuredWidth;
        layoutTarget.measuredMinHeight = (verticalAlign == VerticalAlign.JUSTIFY) ? 
                llv.minMinorSize + vPadding : layoutTarget.measuredHeight;
    }

    /**
     *  @private
     * 
     *  If requestedColumnCount is specified then as many layout elements
     *  or "columns" are measured, starting with element 0, otherwise all of the 
     *  layout elements are measured.
     *  
     *  If requestedColumnCount is specified and is greater than the
     *  number of layout elements, then the typicalLayoutElement is used
     *  in place of the missing layout elements.
     * 
     *  If variableColumnWidth="true", then the layoutTarget's measuredWidth
     *  is the sum of preferred widths of the layout elements, plus the sum of the
     *  gaps between elements, and its measuredHeight is the max of the elements' 
     *  preferred heights.
     * 
     *  If variableColumnWidth="false", then the layoutTarget's measuredWidth
     *  is columnWidth multiplied by the number or layout elements, plus the 
     *  sum of the gaps between elements.
     * 
     *  The layoutTarget's measuredMinWidth is the sum of the minWidths of 
     *  layout elements that have specified a value for the percentWidth
     *  property, and the preferredWidth of the elements that have not, 
     *  plus the sum of the gaps between elements.
     * 
     *  The difference reflects the fact that elements which specify 
     *  percentWidth are considered to be "flexible" and updateDisplayList 
     *  will give flexible components at least their minWidth.  
     * 
     *  Layout elements that aren't flexible always get their preferred width.
     * 
     *  The layoutTarget's measuredMinHeight is the max of the minHeights for 
     *  elements that have specified percentHeight (that are "flexible") and the 
     *  preferredHeight of the elements that have not.
     * 
     *  As before the difference is due to the fact that flexible items are only
     *  guaranteed their minHeight.
     */
    override public function measure():void
    {
        var layoutTarget:GroupBase = target;
        if (!layoutTarget)
            return;
            
        if (useVirtualLayout)
            measureVirtual(layoutTarget);
        else 
            measureReal(layoutTarget);
            
        // Use Math.ceil() to make sure that if the content partially occupies
        // the last pixel, we'll count it as if the whole pixel is occupied.
        layoutTarget.measuredWidth = Math.ceil(layoutTarget.measuredWidth);    
        layoutTarget.measuredHeight = Math.ceil(layoutTarget.measuredHeight);    
        layoutTarget.measuredMinWidth = Math.ceil(layoutTarget.measuredMinWidth);    
        layoutTarget.measuredMinHeight = Math.ceil(layoutTarget.measuredMinHeight);    
    }
    
    /**
     *  @private 
     */  
    override public function getNavigationDestinationIndex(currentIndex:int, navigationUnit:uint, arrowKeysWrapFocus:Boolean):int
    {
        if (!target || target.numElements < 1)
            return -1; 
            
        var maxIndex:int = target.numElements - 1;

        // Special case when nothing was previously selected
        if (currentIndex == -1)
        {
            if (navigationUnit == NavigationUnit.LEFT)
                return arrowKeysWrapFocus ? maxIndex : -1;

            if (navigationUnit == NavigationUnit.RIGHT)
                return 0;    
        }    

        // Make sure currentIndex is within range
        currentIndex = Math.max(0, Math.min(maxIndex, currentIndex));

        var newIndex:int; 
        var bounds:Rectangle;
        var x:Number;

        switch (navigationUnit)
        {
            case NavigationUnit.LEFT:
            {
               if (arrowKeysWrapFocus && currentIndex == 0)
                   newIndex = maxIndex;
               else
                   newIndex = currentIndex - 1;  
               break;
            } 

            case NavigationUnit.RIGHT: 
            {
               if (arrowKeysWrapFocus && currentIndex == maxIndex)
                   newIndex = 0;
               else
                   newIndex = currentIndex + 1;  
               break;
            }
             
            case NavigationUnit.PAGE_UP:
            case NavigationUnit.PAGE_LEFT:
            {
                // Find the first fully visible element
                var firstVisible:int = firstIndexInView;
                var firstFullyVisible:int = firstVisible;
                if (fractionOfElementInView(firstFullyVisible) < 1)
                    firstFullyVisible += 1;
                 
                // Is the current element in the middle of the viewport?
                if (firstFullyVisible < currentIndex && currentIndex <= lastIndexInView)
                    newIndex = firstFullyVisible;
                else
                {
                    // Find an element that's one page left
                    if (currentIndex == firstFullyVisible || currentIndex == firstVisible)
                    {
                        // currentIndex is visible, we can calculate where the scrollRect top
                        // would end up if we scroll by a page                    
                        x = getHorizontalScrollPositionDelta(NavigationUnit.PAGE_LEFT) + getScrollRect().left;
                    }
                    else
                    {
                        // currentIndex is not visible, just find an element a page left from currentIndex
                        x = getElementBounds(currentIndex).right - getScrollRect().width;
                    }

                    // Find the element after the last element that spans left of the x position
                    newIndex = currentIndex - 1;
                    while (0 <= newIndex)
                    {
                        bounds = getElementBounds(newIndex);
                        if (bounds && bounds.left < x)
                        {
                            // This element spans the y position, so return the next one
                            newIndex = Math.min(currentIndex - 1, newIndex + 1);
                            break;
                        }
                        newIndex--;    
                    }
                }
                break;
            }

            case NavigationUnit.PAGE_DOWN:
            case NavigationUnit.PAGE_RIGHT:
            {
                // Find the last fully visible element:
                var lastVisible:int = lastIndexInView;
                var lastFullyVisible:int = lastVisible;
                if (fractionOfElementInView(lastFullyVisible) < 1)
                    lastFullyVisible -= 1;
                
                // Is the current element in the middle of the viewport?
                if (firstIndexInView <= currentIndex && currentIndex < lastFullyVisible)
                    newIndex = lastFullyVisible;
                else
                {
                    // Find an element that's one page right
                    if (currentIndex == lastFullyVisible || currentIndex == lastVisible)
                    {
                        // currentIndex is visible, we can calculate where the scrollRect bottom
                        // would end up if we scroll by a page                    
                        x = getHorizontalScrollPositionDelta(NavigationUnit.PAGE_RIGHT) + getScrollRect().right;
                    }
                    else
                    {
                        // currentIndex is not visible, just find an element a page right from currentIndex
                        x = getElementBounds(currentIndex).left + getScrollRect().width;
                    }

                    // Find the element before the first element that spans right of the y position
                    newIndex = currentIndex + 1;
                    while (newIndex <= maxIndex)
                    {
                        bounds = getElementBounds(newIndex);
                        if (bounds && bounds.right > x)
                        {
                            // This element spans the y position, so return the previous one
                            newIndex = Math.max(currentIndex + 1, newIndex - 1);
                            break;
                        }
                        newIndex++;    
                    }
                }
                break;
            }

            default: return super.getNavigationDestinationIndex(currentIndex, navigationUnit, arrowKeysWrapFocus);
        }
        return Math.max(0, Math.min(maxIndex, newIndex));  
    }
    
    /**
     *  @private
     * 
     *  Used only for virtual layout.
     */
    private function calculateElementHeight(elt:ILayoutElement, targetHeight:Number, containerHeight:Number):Number
    {
       // If percentHeight is specified then the element's height is the percentage
       // of targetHeight clipped to min/maxHeight and to (upper limit) targetHeight.
       var percentHeight:Number = elt.percentHeight;
       if (!isNaN(percentHeight))
       {
          var height:Number = percentHeight * 0.01 * targetHeight;
          return Math.min(targetHeight, Math.min(elt.getMaxBoundsHeight(), Math.max(elt.getMinBoundsHeight(), height)));
       }
       switch(verticalAlign)
       {
           case VerticalAlign.JUSTIFY: 
               return targetHeight;
           case VerticalAlign.CONTENT_JUSTIFY: 
               return Math.max(elt.getPreferredBoundsHeight(), containerHeight);
       }
       return NaN; // not constrained
    }

    /**
     *  @private
     * 
     *  Used only for virtual layout.
     */
    private function calculateElementY(elt:ILayoutElement, eltHeight:Number, containerHeight:Number):Number
    {
       switch(verticalAlign)
       {
           case VerticalAlign.MIDDLE: 
               return Math.round((containerHeight - eltHeight) * 0.5);
           case VerticalAlign.BOTTOM: 
               return containerHeight - eltHeight;
       }
       return 0;  // VerticalAlign.TOP
    }

    /**
     *  @private
     * 
     *  Update the layout of the virtualized elements that overlap
     *  the scrollRect's horizontal extent.
     *
     *  The width of each layout element will be its preferred width, and its
     *  x will be the right edge of the previous item, plus the gap.
     * 
     *  No support for percentWidth, includeInLayout=false, or null layoutElements,
     * 
     *  The height of each layout element will be set to its preferred height, unless
     *  one of the following is true:
     * 
     *  - If percentHeight is specified for this element, then its height will be the
     *  specified percentage of the target's actual (unscaled) height, clipped 
     *  the layout element's minimum and maximum height.
     * 
     *  - If verticalAlign is "justify", then the element's height will
     *  be set to the target's actual (unscaled) height.
     * 
     *  - If verticalAlign is "contentJustify", then the element's height
     *  will be set to the target's content height.
     * 
     *  The Y coordinate of each layout element will be set to 0 unless one of the
     *  following is true:
     * 
     *  - If verticalAlign is "middle" then y is set so that the element's preferred
     *  height is centered within the larget of the contentHeight and the target's height:
     *      y = (Math.max(contentHeight, target.height) - layoutElementHeight) * 0.5
     * 
     *  - If verticalAlign is "bottom" the y is set so that the element's bottom
     *  edge is aligned with the the bottom edge of the content:
     *      y = (Math.max(contentHeight, target.height) - layoutElementHeight)
     * 
     *  Implementation note: unless verticalAlign is either "justify" or 
     *  "top", the layout elements' y or height depends on the contentHeight.
     *  The contentHeight is a maximum and although it may be updated to 
     *  different value after all (viewable) elements have been laid out, it
     *  often does not change.  For that reason we use the current contentHeight
     *  for the initial layout and then, if it has changed, we loop through 
     *  the layout items again and fix up the y/height values.
     */
    private function updateDisplayListVirtual():void
    {
        var layoutTarget:GroupBase = target; 
        var eltCount:int = layoutTarget.numElements;
        var targetHeight:Number = Math.max(0, layoutTarget.height - paddingTop - paddingBottom);
        var minVisibleX:Number = layoutTarget.horizontalScrollPosition;
        var maxVisibleX:Number = minVisibleX + layoutTarget.width;
       
        var contentWidth:Number;
        var paddedContentWidth:Number;

        updateLLV(layoutTarget);

        // Find the index of the first visible item. Since the item's bounds includes the gap
        // that follows it, we want to avoid looking at an item that has only a portion of
        // its gap intersecting with the visible region.
        // We have to also be careful, as gap could be negative and in that case, we should
        // simply start from minVisibleX - SDK-22497.
        var startIndex:int = llv.indexOf(Math.max(0, minVisibleX + gap));
        if (startIndex == -1)
        {
            // No items are visible.  Just set the content size.
            contentWidth = llv.end(llv.length - 1) - paddingLeft;
            paddedContentWidth = Math.ceil(contentWidth + paddingLeft + paddingRight);
            layoutTarget.setContentSize(paddedContentWidth, layoutTarget.contentHeight);
            return;
        }
            
        var fixedColumnWidth:Number = NaN;
        if (!variableColumnWidth)
            fixedColumnWidth = columnWidth;  // may query typicalLayoutElement, elt at index=0
         
        var justifyHeights:Boolean = verticalAlign == VerticalAlign.JUSTIFY;
        var eltWidth:Number = NaN;
        var eltHeight:Number = (justifyHeights) ? Math.max(llv.minMinorSize, targetHeight) : llv.minorSize;  
        var contentHeight:Number = (justifyHeights) ? Math.max(llv.minMinorSize, targetHeight) : llv.minorSize;
        var containerHeight:Number = Math.max(contentHeight, targetHeight);
        var x:Number = llv.start(startIndex);
        var index:int = startIndex;
        var y0:Number = paddingTop;
        
        // First pass: compute element x,y,width,height based on 
        // current contentHeight; cache computed widths/heights in llv.
        for (; (x < maxVisibleX) && (index < eltCount); index++)
        {
            // TODO (hmuller): should pass in eltWidth, eltHeight
            var elt:ILayoutElement = layoutTarget.getVirtualElementAt(index);
            var w:Number = fixedColumnWidth; // NaN for variable width columns
            var h:Number = calculateElementHeight(elt, targetHeight, containerHeight); // can be NaN
            elt.setLayoutBoundsSize(w, h);
            w = elt.getLayoutBoundsWidth();        
            h = elt.getLayoutBoundsHeight();
            var y:Number = y0 + calculateElementY(elt, h, containerHeight);
            elt.setLayoutBoundsPosition(x, y);
            llv.cacheDimensions(index, elt);
            x += w + gap;
        }
        var endIndex:int = index - 1;

        // Second pass: if neccessary, fix up y and height values based
        // on the updated contentHeight
        if (!justifyHeights && (llv.minorSize != contentHeight))
        {
            contentHeight = llv.minorSize;
            containerHeight = Math.max(contentHeight, targetHeight);            
            if ((verticalAlign != VerticalAlign.TOP) && (verticalAlign != VerticalAlign.JUSTIFY))
            {
                for (index = startIndex; index <= endIndex; index++)
                {
                    elt = layoutTarget.getElementAt(index);
                    h = calculateElementHeight(elt, targetHeight, containerHeight); // can be NaN
                    elt.setLayoutBoundsSize(elt.getLayoutBoundsWidth(), h);
                    h = elt.getLayoutBoundsHeight();
                    y = y0 + calculateElementY(elt, h, containerHeight);
                    elt.setLayoutBoundsPosition(elt.getLayoutBoundsX(), y);
                }
             }
        }

        // Third pass: if neccessary, fix up x based on updated contentWidth
        contentWidth = llv.end(llv.length - 1) - paddingLeft;
        var targetWidth:Number = Math.max(0, layoutTarget.width - paddingLeft - paddingRight);
        if (contentWidth < targetWidth)
        {
            var excessWidth:Number = targetWidth - contentWidth;
            var dx:Number = 0;
            var hAlign:String = horizontalAlign;
            if (hAlign == HorizontalAlign.CENTER)
            {
                dx = Math.round(excessWidth / 2);   
            }
            else if (hAlign == HorizontalAlign.RIGHT)
            {
                dx = excessWidth;
            }
            if (dx > 0)
            {
                for (index = startIndex; index <= endIndex; index++)
                {
                    elt = layoutTarget.getElementAt(index);
                    elt.setLayoutBoundsPosition(dx + elt.getLayoutBoundsX(), elt.getLayoutBoundsY());
                }
                contentWidth += dx;
            }
        }
        
        setColumnCount(index - startIndex);
        setIndexInView(startIndex, endIndex);

        // Make sure that if the content spans partially over a pixel to the right/bottom,
        // the content size includes the whole pixel.
        paddedContentWidth = Math.ceil(contentWidth + paddingLeft + paddingRight);
        var paddedContentHeight:Number = Math.ceil(contentHeight + paddingTop + paddingBottom);
        layoutTarget.setContentSize(paddedContentWidth, paddedContentHeight);
    }
    
    /**
     *  @private 
     */
    private function updateDisplayListReal():void
    {
        var layoutTarget:GroupBase = target;
        var targetWidth:Number = Math.max(0, layoutTarget.width - paddingLeft - paddingRight);
        var targetHeight:Number = Math.max(0, layoutTarget.height - paddingTop - paddingBottom);
        
        var layoutElement:ILayoutElement;
        var count:int = layoutTarget.numElements;
        
        // If verticalAlign is top, we don't need to figure out the contentHeight.
        // Otherwise the contentHeight is used to position the element and even size 
        // the element if it's "contentJustify" or "justify".
        var containerHeight:Number = targetHeight;
        if (verticalAlign == VerticalAlign.CONTENT_JUSTIFY ||
           (clipAndEnableScrolling && (verticalAlign == VerticalAlign.MIDDLE ||
                                       verticalAlign == VerticalAlign.BOTTOM))) 
        {
            for (var i:int = 0; i < count; i++)
            {
                layoutElement = layoutTarget.getElementAt(i);
                if (!layoutElement || !layoutElement.includeInLayout)
                    continue;
                
                var layoutElementHeight:Number;
                if (!isNaN(layoutElement.percentHeight))
                    layoutElementHeight = calculatePercentHeight(layoutElement, targetHeight);
                else
                    layoutElementHeight = layoutElement.getPreferredBoundsHeight();
                    
                containerHeight = Math.max(containerHeight, Math.ceil(layoutElementHeight));
            }
        }

        var excessWidth:Number = distributeWidth(targetWidth, targetHeight, containerHeight);
        
        // default to top (0)
        var vAlign:Number = 0;
        if (verticalAlign == VerticalAlign.MIDDLE)
            vAlign = .5;
        else if (verticalAlign == VerticalAlign.BOTTOM)
            vAlign = 1;

        var actualBaseline:Number = 0;
        var alignToBaseline:Boolean = verticalAlign == VerticalAlign.BASELINE;
        if (alignToBaseline)
        {
            var result:Array = calculateBaselineTopBottom(false /*calculateBottom*/);
            actualBaseline = result[0];
        }

        // If columnCount wasn't set, then as the LayoutElements are positioned
        // we'll count how many columns fall within the layoutTarget's scrollRect
        var visibleColumns:uint = 0;
        var minVisibleX:Number = layoutTarget.horizontalScrollPosition;
        var maxVisibleX:Number = minVisibleX + targetWidth

        // Finally, position the LayoutElements and find the first/last
        // visible indices, the content size, and the number of 
        // visible elements. 
        var x:Number = paddingLeft;
        var y0:Number = paddingTop;
        var maxX:Number = paddingLeft;
        var maxY:Number = paddingTop;     
        var firstColInView:int = -1;
        var lastColInView:int = -1;

        // Take horizontalAlign into account
        if (excessWidth > 0 || !clipAndEnableScrolling)
        {
            var hAlign:String = horizontalAlign;
            if (hAlign == HorizontalAlign.CENTER)
            {
                x = paddingLeft + Math.round(excessWidth / 2);   
            }
            else if (hAlign == HorizontalAlign.RIGHT)
            {
                x = paddingLeft + excessWidth;   
            }
        }

        for (var index:int = 0; index < count; index++)
        {
            layoutElement = layoutTarget.getElementAt(index);
            if (!layoutElement || !layoutElement.includeInLayout)
                continue;

            // Set the layout element's position
            var dx:Number = Math.ceil(layoutElement.getLayoutBoundsWidth());
            var dy:Number = Math.ceil(layoutElement.getLayoutBoundsHeight());

            var y:Number;
            if (alignToBaseline)
            {
                var elementBaseline:Number = layoutElement.baseline as Number;
                if (isNaN(elementBaseline))
                    elementBaseline = 0;

                // Note: don't round the position. Rounding will case the text line to shift by
                // a pixel and won't look aligned with the other element's text.
                var baselinePosition:Number = layoutElement.baselinePosition;
                y = y0 + actualBaseline + elementBaseline - baselinePosition;
            }
            else
            {
                y = y0 + (containerHeight - dy) * vAlign;
                // In case we have VerticalAlign.MIDDLE we have to round
                if (vAlign == 0.5)
                    y = Math.round(y);
            }

            layoutElement.setLayoutBoundsPosition(x, y);

            // Update maxX,Y, first,lastVisibleIndex, and x
            maxX = Math.max(maxX, x + dx);
            maxY = Math.max(maxY, y + dy);            
            if (!clipAndEnableScrolling || 
                ((x < maxVisibleX) && ((x + dx) > minVisibleX)) || 
                ((dx <= 0) && ((x == maxVisibleX) || (x == minVisibleX))))            
            {
                visibleColumns += 1;
                if (firstColInView == -1)
                   firstColInView = lastColInView = index;
                else
                   lastColInView = index;
            }                
            x += dx + gap;
        }
        
        setColumnCount(visibleColumns);  
        setIndexInView(firstColInView, lastColInView);

        // Make sure that if the content spans partially over a pixel to the right/bottom,
        // the content size includes the whole pixel.
        layoutTarget.setContentSize(Math.ceil(maxX + paddingRight),
                                    Math.ceil(maxY + paddingBottom));
    }


    /**
     *  @private
     * 
     *  This function sets the width of each child
     *  so that the widths add up to <code>width</code>. 
     *  Each child is set to its preferred width
     *  if its percentWidth is zero.
     *  If its percentWidth is a positive number,
     *  the child grows (or shrinks) to consume its
     *  share of extra space.
     *  
     *  The return value is any extra space that's left over
     *  after growing all children to their maxWidth.
     */
    private function distributeWidth(width:Number,
                                     height:Number,
                                     restrictedHeight:Number):Number
    {
        var spaceToDistribute:Number = width;
        var totalPercentWidth:Number = 0;
        var childInfoArray:Array = [];
        var childInfo:HLayoutElementFlexChildInfo;
        var newHeight:Number;
        var layoutElement:ILayoutElement;
        
        // columnWidth can be expensive to compute
        var cw:Number = (variableColumnWidth) ? 0 : Math.ceil(columnWidth);
        var count:int = target.numElements;
        var totalCount:int = count; // number of elements to use in gap calculation
        
        // If the child is flexible, store information about it in the
        // childInfoArray. For non-flexible children, just set the child's
        // width and height immediately.
        for (var index:int = 0; index < count; index++)
        {
            layoutElement = target.getElementAt(index);
            if (!layoutElement || !layoutElement.includeInLayout)
            {
                totalCount--;
                continue;
            }
            
            if (!isNaN(layoutElement.percentWidth) && variableColumnWidth)
            {
                totalPercentWidth += layoutElement.percentWidth;

                childInfo = new HLayoutElementFlexChildInfo();
                childInfo.layoutElement = layoutElement;
                childInfo.percent    = layoutElement.percentWidth;
                childInfo.min        = layoutElement.getMinBoundsWidth();
                childInfo.max        = layoutElement.getMaxBoundsWidth();
                
                childInfoArray.push(childInfo);                
            }
            else
            {
                sizeLayoutElement(layoutElement, height, verticalAlign, 
                                  restrictedHeight, NaN, variableColumnWidth, cw);
                
                spaceToDistribute -= Math.ceil(layoutElement.getLayoutBoundsWidth());
            } 
        }
        
        if (totalCount > 1)
            spaceToDistribute -= (totalCount-1) * gap;

        // Distribute the extra space among the flexible children
        if (totalPercentWidth)
        {
            Flex.flexChildrenProportionally(width,
                                            spaceToDistribute,
                                            totalPercentWidth,
                                            childInfoArray);
            var roundOff:Number = 0;
            for each (childInfo in childInfoArray)
            {
                // Make sure the calculated percentages are rounded to pixel boundaries
                var childSize:int = Math.round(childInfo.size + roundOff);
                roundOff += childInfo.size - childSize;

                sizeLayoutElement(childInfo.layoutElement, height, verticalAlign, 
                                  restrictedHeight, childSize, 
                                  variableColumnWidth, cw);
                spaceToDistribute -= childSize;
            }
        }
        return spaceToDistribute;
    }
    
    /**
     *  @private
     */
    override public function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
    {
        super.updateDisplayList(unscaledWidth, unscaledHeight);
        
        var layoutTarget:GroupBase = target; 
        if (!layoutTarget)
            return;

        if ((layoutTarget.numElements == 0) || (unscaledWidth == 0) || (unscaledHeight == 0))
        {
            setColumnCount(0);
            setIndexInView(-1, -1);
            if (layoutTarget.numElements == 0)
                layoutTarget.setContentSize(Math.ceil(paddingLeft + paddingRight),
                                            Math.ceil(paddingTop + paddingBottom));
            return;         
        }

        if (useVirtualLayout) 
            updateDisplayListVirtual();
        else
            updateDisplayListReal();
    }
    
    /**
     *  @private 
     *  Convenience function for subclasses that invalidates the
     *  target's size and displayList so that both layout's <code>measure()</code>
     *  and <code>updateDisplayList</code> methods get called.
     * 
     *  <p>Typically a layout invalidates the target's size and display list so that
     *  it gets a chance to recalculate the target's default size and also size and
     *  position the target's elements. For example changing the <code>gap</code>
     *  property on a <code>VerticalLayout</code> will internally call this method
     *  to ensure that the elements are re-arranged with the new setting and the
     *  target's default size is recomputed.</p> 
     */
    private function invalidateTargetSizeAndDisplayList():void
    {
        var g:GroupBase = target;
        if (!g)
            return;

        g.invalidateSize();
        g.invalidateDisplayList();
    }

    //--------------------------------------------------------------------------
    //
    //  Drop methods
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private 
     */
    override protected function calculateDropIndex(x:Number, y:Number):int
    {
        // Iterate over the visible elements
        var layoutTarget:GroupBase = target;
        var count:int = layoutTarget.numElements;
        
        // If there are no items, insert at index 0
        if (count == 0)
            return 0;
        
        // Go through the visible elements
        var minDistance:Number = Number.MAX_VALUE;
        var bestIndex:int = -1;
        var start:int = this.firstIndexInView;
        var end:int = this.lastIndexInView;
        
        for (var i:int = start; i <= end; i++)
        {
            var elementBounds:Rectangle = this.getElementBounds(i);
            if (!elementBounds)
                continue;
            
            if (elementBounds.left <= x && x <= elementBounds.right)
            {
                var centerX:Number = elementBounds.x + elementBounds.width / 2;
                return (x < centerX) ? i : i + 1;
            }
            
            var curDistance:Number = Math.min(Math.abs(x - elementBounds.left),
                                              Math.abs(x - elementBounds.right));
            if (curDistance < minDistance)
            {
                minDistance = curDistance;
                bestIndex = (x < elementBounds.left) ? i : i + 1;
            }
        }
        
        // If there are no visible elements, either pick to drop at the beginning or at the end
        if (bestIndex == -1)
            bestIndex = getElementBounds(0).x < x ? count : 0;

        return bestIndex;
    }
    
    /**
     *  @private
     */
    override protected function calculateDropIndicatorBounds(dropLocation:DropLocation):Rectangle
    {
        var dropIndex:int = dropLocation.dropIndex;
        var count:int = target.numElements;
        var gap:Number = this.gap;
        
        // Special case, if we insert at the end, and the gap is negative, consider it to be zero
        if (gap < 0 && dropIndex == count)
            gap = 0;
        
        var emptySpace:Number = (0 < gap ) ? gap : 0; 
        var emptySpaceLeft:Number = 0;
        if (target.numElements > 0)
        {
            emptySpaceLeft = (dropIndex < count) ? getElementBounds(dropIndex).left - emptySpace : 
                                                   getElementBounds(dropIndex - 1).right + gap - emptySpace;
        }
        
        // Calculate the size of the bounds, take minium and maximum into account
        var width:Number = emptySpace;
        var height:Number = Math.max(target.height, target.contentHeight) - paddingTop - paddingBottom;
        if (dropIndicator is IVisualElement)
        {
            var element:IVisualElement = IVisualElement(dropIndicator);
            width = Math.max(Math.min(width, element.getMaxBoundsWidth(false)), element.getMinBoundsWidth(false));
        }
        
        var x:Number = emptySpaceLeft + Math.round((emptySpace - width)/2);
        // Allow 1 pixel overlap with container border
        x = Math.max(-Math.ceil(width / 2), Math.min(target.contentWidth - Math.ceil(width/2), x));

        var y:Number = paddingTop;
        return new Rectangle(x, y, width, height);
    }

    /**
     *  @private
     */
    override protected function calculateDragScrollDelta(dropLocation:DropLocation,
                                                         elapsedTime:Number):Point
    {
        var delta:Point = super.calculateDragScrollDelta(dropLocation, elapsedTime);
        // Don't scroll in the vertical direction
        if (delta)
            delta.y = 0;
        return delta;
    }

    /**
     *  @private
     *  Identifies the element which has its "compare point" located closest 
     *  to the specified position.
     */
    override mx_internal function getElementNearestScrollPosition(
        position:Point,
        elementComparePoint:String = "center"):int
    {
        if (!useVirtualLayout)
            return super.getElementNearestScrollPosition(position, elementComparePoint);
        
        var g:GroupBase = GroupBase(target);
        if (!g)
            return -1;
        
        // We need a valid LLV for this function
        updateLLV(g);
        
        // Find the element which overlaps with the position
        var index:int = llv.indexOf(position.x);

        // Invalid index indicates that the position is past either end of the 
        // laid-out elements.   In this case, choose either the first or last one.
        if (index == -1)
            index = position.x < 0 ? 0 : g.numElements - 1; 
        
        var bounds:Rectangle = llv.getBounds(index);
        var adjacentBounds:Rectangle;
        
        // If we're comparing with a right-edge point, check both the current element and the element
        // at index-1 to see which is closest.
        if ((elementComparePoint == "topRight" || elementComparePoint == "bottomRight") && index > 0)
        {
            adjacentBounds = llv.getBounds(index - 1);
            if (Point.distance(position, adjacentBounds.bottomRight) < Point.distance(position, bounds.bottomRight))
                index--;
        }
        
        // If we're comparing with a left-edge point, check both the current element and the element
        // at index+1 to see which is closest.
        if ((elementComparePoint == "topLeft" || elementComparePoint == "bottomLeft") && index < g.numElements-1) 
        {
            adjacentBounds = llv.getBounds(index + 1);             
            if (Point.distance(position, adjacentBounds.topLeft) < Point.distance(position, bounds.topLeft))
                index++;
        }
        return index;
    }
}
}

import mx.containers.utilityClasses.FlexChildInfo;
import mx.core.ILayoutElement;
class HLayoutElementFlexChildInfo extends FlexChildInfo
{
    public var layoutElement:ILayoutElement;    
}

class SizesAndLimit
{
    public var preferredSize:Number;
    public var minSize:Number;
}
