////////////////////////////////////////////////////////////////////////////////
//
//  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 flashx.textLayout.compose
{
	import flash.display.DisplayObject;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.geom.Rectangle;
	import flash.text.engine.TextBaseline;
	import flash.text.engine.TextBlock;
	import flash.text.engine.TextElement;
	import flash.text.engine.TextLine;
	import flash.text.engine.TextLineCreationResult;
	import flash.text.engine.TextLineValidity;
	import flash.utils.Dictionary;
	
	import flashx.textLayout.container.ContainerController;
	import flashx.textLayout.debug.Debugging;
	import flashx.textLayout.debug.assert;
	import flashx.textLayout.elements.BackgroundManager;
	import flashx.textLayout.elements.Configuration;
	import flashx.textLayout.elements.ContainerFormattedElement;
	import flashx.textLayout.elements.FlowElement;
	import flashx.textLayout.elements.FlowGroupElement;
	import flashx.textLayout.elements.FlowLeafElement;
	import flashx.textLayout.elements.GlobalSettings;
	import flashx.textLayout.elements.InlineGraphicElement;
	import flashx.textLayout.elements.LinkElement;
	import flashx.textLayout.elements.ListElement;
	import flashx.textLayout.elements.ListItemElement;
	import flashx.textLayout.elements.OverflowPolicy;
	import flashx.textLayout.elements.ParagraphElement;
	import flashx.textLayout.elements.SpanElement;
	import flashx.textLayout.elements.TCYElement;
	import flashx.textLayout.elements.TableBodyElement;
	import flashx.textLayout.elements.TableColElement;
	import flashx.textLayout.elements.TableDataCellElement;
	import flashx.textLayout.elements.TableElement;
	import flashx.textLayout.elements.TableFormattedElement;
	import flashx.textLayout.elements.TableRowElement;
	import flashx.textLayout.elements.TextFlow;
	import flashx.textLayout.formats.BaselineOffset;
	import flashx.textLayout.formats.BlockProgression;
	import flashx.textLayout.formats.ClearFloats;
	import flashx.textLayout.formats.Direction;
	import flashx.textLayout.formats.Float;
	import flashx.textLayout.formats.FormatValue;
	import flashx.textLayout.formats.IListMarkerFormat;
	import flashx.textLayout.formats.ITextLayoutFormat;
	import flashx.textLayout.formats.LeadingModel;
	import flashx.textLayout.formats.ListStylePosition;
	import flashx.textLayout.formats.TextAlign;
	import flashx.textLayout.formats.TextLayoutFormat;
	import flashx.textLayout.formats.VerticalAlign;
	import flashx.textLayout.property.Property;
	import flashx.textLayout.tlf_internal;
	import flashx.textLayout.utils.LocaleUtil;
	import flashx.textLayout.utils.Twips;

	use namespace tlf_internal;
	
	
	[ExcludeClass]
	/** @private Common composer base class */
	public class BaseCompose
	{
		
		public static function get globalSWFContext():ISWFContext
		{ 
			return GlobalSWFContext.globalSWFContext; 
		}
		
		// a one deep AlignData cache
		static private var _savedAlignData:AlignData;
		static private function createAlignData(tfl:TextFlowLine):AlignData
		{ 
			if (_savedAlignData)
			{
				var rslt:AlignData = _savedAlignData; 
				rslt.textFlowLine = tfl;
				_savedAlignData = null;
				return rslt;
			}
			return new AlignData(tfl);
		}
		static private function releaseAlignData(ad:AlignData):void
		{ 
			ad.textLine = null;	// don't hold on to it
			ad.textFlowLine = null;
			_savedAlignData = ad; 
		}
		
		protected var _parcelList:ParcelList;
		
		/** List of areas we're composing into, matches the container's bounding box */
		public function get parcelList():ParcelList
		{ return _parcelList; }
		
		private var _correctTextLength:Boolean = false;
		
		/** Element of current location */
		protected var _curElement:FlowLeafElement;		
		/** Absolute start position of _curElement */
		protected var _curElementStart:int;		
		/** Offset from element start to current location */
		protected var _curElementOffset:int;		
		/** ParagraphElement that contains the current location */
		protected var _curParaElement:ParagraphElement;	
		protected var _curParaFormat:ITextLayoutFormat;
		/** Absolute start position of _curParaElement */
		protected var _curParaStart:int;
		/** leading model for the current line's para (set when line is being composed and committed to _lastLineLeadingModel when line is finalized) */
		private var _curLineLeadingModel:String = "";
		/** leading factor calculated when composing the current line (committed to _lastLineLeading when line is finalized)
		 * The factor has different meanings for different leading models. */
		private var _curLineLeading:Number;
		/** leading model for the last line's para */
		protected var _lastLineLeadingModel:String = "";
		/** leading factor calculated for the line composed last. 
		 * The factor has different meanings for different leading models. */
		protected var _lastLineLeading:Number;
		/** effective descent of the last line. This is the distance between a line's Roman baseline and 
		 * its Descent baseline (for leading models other than LeadingModel.BOX) or the bottom of its CSS line box (for LeadingModel.BOX) */
		protected var _lastLineDescent:Number;
		/** Amount of spaceAfter added to the previous line (used in calculating effective paragraphSpaceBefore/paragraphSpaceAfter */
		protected var _paragraphSpaceCarried:Number;
		/** Amount of vertical space added to the previous element (used in calculating vertical space collapse) **/
		protected var _verticalSpaceCarried:Number;
		/** BlockProgression - vertical horizontal etc. @see text.formats.BlockProgression */
		protected var _blockProgression:String;
		/** Are we at the top of the column? */
		protected var _atColumnStart:Boolean;
		/** Current textIndent amount, 0 if line is not the first */
		protected var _textIndent:Number;
		
		/** Minimum left edge coordinate across all the parcels in a controller */
		private var _controllerLeft:Number;
		/** Minimum top edge across all the parcels in a controller */
		private var _controllerTop:Number;
		/** Maximum right edge coordinate across all the parcels in a controller */
		private var _controllerRight:Number;
		/** Maximum bottom edge coordinate across all the parcels in a controller */
		private var _controllerBottom:Number;
		
		/** Maximum horizontal extension from left/right edge of the parcel.  Alignment width for the parcel when measuring. */
		protected var _contentLogicalExtent:Number;
		/** Commited extent any lines needing additional alignment must update this number */
		protected var _contentCommittedExtent:Number;
		/** Committed logical height from floats */
		protected var _contentCommittedHeight:Number;
		/** Maximum horizontal extension for the current line from left/right edge of the parcel.  */
		protected var _workingContentLogicalExtent:Number;
		/* Extent for the current line, accumulated into _contentCommitedExtent when the line is committed */
		protected var _workingContentExtent:Number;
		/* Height for the current line, accumulated into _contentCommittedHeight when the line is committed */
		protected var _workingContentHeight:Number;
		/* Total depth as of the start of the line */
		protected var _workingTotalDepth:Number;
		/* Current parcel when line was started */
		protected var _workingParcelIndex:int;
		/** logical top of the parcel, for the line in progress */
		protected var _workingParcelLogicalTop:Number;
		/** Minimum starting coord for parcel bounds */
		protected var _accumulatedMinimumStart:Number;
		/** Minimum starting coord for parcel bounds */
		protected var _parcelLogicalTop:Number;
		
		/** Minimum left edge coordinate across all the parcels in a controller */
		protected var _parcelLeft:Number;
		/** Minimum top edge across all the parcels in a controller */
		protected var _parcelTop:Number;
		/** Maximum right edge coordinate across all the parcels in a controller */
		protected var _parcelRight:Number;
		/** Maximum bottom edge coordinate across all the parcels in a controller */
		protected var _parcelBottom:Number;
		
		/** owning textFlow of current compose */
		protected var _textFlow:TextFlow;
		private var _releaseLineCreationData:Boolean;
		/** flowComposer of current compose */
		protected var _flowComposer:IFlowComposer;
		/** rootElement of current compose */
		protected var _rootElement:ContainerFormattedElement;
		/** position to stop composing at */
		protected var _stopComposePos:int;
		
		/** First damaged controller to begin composing */
		protected var _startController:ContainerController;
		/** Beginning composition position.  Note this gets cleared once its been passed */
		protected var _startComposePosition:int;
		
		/** Visible area of the current controller. Used to determine which lines are going to be in view. */	
		protected var _controllerVisibleBoundsXTW:int;
		protected var _controllerVisibleBoundsYTW:int;
		protected var _controllerVisibleBoundsWidthTW:int;
		protected var _controllerVisibleBoundsHeightTW:int; 
		
		protected var _forceILGs:Boolean;
		protected var _lastGoodStart:int;		// used to group lines together in a single container when composing floats
		protected var _linePass:int;			// count of how many times we've retried this line
		protected var _paragraphContainsVisibleLines:Boolean;
		
		// save line slug for reuse - otherwise we're creating and discarding all the time
		static protected var _savedLineSlug:Slug;
		protected var _lineSlug:Slug = new Slug();
		static protected var _floatSlug:Slug;
		protected var _pushInFloats:Array;
		
		// scratch array for holding lines awaiting alignment
		private var _alignLines:Array;
		
		/** Parcel we are composing - used for keeping track of when it changes b/c parcelList.parcel may have advanced */
		protected var _curParcel:Parcel;
		
		/** Start position of _curParcel */
		protected var _curParcelStart:int;
		
		/** For interactive objects */
		protected var _curInteractiveObjects: Dictionary = null;
		
		/** Are we measuring */
		protected var _measuring:Boolean;
		
		protected var _curLine:TextFlowLine;
		protected var _previousLine:TextLine;
		
		protected var _listItemElement:ListItemElement;
		private var _firstLineDescentAndLeading:Number;
		
		protected function createParcelList():ParcelList
		{ return null; }
		protected function releaseParcelList(list:ParcelList):void	// No PMD
		{ }
		
		/** Starting controller for skipping ahead */
		public function get startController():ContainerController
		{ return _startController; }
		
		/** prevent any leaks. @private */
		tlf_internal function releaseAnyReferences():void
		{
			_curElement = null;
			_curParaElement = null;
			_curParaFormat = null;
			_flowComposer = null;
			_parcelList = null;
			_rootElement = null;
			_startController = null;
			_textFlow = null;
			_previousLine = null;
			_curLine = null;
		}
		
		
		/** Initialize for a composition that will compose up through the controllerEndIndex, or all the way to the end of the flow
		 * @param composer
		 * @param composeToPosition 	-1 means not specified.  0 means request to compose nothing, >0 specifies a position to force compose to
		 * @param controllerStartIndex	index of the first controller to compose for, derived class allows -1 for default 
		 * @param controllerEndIndex	index of the last controller to compose for, or -1 to compose through all controllers
		 */
		protected function  initializeForComposer(composer:IFlowComposer, composeToPosition:int, controllerStartIndex:int, controllerEndIndex:int):void
		{
			CONFIG::debug 
			{ 
				var count:int = 0;
				_textFlow.applyFunctionToElements(function (elem:FlowElement):Boolean{ if (elem.defaultTypeName == "img") count++; return false; });
				assert(count == _textFlow.graphicObjectCount,"BaseCompose mistmatched graphicObject count");
				
				count = 0;
				_textFlow.applyFunctionToElements(function (elem:FlowElement):Boolean{ if (elem.hasActiveEventMirror()) count++; if (elem is LinkElement) count++; return false; });
				assert(count == _textFlow.interactiveObjectCount,"BaseCompose mistmatched interactiveObject count");

				assert(composer.getControllerIndex(_startController) == controllerStartIndex, "BaseCompose initializeForComposer expected derived class to set up _startController before now"); 
				assert(controllerStartIndex >= 0, "BaseCompose initializeForComposer expected derived class to set controllerStartIndex to a valid controller"); 
			}
			if (!_savedLineSlug)
				_lineSlug = new Slug();
			else
			{
				_lineSlug = _savedLineSlug;
				_savedLineSlug = null;
			}
			_parcelList = createParcelList();
			
			_paragraphSpaceCarried = 0;
			_blockProgression = composer.rootElement.computedFormat.blockProgression;

			// for a non-specified compose position the ParcelList handles the bail out - just set to textLength
			_stopComposePos = composeToPosition >= 0 ? Math.min(_textFlow.textLength,composeToPosition) : _textFlow.textLength;
			
			if (controllerStartIndex < 0)
				controllerStartIndex = 0;
			
			// this chains through the list - tell it if a "care about" comopseToPosition was specified
			_parcelList.beginCompose(composer, controllerStartIndex, controllerEndIndex, composeToPosition > 0);	
			
			_contentLogicalExtent = 0;
			_contentCommittedExtent = 0;
			_contentCommittedHeight = 0;
			_accumulatedMinimumStart = TextLine.MAX_LINE_WIDTH;
			_parcelLogicalTop = NaN;
			
			_linePass = 0;
			_lastGoodStart = -1;
			if (_pushInFloats)
				_pushInFloats.length = 0;
			
			_listItemElement = null;
		}
		
		private function composeBlockElement(elem:FlowGroupElement,absStart:int,isInTable:Boolean=false, startChildIdx:int = -1):Boolean
		{	
			var child:FlowElement;
			var rslt:Boolean;	// scratch
			
			// Iterate through the children, composing them. If we're starting in the middle of the element,
			// make sure we advance to the starting child.
			var idx:int = 0;
			if ( startChildIdx != -1 )
				idx = startChildIdx;
			if(!isInTable)
			{
				if (absStart != _curElementStart + _curElementOffset) 	// starting partway in
				{
					idx = elem.findChildIndexAtPosition((_curElementStart + _curElementOffset) - absStart);
					child = elem.getChildAt(idx);
					absStart += child.parentRelativeStart;
					
					// Fix bug#2907691 When composition starts in middle of the container, paddingBottom for the previous paragraph is ignored
					// add prevous paragraph's paddingBottom values to totalDepth
					var previousElement:FlowLeafElement = _textFlow.findLeaf(_startComposePosition - 1);
					if (previousElement)
					{
						var previousParagraph:ParagraphElement = previousElement.getParagraph();
						if (previousParagraph && previousParagraph != _curElement.getParagraph())
							if (previousParagraph.paddingBottom != undefined)
								_parcelList.addTotalDepth(previousParagraph.paddingBottom);
					}
					
					// child is table means recompose starts in the middle of a table. 
					// In this case, we finished compose the table, then continue
					if ( child is TableElement )
					{
						child = _curElement;
						while ( child && ! (child is TableRowElement) )
							child = child.parent;
						
						var tableElement:TableElement = child.parent as TableElement;
						tableElement.totalRowDepth = 0;
						tableElement.numAcrossParcels = 0;
						tableElement.originParcelIndex = 0;
						tableElement.heightArray = [];
						if ( ! composeBlockElement(child.parent, _curElementStart, true, (child as TableRowElement).rowIndex) )
						{
							BackgroundManager.collectBlock(_textFlow, tableElement, _parcelList, true);
							return false;
						}
						
						// Add table border info
						tableElement.totalRowDepth += tableElement.getEffectiveBorderBottomWidth() + tableElement.computedFormat.cellSpacing;
						tableElement.height = tableElement.totalRowDepth;
						
						absStart = _curElementStart;
						idx ++;
						
						if ( ! gotoParcel(tableElement.numAcrossParcels, tableElement.totalRowDepth) )	
							return false;
						
						_atColumnStart = false;
						_parcelList.addTotalDepth(tableElement.getEffectiveMarginBottom());
						
						BackgroundManager.collectBlock(_textFlow, tableElement, _parcelList, true);
					}
				}
			}

			
			
			
			var composeEntireElement:Boolean = (absStart == _curElementStart + _curElementOffset);

			// Compose all the children, until all the containers are filled, or if we're on the last container, we've hit the stop compose text index			
			for (; idx < elem.numChildren && (absStart <= _stopComposePos || ! parcelList.atLast()); idx++)
			{
				child = elem.getChildAt(idx);
				
				if(!isInTable)
				{
					// If the element has clear applied, handle that now
					if (child.computedFormat.clearFloats != ClearFloats.NONE)
					{
						var adjustedDepth:Number = _curParcel.applyClear(child.computedFormat.clearFloats, _parcelList.totalDepth, child.computedFormat.direction);
						_parcelList.addTotalDepth(adjustedDepth);
						_verticalSpaceCarried = 0;
					}
	
					var boxLeftIndent:Number;		// logical with respect to horizontal/vertical text
					var boxRightIndent:Number;		// logical with respect to horizontal/vertical text
					var boxTopIndent:Number;		// logical with respect to horizontal/vertical text
					var boxBottomIndent:Number;		// logical with respect to horizontal/vertical text
					if (_blockProgression == BlockProgression.RL)
					{
						boxLeftIndent = child.getEffectivePaddingTop() + child.getEffectiveBorderTopWidth() + child.getEffectiveMarginTop();
						boxRightIndent = child.getEffectivePaddingBottom() + child.getEffectiveBorderBottomWidth() + child.getEffectiveMarginBottom();
						boxTopIndent = child.getEffectivePaddingRight() + child.getEffectiveBorderRightWidth() + child.getEffectiveMarginRight();
						boxBottomIndent = child.getEffectivePaddingLeft() + child.getEffectiveBorderLeftWidth() + child.getEffectiveMarginLeft();
					}
					else
					{
						boxLeftIndent = child.getEffectivePaddingLeft() + child.getEffectiveBorderLeftWidth() + child.getEffectiveMarginLeft();
						boxRightIndent = child.getEffectivePaddingRight() + child.getEffectiveBorderRightWidth() + child.getEffectiveMarginRight();
						boxTopIndent = child.getEffectivePaddingTop() + child.getEffectiveBorderTopWidth() + child.getEffectiveMarginTop();
						boxBottomIndent = child.getEffectivePaddingBottom() + child.getEffectiveBorderBottomWidth() + child.getEffectiveMarginBottom();
					}
					CONFIG::debug { assert(!isNaN(boxLeftIndent) && ! isNaN(boxRightIndent),"BAD indents"); }
					_parcelList.pushLeftMargin(boxLeftIndent);
					_parcelList.pushRightMargin(boxRightIndent);
					if (composeEntireElement && boxTopIndent > _verticalSpaceCarried)
						_parcelList.addTotalDepth(boxTopIndent - _verticalSpaceCarried);
					_verticalSpaceCarried = Math.max(boxTopIndent, 0);
				}
								
				
				var para:ParagraphElement = child as ParagraphElement;
				if (para)
				{
					import flashx.textLayout.formats.BreakStyle ;
					if ( !_atColumnStart && para.computedFormat.columnBreakBefore == BreakStyle.ALWAYS)
					{
						advanceToNextParcel() ;
					}
					if ( !(_atColumnStart && _parcelList.currentParcel != null && _parcelList.currentParcel.columnIndex == 0) && para.computedFormat.containerBreakBefore == BreakStyle.ALWAYS)
					{
						advanceToNextContainer() ;
					}
					
					if (!composeParagraphElement(para,absStart))
					{
						//for paragraph that has invisible text
						BackgroundManager.collectBlock(_textFlow, elem);
						return false;	// done
					}
					
					if (!(_atColumnStart && _parcelList.currentParcel != null && _parcelList.currentParcel.columnIndex == 0) && para.computedFormat.containerBreakAfter == BreakStyle.ALWAYS)
					{
						advanceToNextContainer() ;
					}
					if (!_atColumnStart && para.computedFormat.columnBreakAfter == BreakStyle.ALWAYS)
					{
						advanceToNextParcel() ;
					}
				}
				else if (child is ListElement)
				{						
					rslt = composeBlockElement(FlowGroupElement(child),absStart,isInTable);
					
					if (!rslt)
					{
						//for list that has invisible text
						BackgroundManager.collectBlock(_textFlow, elem);
						return false;
					}
				}
				else if (child is ListItemElement)
				{
					var savedListItemElement:ListItemElement = _listItemElement;
					_listItemElement = child as ListItemElement;
					rslt = composeBlockElement(FlowGroupElement(child),absStart,isInTable);
					_listItemElement = savedListItemElement;
						
					if (!rslt)
					{
						//for list item that has invisible text 
						BackgroundManager.collectBlock(_textFlow, elem);
						return false;
					}
				}
				else if (child is TableElement)         // Compose TableElement
				{
					if ( ! composeTableElement(child as TableElement, absStart, isInTable) )
						return false;
				}
				else if (child is TableRowElement)     // Compose TableRowElement
				{
					var rowElement:TableRowElement = child as TableRowElement;
					rowElement.rowIndex = idx;
					
					if ( ! composeTableRowElement(elem as TableElement, rowElement, absStart, isInTable) )
						return false;
				}
				else if (child is TableDataCellElement) // Compose TableDataCellElement
				{
					if ( ! composeTableDataCellElement(elem as TableRowElement, child as TableDataCellElement, absStart, isInTable) )
						return false;
				}
				else 
				{
					if ( ! composeBlockElement(FlowGroupElement(child),absStart))
					{
						//for div that has invisible text
						BackgroundManager.collectBlock(_textFlow, elem);
						return false;
					}
				}
				
				if(! isInTable)
				{
					if (boxBottomIndent > _verticalSpaceCarried)
						_parcelList.addTotalDepth(boxBottomIndent - _verticalSpaceCarried);
					_verticalSpaceCarried = Math.max(boxBottomIndent, 0);
	
					// restore to original values
					_parcelList.popLeftMargin(boxLeftIndent);
					_parcelList.popRightMargin(boxRightIndent);
					composeEntireElement = true;
				}
				absStart += child.textLength;
			}
			
			//for elements, whose text are all visible, except for TableElement, TableRowElement and TableDataCellElement
			if(!(elem is TableElement || elem is TableRowElement || elem is TableDataCellElement))
				BackgroundManager.collectBlock(_textFlow, elem);
			
			return true;
		}
		
		/** @private
		 * Compose a entire table element
		 * In  : TableElement, table's absStart position, isInTable
		 * Out : Boolean value, composition result, true - successful, false - failed
		 */
		private function composeTableElement(tableElement:TableElement, absStart:int, isInTable:Boolean):Boolean
		{
			//1st step findout the TableGroup element and get the composing parameter for the columns
			//my first idea is to read them to be a TableElement list or map. And remove all the column 
			//element so that the column element will not fall into the recursive loop
			tableElement.numAcrossParcels = 0;
            tableElement.heightArray = [];
            tableElement.curRowIdx = 0;
            tableElement.outOfLastParcel = false;
            
			//2nd step setup the environment settings
			var marginLeft:Number = tableElement.computedFormat.marginLeft;
			var marginTop:Number  = tableElement.computedFormat.marginTop;
            
			tableElement.x = _parcelList.currentParcel.x + marginLeft;
			tableElement.y = _parcelList.totalDepth + (_atColumnStart ? marginTop : _firstLineDescentAndLeading + marginTop);
			
			_parcelList.addTotalDepth(tableElement.y - _parcelList.totalDepth);
			
			// The following codes are setting the column width
			serializeTableColumnWidth(tableElement);
			
			//TO-DO: Verify the borderTopWidth Value
			tableElement.originParcelIndex = _parcelList.currentParcelIndex;
			var originParcel:Parcel = _parcelList.currentParcel;
			
			// Add table border info
			_parcelList.addTotalDepth(tableElement.getEffectiveBorderTopWidth());
			tableElement.totalRowDepth = _parcelList.totalDepth;
			
			//2nd step recursively compose the table elements
			if ( ! composeBlockElement(FlowGroupElement(tableElement), absStart, true) )
            {
                // If we're out of parcel, we don't need to calculate table height anymore,
                // because we've done in composeTableRowElement before it return false.
                if(tableElement.outOfLastParcel)
                    BackgroundManager.collectBlock(_textFlow, tableElement, _parcelList, false, true);
                
                return false;
            }
			
			// Add table border info
			tableElement.totalRowDepth += tableElement.getEffectiveBorderBottomWidth() + tableElement.computedFormat.cellSpacing;
			
            if(tableElement.numAcrossParcels == 0 && _startComposePosition <= tableElement.getAbsoluteStart())
                tableElement.height = tableElement.totalRowDepth - tableElement.y;
            else
				tableElement.height = tableElement.totalRowDepth;

			// If current composition position plus one line height beyond the parcel bottom, then we jump to next parcel 
			var depth:Number = tableElement.totalRowDepth;
			
			// If table already full the last column, we won't goto table cell parcel. Just goto last not table cell parcel
			var parcelIdx:int = tableElement.originParcelIndex + tableElement.numAcrossParcels;
			if ( _parcelList.getParcelAt(parcelIdx).isTableParcel )
				depth = _parcelList.getParcelAt(--parcelIdx).bottom;
			
			if ( ! gotoParcel(parcelIdx, depth) )	
				return false;
			
            _atColumnStart = false;
			_parcelList.addTotalDepth(tableElement.getEffectiveMarginBottom());
			
			BackgroundManager.collectBlock(_textFlow, tableElement, _parcelList);
			return true;
		}
		
		/** @private
		 * Compose a entire table row element
		 * In  : TableElement, TableRowElement, table's absStart position, isInTable
		 * Out : Boolean value, composition result, true - successful, false - failed
		 */
		private function composeTableRowElement(tableElement:TableElement, rowElement:TableRowElement, absStart:int, isInTable:Boolean):Boolean
		{
			rowElement.iMaxRowDepth = 0;
            rowElement.columnIndex = 0;
			
			// Add table cell spacing value
			tableElement.totalRowDepth += tableElement.computedFormat.cellSpacing;
			
			// Save environment parameters before compose a table row, because maybe this row out of "current" parcel, 
			// in that case, we need to reload these parameters, then recompose this row.
			var curParaStart:int = _curParaStart;
			var curElementStart:int = _curElementStart;
			var curParcelStart:int = _curParcelStart;
			var curElement:FlowLeafElement = _curElement;
			var curParaElement:ParagraphElement = _curParaElement;
            
            if ( ! composeBlockElement(FlowGroupElement(rowElement), absStart, isInTable) )
			{
				// Compose row failed, see if we it's because of out of parcel
				if ( rowElement.beyondParcel )
				{
                    var nextParcel:Parcel = _parcelList.getParcelAt(tableElement.originParcelIndex + tableElement.numAcrossParcels + 1);

                    if(tableElement.curRowIdx == 0)
                    {
                        if(!nextParcel || nextParcel.isTableParcel)
                        {
                            tableElement.x = tableElement.computedFormat.marginLeft;
                            tableElement.y = tableElement.totalRowDepth;
                        }
                    }
                    
                    // Release textLines before re-compose
                    for ( var i:int = 0; i < rowElement.numChildren; i ++ )
                    {
                        var cell:TableDataCellElement = rowElement.getChildAt(i) as TableDataCellElement;
                        for ( var j:int = 0; j < cell.numChildren; j ++ )
                        {
                            var paragraph:ParagraphElement = cell.getChildAt(j) as ParagraphElement;
                            var textBlock:TextBlock = paragraph.getTextBlock();
                            _parcelList.currentParcel.controller.clearFloatsAt(paragraph.getAbsoluteStart());
                            for (var textLine:TextLine = textBlock.lastLine; textLine; )
                            {
                                textBlock.releaseLines(textLine, textLine);
                                textLine.userData = null;
                                textLine.visible = false;
                                //TextLineRecycler.addLineForReuse(textLine);
                                if (_textFlow.backgroundManager)
                                    _textFlow.backgroundManager.removeLineFromCache(textLine);
                                textLine = textBlock.lastLine;
                            }
                            paragraph.releaseTextBlock();
                        }
                    }
                    
					// If table already full the last column, we won't goto table cell parcel. Just goto last not table cell parcel
					if ( ! nextParcel || nextParcel.isTableParcel)
                    {
                        tableElement.outOfLastParcel = true;
						return false;
                    }
                    
                    if(tableElement.curRowIdx > 0)
                    {
                        tableElement.numAcrossParcels ++;
                        tableElement.heightArray.push(0);
                        tableElement.totalRowDepth = nextParcel.y + tableElement.computedFormat.cellSpacing;
                    }
                    else if(tableElement.curRowIdx == 0)
                    {
                        tableElement.originParcelIndex++;
                        tableElement.x = nextParcel.x + tableElement.computedFormat.marginLeft;
                        tableElement.y = nextParcel.y;
                        tableElement.totalRowDepth = nextParcel.y + tableElement.computedFormat.cellSpacing + tableElement.getEffectiveBorderTopWidth();
                    }

					rowElement.beyondParcel = false;
                    
                    // Reload values for recompose
                    _curParaStart = curParaStart;
                    _curElementStart = curElementStart;
                    _curParcelStart = curParcelStart;
                    _curElement = curElement;
                    _curParaElement = curParaElement;
                    _curElementOffset = 0;
                    _contentLogicalExtent = 0;
                    rowElement.columnIndex = 0;
                    
					// Recompose current table row
					if ( ! composeBlockElement(FlowGroupElement(rowElement), absStart, isInTable) )
						return false;
				}
			}
			
            var curParcel:Parcel = _parcelList.getParcelAt(tableElement.originParcelIndex + tableElement.numAcrossParcels);
			rowElement.parcelIndex = tableElement.originParcelIndex + tableElement.numAcrossParcels;
			rowElement.height = rowElement.iMaxRowDepth;
			rowElement.x = curParcel.x;
			rowElement.y = tableElement.totalRowDepth;
			tableElement.totalRowDepth += rowElement.height;
			
			if(tableElement.numAcrossParcels == 0 && _startComposePosition <= tableElement.getAbsoluteStart())
				tableElement.height = tableElement.totalRowDepth - tableElement.y;
			else
				tableElement.height = tableElement.totalRowDepth;
			
			tableElement.height += tableElement.cellSpacing;
			
			// Add table cell to columnState for hitTest
			var ccOfRow:ContainerController = _parcelList.getParcelAt(rowElement.parcelIndex).controller;
			for ( i = 0; i < rowElement.numChildren; i ++ )
			{
				cell = rowElement.getChildAt(i) as TableDataCellElement;
				cell.height = rowElement.height;
				_parcelList.addTableCell2ColumnState(ccOfRow, cell);
			}
			
			BackgroundManager.collectBlock(_textFlow, rowElement, _parcelList);
            tableElement.curRowIdx++;
			return true;
		}
		
		/** @private
		 * Compose a entire table row element
		 * In  : TableRowElement, TableDataCellElement, table's absStart position, isInTable
		 * Out : Boolean value, composition result, true - successful, false - failed
		 */
		private function composeTableDataCellElement(rowElement:TableRowElement, cellElement:TableDataCellElement, absStart:int, isInTable:Boolean):Boolean
		{
			//TableDataCellElement's parent must be TableRowElement
			var tableElement:TableElement = rowElement.getTable();
			
			//TO-DO: This is temporary codes, needs to be updated when the real column attribute is implemented
			var currParcel:Parcel = _parcelList.getParcelAt(tableElement.originParcelIndex + tableElement.numAcrossParcels);
			cellElement.x = currParcel.x + tableElement.getColumnAt(rowElement.columnIndex).x;
			cellElement.y = tableElement.totalRowDepth;
			cellElement.width = tableElement.getColumnWidth(rowElement.columnIndex);
			cellElement.height = undefined;
			var rc:Rectangle = new Rectangle(cellElement.x, cellElement.y, cellElement.width, 8000); // 8000 is Max row height
			cellElement.parcelIndex = _parcelList.numParcels();
			var newParcel:Parcel = _parcelList.addParcel(rc, currParcel.controller,
				tableElement.originParcelIndex + tableElement.numAcrossParcels);
			newParcel.isTableParcel = true;
			
			if ( ! gotoParcel(cellElement.parcelIndex, 0) )
				return false;
			
			// Add border and cell padding
			_parcelList.addTotalDepth(cellElement.getEffectiveBorderTopWidth() + cellElement.computedFormat.cellPadding);
			_parcelList.pushLeftMargin(cellElement.getEffectiveBorderLeftWidth() + cellElement.computedFormat.cellPadding);
			_parcelList.pushRightMargin(cellElement.getEffectiveBorderRightWidth() + cellElement.computedFormat.cellPadding);
			
			// fall into the recursive loop directly
			if ( ! composeBlockElement(FlowGroupElement(cellElement), absStart, isInTable) )
				return false;
			
			// Add border and cell padding, pop out padding margin
			_parcelList.addTotalDepth(cellElement.getEffectiveBorderBottomWidth() + cellElement.computedFormat.cellPadding);
			_parcelList.popLeftMargin(cellElement.getEffectiveBorderLeftWidth() + cellElement.computedFormat.cellPadding);
			_parcelList.popRightMargin(cellElement.getEffectiveBorderRightWidth() + cellElement.computedFormat.cellPadding);
			
			//TO-DO, The codes may be changed, mingjun's original codes are as following:
			//cellElement.height = _parcelList.totalDepth + paragraph.paddingBottom + paragraph.borderBottomWidth + paragraph.marginBottom;
			cellElement.height = _parcelList.totalDepth;
			if ( cellElement.height > rowElement.iMaxRowDepth )
				rowElement.iMaxRowDepth = cellElement.height;
			rowElement.columnIndex ++;
			
			// See if the composed line beyond "current" parcel's bottom
			if ( tableElement.totalRowDepth + rowElement.iMaxRowDepth > currParcel.bottom)
			{
				rowElement.beyondParcel = true;
				
				// Pop out useless parcels for this row
				for ( var n:int = 0; n < rowElement.columnIndex; n ++ )
					_parcelList.popParcel();
				return false;
			}
			
			return true;
		}
		
		/** @private
		 * Calculate table columm width based on column's width value, the rule is :
		 * if there are zero column width or the sum(columnWidth) not equal to table.tableWidth,
		 * we calculate average column width.
		 * In  : Number or percentage
		 * Out : Set pixcel based width of each table column
		 */
		private function serializeTableColumnWidth(table:TableElement):void
		{
            var curParcelWidth:Number = _parcelList.currentParcel.width;
			if ( table.tableWidth != undefined && table.tableWidth < curParcelWidth )
				table.computedWidth = table.tableWidth;
			else
                table.computedWidth = curParcelWidth;
            
            if(table.computedFormat.marginLeft > 0)
                table.computedWidth -= table.computedFormat.marginLeft;
            
            table.computedWidth -= table.computedFormat.marginRight;
            
			var logicalWidth:Number = table.computedWidth - table.getEffectiveBorderLeftWidth() - table.getEffectiveBorderRightWidth() - (table.column + 1) * table.computedFormat.cellSpacing;
			var columnTotalWidth:Number = table.getEffectiveBorderLeftWidth() + table.computedFormat.marginLeft;
            
			for ( var i:int = 0; i < table.column; i ++ )
			{
				var colWidth:* = table.getColumnWidth(i);
				
				// Column width is percentage like "20%"
				var strWidth:String = colWidth as String;
				if ( strWidth && strWidth.length != 0 && strWidth.charAt(strWidth.length - 1) == '%' )
				{
					colWidth = Property.toNumberIfPercent(colWidth) * logicalWidth / 100;
					if ( colWidth >= 0 )
						table.setColumnWidth(i, colWidth);
				}
				
				columnTotalWidth += table.computedFormat.cellSpacing;
				table.getColumnAt(i).x = columnTotalWidth;
				columnTotalWidth += colWidth;
			}
            
			columnTotalWidth -= (table.computedFormat.marginLeft + table.getEffectiveBorderLeftWidth() + table.column * table.computedFormat.cellSpacing);
			
			// If the sum of column width wider than table width,
			// we set every column width to average column width
			if ( columnTotalWidth - logicalWidth > 1 )
			{
				var avgColumnWidth:Number = logicalWidth / table.column;
				for ( var m:int = 0; m < table.column; m ++ )
				{
					table.setColumnWidth(m, avgColumnWidth);
					table.getColumnAt(m).x = table.getEffectiveBorderLeftWidth() + table.computedFormat.marginLeft 
						+ (m+1)*table.computedFormat.cellSpacing + m * avgColumnWidth;
				}
			} 
			// if the sum of column width less than table width, we enlarge the last column's width to fit table width
			else if ( columnTotalWidth < logicalWidth ) 
			{
				var orgWidth:Number = table.getColumnWidth(table.column - 1);
				table.setColumnWidth(table.column - 1, orgWidth + logicalWidth - columnTotalWidth);
			}
		}
		
		/**
		 * Compose the flow into the text container. Starts at the root element,
		 * and composes elements until either there are no more elements, or the
		 * text container is full. It will compose only the lines which are
		 * marked invalid, so that existing lines that are unchanged are not
		 * recomposed.
		 */
		public function composeTextFlow(textFlow:TextFlow, composeToPosition:int, controllerEndIndex:int):int
		{
			_textFlow = textFlow;
			
			if(_textFlow && _textFlow.backgroundManager)
				_textFlow.backgroundManager.clearBlockRecord();
			
			_releaseLineCreationData = textFlow.configuration.releaseLineCreationData && Configuration.playerEnablesArgoFeatures;
			
			_flowComposer = _textFlow.flowComposer;
			_rootElement = textFlow;
			_curElementOffset = 0;
			_curElement = _rootElement.getFirstLeaf();	
			
			_curElementStart = 0;		// current position in the text (start of current line)
			
			_curParcel = null;

			// must setup _startController and _startComposePosition
			initializeForComposer(_flowComposer, composeToPosition, -1 /* use default */, controllerEndIndex);
			
			resetControllerBounds();
			
			// Bug, needs to remove 
			_startComposePosition = _startController.absoluteStart;
			
			// This is where we will start composing from
			_curElement = _textFlow.findLeaf(_startComposePosition);
			_curElementStart = _curElement.getAbsoluteStart();
			_curElementOffset = _startComposePosition - _curElementStart;
			
			//clear interactiveObject 
			var curInteractiveObjects:Dictionary = _startController.interactiveObjects;
			var interactiveObjects_lastTime:Array = _startController.oldInteractiveObjects
			var curElem:Object;
			interactiveObjects_lastTime.splice(0);
			for each(curElem in curInteractiveObjects)
			{
				if(curElem && (curElem as FlowElement).getAbsoluteStart() >= _startComposePosition)
				{
					interactiveObjects_lastTime.push(curInteractiveObjects[curElem]);
					delete curInteractiveObjects[curElem];
				}
			}
			for(var cidx:int = _flowComposer.getControllerIndex(_startController) + 1; cidx <= controllerEndIndex; cidx ++)
			{
				curInteractiveObjects = _flowComposer.getControllerAt(cidx).interactiveObjects
				for each(curElem in curInteractiveObjects)
					if(curElem)
						delete curInteractiveObjects[curElem];
					
				// Clear previous composition results
				_flowComposer.getControllerAt(cidx).clearCompositionResults();
			}
			// If we're starting composition from the middle of the container, we have to set up the composition
			// state so that its the same as if we'd composed from the start.
			if (_startComposePosition <= _startController.absoluteStart || !advanceToComposeStartPosition())
			{
				if (_startComposePosition > _startController.absoluteStart)
				{
					// We tried to start from the middle, but it didn't succeed. Reset from the start of the container
					_startComposePosition = _startController.absoluteStart;
					_curElement = _textFlow.findLeaf(_startComposePosition);
					_curElementStart = _curElement.getAbsoluteStart();
					_curElementOffset = _startComposePosition - _curElementStart;
				} 
				if (_startComposePosition == _curElement.getParagraph().getAbsoluteStart())
					_previousLine = null;
				else
				{
					var startLineIndex:int = _flowComposer.findLineIndexAtPosition(_startComposePosition - 1);
					var line:TextFlowLine = _flowComposer.getLineAt(startLineIndex);
					_previousLine = line.getTextLine(true);
				}
				advanceToNextParcel();		// advance to first parcel
				if (_curParcel)
					_curParcel.controller.clearFloatsAt(0);
			}
			
			_startController.clearComposedLines(_curElementStart + _curElementOffset);
			
			_curParcelStart = _startController.absoluteStart; 		// yuck! this gets set to where we're composing from in parcelHasChanged, set it back to start of parcel
			
			composeInternal(_rootElement,0);
			
			for (;;)
			{
				if (parcelList.atEnd())
				{
					parcelHasChanged(null);		// force end of composition accounting for the parcel
					break;
				}
				
				var nextParcel:Parcel = parcelList.getParcelAt(parcelList.currentParcelIndex + 1);
				if ( parcelList.currentParcel.isTableParcel
					&& ((nextParcel && nextParcel.isTableParcel) || parcelList.currentParcelIndex == parcelList.numParcels()-1))
					_correctTextLength = true;
		
				advanceToNextParcel();
				_correctTextLength = false;
			}
			releaseParcelList(_parcelList);
			_parcelList = null;
			
			_savedLineSlug = _lineSlug;
			
			return _curElementStart + _curElementOffset;		// Return last composed position
		}
		
		// If we're starting composition from the middle of the container, we have to set up the composition
		// state so that its the same as if we'd composed from the start.
		private function advanceToComposeStartPosition():Boolean
		{
			var startLineIndex:int = _flowComposer.findLineIndexAtPosition(_startComposePosition - 1);
			var curLine:TextFlowLine = _flowComposer.getLineAt(startLineIndex);
			
			// cannot start in the middle if we are measuring AND there are floats
			if (curLine.controller.numFloats)
			{
				CONFIG::debug { assert((_blockProgression == BlockProgression.TB && curLine.controller.measureWidth 
					|| _blockProgression == BlockProgression.RL && curLine.controller.measureHeight) == _measuring,"Bad _measuring intialization"); }
				if (_measuring)
					return false;
			}

			_curLine = curLine;
			var previousElement:FlowLeafElement = (_curElementOffset == 0) ? _curElement.getPreviousLeaf() : _curElement;							
			// set up previous line leading info, and paragraphSpaceCarried (in case previous line had spaceAfter).
			_curLineLeadingModel = previousElement.getParagraph().getEffectiveLeadingModel();
			var curElem:FlowLeafElement = _textFlow.findLeaf(_curLine.absoluteStart);
			var curElemStart:int = curElem.getAbsoluteStart();
			calculateLeadingParameters(curElem, curElemStart, TextFlowLine.findNumberLine(_curLine.getTextLine())); 
			if (_startComposePosition == _curElement.getParagraph().getAbsoluteStart())
				_previousLine = null;
			else
				_previousLine = _curLine.getTextLine(true);
			CONFIG::debug { assert(!_previousLine || _previousLine.userData != null, "previousLine has no user data"); }
			CONFIG::debug { assert(!_previousLine || _previousLine.validity == TextLineValidity.VALID, "preivous line is invalid"); }
			_paragraphSpaceCarried = _curLine.spaceAfter;
			commitLastLineState(_curLine);
			
			// advance through the parcels to find the column where composition will start
			var startParcel:int = _curLine.columnIndex == -1 ? 0 : _curLine.columnIndex;
			_curParcel = _parcelList.currentParcel;
			var floatIndex:int = 0;
			for (var parcelIndex:int = -1; parcelIndex < startParcel; ++parcelIndex) 	// do this at least once!
			{
				advanceToNextParcel();

				_curParcelStart = _curParcel.controller.absoluteStart;		// so that bounds will be updated in finishParcel correctly (parcel won't appear empty!)

				// Process knockouts for floats that may be in the previously composed content, so that the parcel list will have
				// whatever knockouts came before the text we're composing
				var numFloats:int = _curParcel.controller.numFloats;
				if (numFloats)
				{
					for  (; floatIndex < numFloats; ++floatIndex)
					{
						var floatInfo:FloatCompositionData = _curParcel.controller.getFloatAt(floatIndex);
						if (floatInfo.columnIndex > _curParcel.columnIndex)
							break;
						if (floatInfo.floatType != Float.NONE && floatInfo.absolutePosition < _startComposePosition)
						{
							var ilg:InlineGraphicElement = _textFlow.findLeaf(floatInfo.absolutePosition) as InlineGraphicElement;
							var logicalHeight:Number = (_blockProgression == BlockProgression.RL) ? ilg.elementWidthWithMarginsAndPadding() : ilg.elementHeightWithMarginsAndPadding();
							_curParcel.knockOut(floatInfo.knockOutWidth, floatInfo.depth - _lastLineDescent, floatInfo.depth + logicalHeight, floatInfo.floatType == Float.LEFT);
						}
					}
				}
				_curParcel.controller.clearFloatsAt(_startComposePosition);
			}
			_curParcelStart = _curElementStart + _curElementOffset;	

			// Set the depth of the parcel based on the starting line's position	
			if (_blockProgression == BlockProgression.TB)
				_parcelList.addTotalDepth(_curLine.y + _curLine.ascent - _curParcel.y);
			else
				_parcelList.addTotalDepth(_curParcel.right - _curLine.x);
			_atColumnStart = false;
			
			// generate content bounds summary for the lines from the start of the container, to the startComposePosition
			var lineIndex:int = _flowComposer.findLineIndexAtPosition(_startController.absoluteStart);
			CONFIG::debug { assert(startLineIndex + 1 == _flowComposer.findLineIndexAtPosition(_startComposePosition), "startLineIndex not as expected"); }
			initializeContentBounds(lineIndex, startLineIndex);
			
			return true;
		}
		
		// Generate content bounds for the case where we're doing incremental composition (starting compose from middle of container)
		// If we're aligning horizontally to the measured width, then any lines that are center or right will have to get
		// realigned when we're done, even if they've already been composed. But, if the line is not aligned, or if it's
		// been aligned during the previous composition to the absolute compositionWidth, then we don't have to align it again.
		private function initializeContentBounds(lineIndex:int, lastLineToCheck:int):void
		{
			var columnIndex:int = -1;
			var line:TextFlowLine;
			
			// measuring for the line widths
			CONFIG::debug { assert((_blockProgression == BlockProgression.TB && _curParcel.controller.measureWidth 
				|| _blockProgression == BlockProgression.RL && _curParcel.controller.measureHeight) == _measuring,"Bad _measuring intialization"); }
			
			_parcelLogicalTop = computeTextFlowLineMinimumLogicalTop(_flowComposer.getLineAt(lineIndex),null);
			if (_measuring)
			{
				for (; lineIndex <= lastLineToCheck; ++lineIndex)
				{
					line = _flowComposer.getLineAt(lineIndex);
					
					if (line.columnIndex != columnIndex)
					{
						columnIndex = line.columnIndex;
						_contentLogicalExtent = 0;
						_contentCommittedExtent = 0;
						_accumulatedMinimumStart = TextLine.MAX_LINE_WIDTH;
					}
					var lineExtent:Number = line.lineExtent;
					_contentLogicalExtent = Math.max(_contentLogicalExtent, lineExtent);
					var textLine:TextLine 
					// If we're aligning horizontally to the measured width, then any lines that are center or right will have to get
					// realigned when we're done, even if they've already been composed. But, if the line is not aligned, or if it's
					// been aligned during the previous composition to the absolute compositionWidth, then we don't have to align it again.

					if (line.alignment == TextAlign.LEFT && !line.hasNumberLine)
						_contentCommittedExtent = Math.max(_contentCommittedExtent, lineExtent);	
					else
					{
						var alignData:AlignData = createAlignData(line);
						alignData.textLine = line.getTextLine(true);
						alignData.textAlign = line.alignment;
						var paraFormat:ITextLayoutFormat = line.paragraph.computedFormat;
						alignData.rightSideGap = getRightSideGap(line, line.alignment != TextAlign.LEFT);
						alignData.leftSideGap = getLeftSideGap(line);
						alignData.textIndent = paraFormat.textIndent;
						alignData.lineWidth = lineExtent - (alignData.rightSideGap + alignData.leftSideGap);
						if (!_alignLines)
							_alignLines = [];
						_alignLines.push(alignData);
					}
				}	
				CONFIG::debug { assert(_flowComposer.getLineAt(lastLineToCheck).accumulatedLineExtent == _contentLogicalExtent,"Bad _contentLogicalExtent"); }
			}
			else
			{
				line = _flowComposer.getLineAt(lastLineToCheck);
				_contentLogicalExtent = _contentCommittedExtent = line.accumulatedLineExtent;
				_accumulatedMinimumStart = line.accumulatedMinimumStart;
				// Assume any columns that came before this one are full. We don't want to take the time to iterate all previous lines in previous parcels/columns.
				if (_parcelList.currentParcelIndex > 0 && _parcelList.currentParcel.columnIndex > 0)
				{
					if (_blockProgression == BlockProgression.TB)
						_controllerBottom =  _curParcel.controller.compositionHeight;
					else
						_controllerLeft = 0 - _curParcel.controller.compositionWidth;
					if (_textFlow.computedFormat.direction == Direction.RTL)		// columns are right to left
						_controllerRight = _curParcel.controller.compositionWidth;
				}
			}
		}
		
		/** @private */
		tlf_internal function computeTextFlowLineMinimumLogicalTop(line:TextFlowLine,textLine:TextLine):Number
		{
			if (line.hasGraphicElement)
			{
				var pos:int = line.absoluteStart;
				var leafElement:FlowLeafElement = _textFlow.findLeaf(pos);
				var adjustedAscent:Number = line.getLineTypographicAscent(leafElement, leafElement.getAbsoluteStart(),textLine);
				var parcelTop:Number = (_blockProgression == BlockProgression.RL) ? line.x + adjustedAscent : line.y + line.ascent - adjustedAscent;
				var controller:ContainerController = line.controller;
				var lineEnd:int = pos + line.textLength;
				if (controller.numFloats > 0)		// adjust line upwards if it has a float that came before (e.g., landed on its own line before, and there was no room for text beside)
				{
					while (pos < lineEnd)
					{
						var floatInfo:FloatCompositionData = controller.getFloatAtPosition(pos);
						if (floatInfo)
						{
							parcelTop = Math.min(parcelTop, floatInfo.depth);
							pos = floatInfo.absolutePosition + 1;
						}
						else
							break;
					}
				} 
				return parcelTop;
			}
			// don't have one
			return NaN;
		}
		
		private function resetControllerBounds():void
		{
			_controllerLeft = TextLine.MAX_LINE_WIDTH;
			_controllerTop = TextLine.MAX_LINE_WIDTH;
			_controllerRight = -TextLine.MAX_LINE_WIDTH;
			_controllerBottom = -TextLine.MAX_LINE_WIDTH;
		}
		
		/** Release line creation data during this compose */
		protected function get releaseLineCreationData():Boolean
		{ return _releaseLineCreationData; }
		
		// Create new lines through composition. lines, wrap, etc.
		protected function composeInternal(composeRoot:FlowGroupElement,absStart:int):void
		{
			composeBlockElement(composeRoot,absStart);
		}
		
		/** @private
		 * Compose a single paragraph. If no lines in the paragraph are going to be visible, 
		 * then the TextLines are released for later reuse.
		 */
		protected function composeParagraphElement(elem:ParagraphElement,absStart:int):Boolean
		{
			_curParaElement  = elem;
			_curParaStart    = absStart;
			_curParaFormat = elem.computedFormat;
			
			CONFIG::debug { assert(_curParaStart == elem.getAbsoluteStart(),"composeParagraphElement: bad start"); }

			// Initialize the flag so that if we are composing only part of the paragraph, we will consider it in view.
			// We could examine the earlier part of the paragraph to see if its visible, but for now just assume it
			// might be.
			_paragraphContainsVisibleLines = (_curElementStart + _curElementOffset != _curParaStart) ;
			
			var success:Boolean = composeParagraphElementIntoLines();
			
			var okToRelease:Boolean = true;

			// If no lines in the paragraph are visible, release the paragraph's TextBlock and its lines so they can be reused later
			if (!_paragraphContainsVisibleLines)
			{
				// Lines that are now composed that would not be visible on update, might still be in the display list from
				// a previous update. Don't release in that case.
				var textBlock:TextBlock = elem.getTextBlock();
				var textLine:TextLine;
				for (textLine = textBlock.lastLine; textLine && okToRelease; textLine = textLine.previousLine) 
				{
					if (textLine.parent)
						okToRelease = false;
				}
				if (okToRelease)	// no textlines were in view, go ahead and release them all, starting at the end and working to the start
				{
					for (textLine = textBlock.lastLine; textLine; )
					{
						textBlock.releaseLines(textLine, textLine);
						textLine.userData = null;
						TextLineRecycler.addLineForReuse(textLine);
						if (_textFlow.backgroundManager)
							_textFlow.backgroundManager.removeLineFromCache(textLine);
						textLine = textBlock.lastLine;
					}
					elem.releaseTextBlock();
				}
			}

			// If we didn't release the TextBlock, flush it to save memory (at the cost of performance during editing).
			// This saves a lot of memory in Argo, is a nop on older players. only newer players implement flush	
			if (releaseLineCreationData && !okToRelease)
				elem.releaseLineCreationData();
			
			//draw background and border for paragraph if any - start
			BackgroundManager.collectBlock(_textFlow, elem);
			//end
			
			return success;
		}
		
		protected function getFirstIndentCharPos(paragraph:ParagraphElement):int
		{
			var pos:int = 0;
			var leaf:FlowLeafElement = paragraph.getFirstLeaf();
			while (leaf && (leaf is InlineGraphicElement) && (InlineGraphicElement(leaf).effectiveFloat != Float.NONE))
			{
				pos += leaf.textLength;
				leaf = leaf.getNextLeaf();
			}
			return pos;
		}
		
		/** Compose the lines in the paragraph. 
		 * Updates the _paragraphContainsVisibleLines flag if the paragraph contains at least one visible line.
		 * Returns true if composition should continue, false if all space is used and composition should stop. 
		 */
		protected function composeParagraphElementIntoLines():Boolean
		{
			var result:Boolean = true;
			var textLine:TextLine;
			
			var leftMargin:Number;
			var rightMargin:Number;
			
			var firstLineIndent:Number = 0;
			if (_curParaFormat.direction == Direction.LTR)
			{
				leftMargin = _curParaFormat.paragraphStartIndent;
				rightMargin = _curParaFormat.paragraphEndIndent;
			}
			else
			{
				leftMargin = _curParaFormat.paragraphEndIndent;
				rightMargin = _curParaFormat.paragraphStartIndent;
			}	
			_parcelList.pushLeftMargin(leftMargin);
			_parcelList.pushRightMargin(rightMargin);
			
			var firstIndentCharPos:int = _curParaStart;
			
			if (preProcessILGs(_curElementStart - _curParaStart))
				firstIndentCharPos = getFirstIndentCharPos(_curParaElement) + _curParaStart;

			// loop creating lines_curParaStart
			while (result)
			{
				if (_parcelList.atEnd())
				{
					result = false;
					break;
				}
				
				// Allow derived classes to do processing here
				startLine();

				if (!_forceILGs)		// floats will compose as inline graphics
					processFloatsAtLineStart();
				
				_textIndent = (_curElementStart + _curElementOffset <= firstIndentCharPos) ? _curParaFormat.textIndent : 0;
				
				if (_parcelList.atEnd())
				{
					result = false;
					break;
				}

				// Get the next line
				textLine = composeNextLine();
				if (textLine ==  null)
				{
					result = false;
					break;
				}
				
				CONFIG::debug { assert(_curLine != null, "curLine is null!"); }
				
				// Adjust the coordinates of the line for center/right.  The line is always left aligned.  TextBlock handles justified cases
				// If we're on the last line of a justified paragraph, use the textAlignLast value 
				var textAlignment:String = _curParaFormat.textAlign;
				if (textAlignment == TextAlign.JUSTIFY)
				{
					var location:int = _curLine.location;
					if (location == TextFlowLineLocation.LAST || location == TextFlowLineLocation.ONLY)
						textAlignment = _curParaFormat.textAlignLast;
				}
				switch(textAlignment)
				{
					case TextAlign.START:
						textAlignment = (_curParaFormat.direction == Direction.LTR) ? TextAlign.LEFT : TextAlign.RIGHT;
						break;
					case TextAlign.END:
						textAlignment = (_curParaFormat.direction == Direction.LTR) ? TextAlign.RIGHT : TextAlign.LEFT;
						break; 
				}
				
				// need alignData whenever there is a numberLine - alignData also computes contentBounds which need to take numberlines into account
				var numberLine:TextLine = TextFlowLine.findNumberLine(textLine);
				var needAlignData:Boolean = (numberLine && TextFlowLine.getNumberLineListStylePosition(numberLine) == ListStylePosition.OUTSIDE) || textAlignment == TextAlign.CENTER || textAlignment == TextAlign.RIGHT;
				
				// in argo lines that have tabs must be either START or JUSTIFY
				if (Configuration.playerEnablesArgoFeatures)
				{
					if (textLine["hasTabs"])
					{
						if (_curParaFormat.direction == Direction.LTR)
						{
							if (!numberLine || TextFlowLine.getNumberLineListStylePosition(numberLine) == ListStylePosition.INSIDE)
								needAlignData = false;	// don't align it - let it be left align
							textAlignment = TextAlign.LEFT;
						}
						else
						{
							needAlignData = true;
							textAlignment = TextAlign.RIGHT;
						}
					}
				}

				
				var alignData:AlignData;
				if (needAlignData)
				{
					alignData = createAlignData(_curLine);
					alignData.textLine = textLine;
					alignData.textAlign = textAlignment;
				}

				/* {
				for (var idx:int = 0; idx < curLine.textLine.atomCount; idx++)
				{
				trace(idx.toString()+": beginIndex: " + curLine.textLine.getAtomTextBlockBeginIndex(idx)+ " bidiLevel: "+ curLine.textLine.getAtomBidiLevel(idx) + " bounds: " + curLine.textLine.getAtomBounds(idx));
				}
				} */
				
				// Space before does not apply to the first line, unless LeadingModel.BOX is used
				// Space carried never applies to the first line
				var spaceBefore:Number  = _atColumnStart && (_curParaFormat.leadingModel != LeadingModel.BOX) ? 0 : _curLine.spaceBefore;
				var spaceCarried:Number = _atColumnStart ? 0 : _paragraphSpaceCarried;
				if (spaceBefore != 0 || spaceCarried != 0)
					_parcelList.addTotalDepth(Math.max(spaceBefore, spaceCarried));
				
				_paragraphSpaceCarried = 0;
				if (_verticalSpaceCarried != 0)
					_verticalSpaceCarried = 0;
				_parcelList.addTotalDepth(_curLine.height);

				alignData = calculateLineAlignmentAndBounds(textLine, numberLine, alignData);
				
				if (alignData)
				{
					if (!_alignLines)
						_alignLines = [];
					_alignLines.push(alignData);
					_curLine.alignment = textAlignment;
				}
								
				// textLength is the first character in the next line
				CONFIG::debug { assert(_curParcel.controller.textLength >= 0, "frame has negative composition"); }
				
				if (firstLineIndent != 0)
				{
					if (_curParaFormat.direction == Direction.LTR)
						_parcelList.popLeftMargin(firstLineIndent);
					else
						_parcelList.popRightMargin(firstLineIndent);
					firstLineIndent = 0;
				}

				// The line didn't fit in the parcel when all the floats were factored in.
				// If we're hitting this case, we are now in the next parcel, try laying out 
				// the line there.
				if (!processFloatsAtLineEnd(textLine) || !_curLine)	
				{
					resetLine(textLine);
					continue;
				}
				
				endLine(textLine);

				_lastGoodStart = -1;		// everything committed
				
				// If the line is going to be visible, add it to the list of visible lines we will give to the container
				if (isLineVisible(textLine))
				{
					_curParcel.controller.addComposedLine(textLine);
					_paragraphContainsVisibleLines = true;
				}
				
				if (_parcelList.atEnd())
				{
					result = false;
					break;
				}
				
				_previousLine = textLine;
				
				// advance to the next element, using the rootElement of the container as a limitNode
				// to prevent going past the content bound to this container
				_curElementOffset += _curLine.textLength;
				if (_curElementOffset >= _curElement.textLength)
				{
					// We may have composed ahead over several spans; skip until we match up
					// Loop until we use catch up to where the line we just composed ended (pos).
					// Stop if we run out of elements. Skip empty inline elements, and skip floats
					// that came at the start of the line before any text -- they've already been 
					// processed.
					do{
						import flashx.textLayout.elements.LinkElement;
						if (_curParaElement.hasInteractiveChildren())
						{
							// Find link & interactive mirror element =
							var curElement:FlowElement = _curElement;
							while (curElement && (curElement != _curParaElement))
							{
								// It's a link element?
								if (curElement is LinkElement)
								{
									_curInteractiveObjects[curElement] = curElement;
								}
								else if (curElement.hasActiveEventMirror())
								{
									_curInteractiveObjects[curElement] = curElement;
								}
								curElement = curElement.parent ;
							}
						}

						_curElementOffset -= _curElement.textLength;
						_curElementStart  += _curElement.textLength;
						_curElement = _curElement.getNextLeaf();
						if (_curElementStart == _curParaStart+_curParaElement.textLength)
							break;

						CONFIG::debug { assert(_curElement && _curElement.getParagraph() == _curParaElement,"composeParagraphElement: bad textLength in TextLine"); }
					} while (_curElementOffset >= _curElement.textLength || _curElement.textLength == 0 );
				}
				
				_paragraphSpaceCarried = _curLine.spaceAfter;
				
				// We finished composing the paragraph
				if (_curElementStart == _curParaStart + _curParaElement.textLength)
					break;
			}

			_parcelList.popLeftMargin(leftMargin);
			_parcelList.popRightMargin(rightMargin);
			if (firstLineIndent != 0)		// first line indent pop
			{
				if (_curParaFormat.direction == Direction.LTR)
					_parcelList.popLeftMargin(firstLineIndent);
				else
					_parcelList.popRightMargin(firstLineIndent);
				firstLineIndent = 0;
			}

			_previousLine = null;
			return result;
		}
		
		/** @private */
		protected function createTextLine(
			targetWidth:Number,	// target width we're composing into
			allowEmergencyBreaks:Boolean	// true to allow words to break in the middle of narrow columns, false to force overset
		):TextLine
		{
			var lineOffset:Number = (_curParaFormat.direction == Direction.LTR) ? _lineSlug.leftMargin : _lineSlug.rightMargin;     		
			
			var textLine:TextLine = null;
			textLine = TextLineRecycler.getLineForReuse();
			var textBlock:TextBlock = _curParaElement.getTextBlock();
			if (textLine)
			{
				CONFIG::debug { assert(_textFlow.backgroundManager == null || _textFlow.backgroundManager.getEntry(textLine) === undefined,"createTextLine - Bad TextLine in recycler cache"); }
				textLine = swfContext.callInContext(textBlock["recreateTextLine"],textBlock,[textLine, _previousLine, targetWidth, lineOffset, true]);
			}
			else
			{
				textLine = swfContext.callInContext(textBlock.createTextLine,textBlock,[_previousLine, targetWidth, lineOffset, true]);
			}
			CONFIG::debug { assert(!_previousLine || !textLine || _previousLine.textBlockBeginIndex + _previousLine.rawTextLength == textLine.textBlockBeginIndex, "FTE made non-contiguous TextLine"); }
			if (!allowEmergencyBreaks && textBlock.textLineCreationResult == TextLineCreationResult.EMERGENCY)
				textLine = null;

			// Unable to fit a new line
			if (textLine == null)
				return null;

			CONFIG::debug { assert(_curParaStart == _curParaElement.getAbsoluteStart(),"bad _curParaStart"); }

			_curLine.initialize(_curParaElement, targetWidth, lineOffset-_parcelList.insideListItemMargin, textLine.textBlockBeginIndex + _curParaStart, textLine.rawTextLength, textLine);
			CONFIG::debug { assert(_curLine.targetWidth == targetWidth,"Bad targetWidth"); }

			return textLine;
		}
		
		/** Called when we are about to compose a line. Handler for derived classes to override default behavior. */
		protected function startLine():void
		{
			_workingContentExtent = 0;
			_workingContentHeight = 0;
			_workingContentLogicalExtent = 0;
			_workingParcelIndex = _parcelList.currentParcelIndex;
			_workingTotalDepth = parcelList.totalDepth;
			_workingParcelLogicalTop = NaN;
		}
		
		protected function isLineVisible(textLine:TextLine):Boolean
		{ 
			// isLineVisible completes initializing textLine - so must call it even if we are _measuring
			return _curParcel.controller.testLineVisible(_blockProgression, _controllerVisibleBoundsXTW, _controllerVisibleBoundsYTW, _controllerVisibleBoundsWidthTW, _controllerVisibleBoundsHeightTW, _curLine, textLine) is TextLine; 
		}
		
		/** Called when we are finished composing a line, and it is committed. Handler for derived classes to override default behavior.  */
		protected function endLine(textLine:TextLine):void	// No PMD
		{
			_contentCommittedExtent = Math.max(_contentCommittedExtent, _workingContentExtent);
			_contentCommittedHeight = Math.max(_contentCommittedHeight, _workingContentHeight);
			_contentLogicalExtent = Math.max(_contentLogicalExtent, _workingContentLogicalExtent);

			// if not measuring than contentLogicalExtent needs to match contentCommitedExtent so restarting composition in the middle gets the right extent
			// don't need contentLogicalExtent to exclude things pushing beyond the right margin as alignment is happening as we go
			if (!_measuring)
				_contentLogicalExtent = _contentCommittedExtent;
			if (_pushInFloats)
				_pushInFloats.length = 0;	// zero it out for the next line
			_atColumnStart = false;
			_linePass = 0;
			if (!isNaN(_workingParcelLogicalTop))
				_parcelLogicalTop = _workingParcelLogicalTop;
		}		
		
		protected function resetLine(textLine:TextLine):void
		{
			// if there is a BG manager remove the textLine since it isn't used
			if (_textFlow.backgroundManager)
				_textFlow.backgroundManager.removeLineFromCache(textLine);
			if (_workingParcelIndex != parcelList.currentParcelIndex)		// if we've moved to a new parcel, start over with the line
			{
				_linePass = 0;
				if (_pushInFloats)
					_pushInFloats.length = 0;
			}	
			else
				++_linePass;
			parcelList.addTotalDepth(_workingTotalDepth - _parcelList.totalDepth);
			_workingTotalDepth = parcelList.totalDepth;
		}
		
		protected function preProcessILGs(startPos:int):Boolean
		{
			if (!_curParcel)
				return false;
			
			var foundFloat:Boolean = false;
			
			// Before composing, run through the inline graphics and make sure the content elements are set up correctly
			// We don't support floats when we aren't wrapping the text
			var verticalText:Boolean = (_blockProgression == BlockProgression.RL);
			_forceILGs = (_parcelList.explicitLineBreaks || 
				(verticalText && _curParcel.controller.measureHeight) || (!verticalText && _curParcel.controller.measureWidth));

			for (var leaf:FlowLeafElement = _curParaElement.findLeaf(startPos); leaf; leaf = leaf.getNextLeaf(_curParaElement))
			{
				if (leaf is InlineGraphicElement)
				{
					var inlineGraphic:InlineGraphicElement = leaf as InlineGraphicElement;
					inlineGraphic.setEffectiveFloat(_forceILGs ? Float.NONE : inlineGraphic.computedFloat);
					foundFloat = true;
				}
			}
			return foundFloat;
		}
		
		// Called from composeParagraphElementIntoLines when we are starting to compose a line. Has hooks to handle floats.
		protected function processFloatsAtLineStart():void
		{
			if (_forceILGs)
				return;

			// There are two possible passes through this code for each line. On pass one, all floats at the
			// start of the line are processed, so they appear at the same level with the line (text in the 
			// line will wrap the float). On this pass, processFloatsAtLineEnd may find floats that are in the
			// middle of the line and "hoist" them by adding them to _pushInFloats. This will trigger a second
			// pass through the line, that will call back into this function. On the second pass, the floats
			// at the start have already been added to the parcel's knockout area, but we have to regenerate
			// their impact to the content bounds. Also, we have to compose the floats that were hoisted.
						
			// On the second pass, all floats that are hoisted will be in the array
			if (_pushInFloats && _pushInFloats.length > 0)
			{
				for (var i:int = 0; i < _pushInFloats.length; ++i)
				{
					var pos:int = _pushInFloats[i];
					var leaf:FlowLeafElement = _textFlow.findLeaf(pos);
					CONFIG::debug { assert(leaf is InlineGraphicElement, "pushed an element that is not a float"); }
					if (!composeFloat(leaf as InlineGraphicElement, false))	// If the float does not fit, cancel it and any following hoist requests
						_pushInFloats.length = i;
				}
			} 
		}
		
		// Return true if we tried to hoise some floats and need to retry the line
		protected function processFloatsAtLineEnd(textLine:TextLine):Boolean
		{
			// If there are no anchor points in the line, nothing to do
			if (!textLine.hasGraphicElement && _linePass <= 0)
				return true;
			
			// If the anchor point was pushed out, try again with one less float hoisted.
			if (_pushInFloats && _pushInFloats.length > 0)
			{
				var floatPosition:int = _pushInFloats[_pushInFloats.length - 1];
				if (_curLine.absoluteStart + _curLine.textLength <= floatPosition)
				{
					// Back out all the push in floats, remove the last push in float, and try again
					for (var floatIndex:int = _pushInFloats.length - 1; floatIndex >= 0; --floatIndex)
					{
						floatPosition = _pushInFloats[floatIndex];
						var elem:InlineGraphicElement = _textFlow.findLeaf(floatPosition) as InlineGraphicElement;
						var logicalFloatHeight:Number = (_blockProgression == BlockProgression.RL) ?
							elem.elementWidth + elem.getEffectivePaddingLeft() + elem.getEffectivePaddingRight() :
							elem.elementHeightWithMarginsAndPadding();
						var floatInfo:FloatCompositionData = _curLine.controller.getFloatAtPosition(floatPosition);
						if (floatInfo && floatInfo.absolutePosition == floatPosition)		// check: float might have been skipped if it's not loaded yet, in which case nothing to back out
						{
							var adjustTop:Number = isNaN(_lastLineDescent) ? 0 : _lastLineDescent;
							_curParcel.removeKnockOut(floatInfo.knockOutWidth, floatInfo.depth - adjustTop, floatInfo.depth + logicalFloatHeight, floatInfo.floatType == Float.LEFT);
						}
					}
					_curLine.controller.clearFloatsAt(_pushInFloats[0]);
					--_pushInFloats.length;
					return false;			// we've changed the floats, need to reset the line
				}
			}			
			
			var elementStart:int = _curElementStart;
			var element:FlowLeafElement = _curElement;
			var endPos:int = _curLine.absoluteStart + _curLine.textLength;
			var skipCount:int = 0;
						
			// Advance through the elements in the line, composing any InlineGraphicElements we find
			var hasInlines:Boolean = false;

			while (elementStart < endPos)
			{
				if (element is InlineGraphicElement)
				{
					var inlineGraphic:InlineGraphicElement = InlineGraphicElement(element);
					if (inlineGraphic.computedFloat == Float.NONE || _forceILGs)
						hasInlines = true;
					else 
					{
						if (_linePass == 0)
						{		// Hoist it. We will retry the line, composing this float at the start next time.
							if (!_pushInFloats)
								_pushInFloats = [];
							_pushInFloats.push(elementStart);
						}
						else if (_pushInFloats.indexOf(elementStart) >= 0)	// we hoisted, so skip it
							++skipCount;
						else 	// not hoisted
						{
							if (!composeFloat(inlineGraphic, true))	// Add it in below the line
							{
								advanceToNextParcel();
								return false;		// we need to start the line again in the next container; stop composing now 
							}
						}						
					}
				}
				elementStart += element.textLength;
				element = element.getNextLeaf();
			}
	
			var completed:Boolean = (skipCount >= (_pushInFloats ? _pushInFloats.length : 0));	// true if no floats need to be hoisted
			
			// process inline graphics if we have some, and we're on the last pass
			if (completed && hasInlines)
				processInlinesAtLineEnd(textLine);

			return completed;
		}
		
		// Process inline graphics for our current line.
		protected function processInlinesAtLineEnd(textLine:TextLine):void
		{
			// process inline graphics if we have some, and we're on the last pass
			var elementStart:int = _curElementStart;
			var element:FlowLeafElement = _curElement;
			var endPos:int = _curLine.absoluteStart + _curLine.textLength;
			while (elementStart < endPos)
			{
				if (element is InlineGraphicElement)
				{
					var inlineGraphic:InlineGraphicElement = element as InlineGraphicElement;
					if (inlineGraphic.computedFloat == Float.NONE || _forceILGs)
						composeInlineGraphicElement(inlineGraphic, textLine);
				}
				elementStart += element.textLength;
				element = element.getNextLeaf();
			}
		}
		
		protected function composeInlineGraphicElement(inlineGraphic:InlineGraphicElement, textLine:TextLine):Boolean
		{
			// Add the ILG to list of objects the container will update
			
			var marginAndPaddingX:Number = _blockProgression == BlockProgression.RL ? -inlineGraphic.getEffectivePaddingRight() : inlineGraphic.getEffectivePaddingLeft();
			var marginAndPaddingY:Number = inlineGraphic.getEffectivePaddingTop();

			// Get alpha and matrix values from FTE's inline placeholder
			var fteInline:DisplayObject = inlineGraphic.placeholderGraphic.parent;
			
			_curParcel.controller.addFloatAt(_curParaStart + inlineGraphic.getElementRelativeStart(_curParaElement), inlineGraphic.graphic, Float.NONE, 
				marginAndPaddingX, marginAndPaddingY, fteInline ? fteInline.alpha : 1, fteInline ? fteInline.transform.matrix : null, _parcelList.totalDepth, 0, 
				_curParcel.columnIndex, textLine);
			
			// Check if interactive
			import flashx.textLayout.elements.LinkElement;
			if (_curParaElement.hasInteractiveChildren())
			{
				// Find link & interactive mirror element =
				var curElement:FlowElement = inlineGraphic;
				while (curElement && (curElement != _curParaElement))
				{
					// It's a link element?
					if (curElement is LinkElement)
					{
						_curInteractiveObjects[curElement] = curElement;					
					}
					else if (curElement.hasActiveEventMirror())
					{
						_curInteractiveObjects[curElement] = curElement;
					}
					curElement = curElement.parent ;
				}
			}
			return true;
		}

		/*
		* Compose a floating graphic. Returns false if it doesn't fit in the parcel.
		*
		* @param elem	float we'e composing
		*/
		protected function composeFloat(elem:InlineGraphicElement, afterLine:Boolean):Boolean
		{
			if (elem.elementHeight == 0 || elem.elementWidth == 0)		// can't compose yet -- graphic isn't ready
				return true;
					
			if (_lastGoodStart == -1)
				_lastGoodStart = _curElementStart + _curElementOffset;
			
			var verticalText:Boolean = (_blockProgression == BlockProgression.RL);
			
			// HACK!!!
			//	if the baselineZero is set to ideographicTop, then the descent is the point size (measured from ideographic top)
			//	but in this case we've already factored that into the line height, so we're adding twice. Very confusing.
			var effectiveLastLineDescent:Number = 0;
			if ((afterLine ||  !_atColumnStart) && !isNaN(_lastLineDescent))
				effectiveLastLineDescent = _lastLineDescent;
			
			// If we're composing at the start of the paragraph, we may have spaceBefore (or spaceAfter from the previous paragraph)
			// that we need to take into account when placing the float.
			var spaceBefore:Number = 0;
			if (_curLine && _curParaElement != _curLine.paragraph && !_atColumnStart)
				spaceBefore = Math.max(_curParaElement.computedFormat.paragraphSpaceBefore, _paragraphSpaceCarried);
			var totalDepth:Number = _parcelList.totalDepth + spaceBefore + effectiveLastLineDescent;
			
			if (!_floatSlug)
				_floatSlug = new Slug();
			
			// See if it fits. If so, update the state to show the change. If not, remove the item.
			var logicalFloatWidth:Number;
			var logicalFloatHeight:Number;
			if (verticalText)
			{
				logicalFloatWidth = elem.elementHeight + elem.getEffectivePaddingTop() + elem.getEffectivePaddingBottom();
				logicalFloatHeight = elem.elementWidth + elem.getEffectivePaddingLeft() + elem.getEffectivePaddingRight();
			}
			else
			{
				logicalFloatWidth = elem.elementWidthWithMarginsAndPadding();
				logicalFloatHeight = elem.elementHeightWithMarginsAndPadding();
			}			
			
			var floatPosition:int = elem.getAbsoluteStart();
			var floatFits:Boolean = _parcelList.fitFloat(_floatSlug, totalDepth, logicalFloatWidth, logicalFloatHeight);
			
			// If the float is too wide but it fits in height, AND there is no text or other floats before it, allow it to overlap
			// the column so it doesn't go overset.
			if (!floatFits && (_curParcel.fitAny || _curParcel.fitsInHeight(totalDepth, int(logicalFloatHeight))) && (!_curLine || _curLine.absoluteStart == floatPosition || afterLine))
				floatFits = true;
			
			if (floatFits)
			{
				var floatType:String = elem.computedFloat;
				if (floatType == Float.START)
					floatType = (_curParaFormat.direction == Direction.LTR) ? Float.LEFT : Float.RIGHT;
				else if (floatType == Float.END)
					floatType = (_curParaFormat.direction == Direction.LTR) ? Float.RIGHT : Float.LEFT;
				
				var floatRect:Rectangle = calculateFloatBounds(elem, verticalText, floatType);
				
				// Take it into account for content bounds
				if (verticalText)
				{
					// mjzhang : Fix for bug#2898924 TLF reports incorrect content height after composition when floats are used with padding
					_workingContentExtent = Math.max(_workingContentExtent, floatRect.bottom + elem.getEffectivePaddingLeft() + elem.getEffectivePaddingRight());
					_workingContentHeight = Math.max(_workingContentHeight, _floatSlug.depth + floatRect.width + elem.getEffectivePaddingTop() + elem.getEffectivePaddingBottom());
					_workingContentLogicalExtent = Math.max(_workingContentLogicalExtent, floatRect.bottom);
					_accumulatedMinimumStart = Math.min(_accumulatedMinimumStart, floatRect.y);
				}
				else
				{
					// mjzhang : Fix for bug#2898924 TLF reports incorrect content height after composition when floats are used with padding
					_workingContentExtent = Math.max(_workingContentExtent, floatRect.right + elem.getEffectivePaddingLeft() + elem.getEffectivePaddingRight());
					_workingContentHeight = Math.max(_workingContentHeight, _floatSlug.depth + floatRect.height + elem.getEffectivePaddingTop() + elem.getEffectivePaddingBottom());
					_workingContentLogicalExtent = Math.max(_workingContentLogicalExtent, floatRect.right);
					_accumulatedMinimumStart = Math.min(_accumulatedMinimumStart, floatRect.x);
				}
				if (floatPosition == _curParcelStart)
					 _workingParcelLogicalTop = _floatSlug.depth;
				
				// floatRect is returned at new (x, y) location, sized to fit the column.
				var knockOutWidth:Number = ((floatType == Float.LEFT) ? _floatSlug.leftMargin : _floatSlug.rightMargin) + logicalFloatWidth;
				
				var adjustTop:Number = isNaN(_lastLineDescent) ? 0 : _lastLineDescent;
				_curParcel.knockOut(knockOutWidth, _floatSlug.depth - adjustTop, _floatSlug.depth + logicalFloatHeight, floatType == Float.LEFT);
				
				// Add info about the float so we can regenerate the knock out area if necessary for an incremental compose, as well as take care of update, etc.
				_curParcel.controller.addFloatAt(floatPosition, elem.graphic, floatType, floatRect.x, floatRect.y, elem.computedFormat.textAlpha, null, 
					_floatSlug.depth, knockOutWidth, _curParcel.columnIndex, _curParcel.controller.container);
				
				CONFIG::debug { _curParcel.controller.getFloatAt(_curParcel.controller.numFloats - 1).displacedVertically = totalDepth != _floatSlug.depth; } 
			}
			
		return floatFits;
		}
		
		private function calculateFloatBounds(elem:InlineGraphicElement, verticalText:Boolean, floatType:String):Rectangle
		{
			// We need to place it on the left or right side, sized to fit the graphic
			var floatRect:Rectangle = new Rectangle();
			if (verticalText)
			{
				floatRect.x = ((_curParcel.right - _floatSlug.depth) - elem.elementWidth) - elem.getEffectivePaddingRight();
				floatRect.y = (floatType == Float.LEFT) ? 
					(_curParcel.y + _floatSlug.leftMargin + elem.getEffectivePaddingTop()) : 
					(_curParcel.bottom - _floatSlug.rightMargin - elem.getEffectivePaddingBottom() - elem.elementHeight);
				floatRect.width = elem.elementWidth;
				floatRect.height = elem.elementHeight;
			}
			else
			{
				floatRect.x = (floatType == Float.LEFT) ? 
					_curParcel.x + _floatSlug.leftMargin + elem.getEffectivePaddingLeft() : 
					_curParcel.right - _floatSlug.rightMargin - elem.getEffectivePaddingRight() - elem.elementWidth;
				floatRect.y = _curParcel.y + _floatSlug.depth + elem.getEffectivePaddingTop();
				floatRect.width = elem.elementWidth;
				floatRect.height = elem.elementHeight;
			}
			return floatRect;
		}
		
		private function calculateLineWidthExplicit(textLine:TextLine):Number
			// Returns the content bounds width of a line set with explicit lineBreaks
		{
			var isRTL:Boolean = _curParaElement.computedFormat.direction == Direction.RTL;
			var lastAtom:int = textLine.atomCount - 1;
			// If we're at the end of the paragraph, don't count the terminator
			var endOfParagraph:Boolean = _curLine.absoluteStart + _curLine.textLength == _curParaStart + _curParaElement.textLength;
			if (endOfParagraph && !isRTL)
				--lastAtom;	// can go negative if just the terminator.  in that case use left/top of atom zero
			var bounds:Rectangle = textLine.getAtomBounds(lastAtom >= 0 ? lastAtom : 0);	// get rightmost atom bounds
			var lineWidth:Number = (_blockProgression == BlockProgression.TB) 
				? (lastAtom >= 0 ? bounds.right : bounds.left)
				: (lastAtom >= 0 ? bounds.bottom : bounds.top);
			if (isRTL)	// in right to left, get leftmost atom bounds, that has trailing space
			{
				// in RTL strip the width of the paragraph terminator from the front
				bounds = textLine.getAtomBounds(lastAtom != 0 && endOfParagraph ? 1 : 0);						
				lineWidth -= (_blockProgression == BlockProgression.TB) ? bounds.left : bounds.top;
			}
			textLine.flushAtomData();
			return lineWidth;
		}

		private function getRightSideGap(curLine:TextFlowLine, aligned:Boolean):Number
		{
			var elem:FlowGroupElement = curLine.paragraph;
			var paraFormat:ITextLayoutFormat = elem.computedFormat;
			
			var rightSideGap:Number = paraFormat.direction == Direction.RTL ? paraFormat.paragraphStartIndent : paraFormat.paragraphEndIndent;
			if (paraFormat.direction == Direction.RTL && (curLine.location & TextFlowLineLocation.FIRST))
			{
				// need to be careful because leftaligned paragraphs need to be exactly right coming out of this routine
				// if (aligned && (_blockProgression == BlockProgression.TB && !curLine.controller.measureWidth || _blockProgression == BlockProgression.RL && !curLine.controller.measureHeight))
				rightSideGap += paraFormat.textIndent;
				
				if (curLine.hasNumberLine && elem.getParentByType(ListItemElement).computedFormat.listStylePosition == ListStylePosition.INSIDE)
				{
					var textLine:TextLine = curLine.getTextLine(true);
					var numberLine:TextLine = TextFlowLine.findNumberLine(textLine)
					rightSideGap += TextFlowLine.getNumberLineInsideLineWidth(numberLine);
				}
			}

			do 
			{
				rightSideGap += _blockProgression == BlockProgression.TB ? elem.getEffectivePaddingRight() + elem.getEffectiveBorderRightWidth() + elem.getEffectiveMarginRight() : elem.getEffectivePaddingBottom() + elem.getEffectiveBorderBottomWidth() + elem.getEffectiveMarginBottom();
				elem = elem.parent;
			} while (!(elem is TextFlow))
			return rightSideGap;
		}
		
		private function getLeftSideGap(curLine:TextFlowLine):Number
		{
			var elem:FlowGroupElement = curLine.paragraph;
			var paraFormat:ITextLayoutFormat = elem.computedFormat;
			
			var leftSideGap:Number = paraFormat.direction == Direction.LTR ? paraFormat.paragraphStartIndent : paraFormat.paragraphEndIndent;
			
			if (paraFormat.direction == Direction.LTR && (curLine.location & TextFlowLineLocation.FIRST))
			{
				// recording leftSideIndent is here because there is an extra alignment step for non-left aligned paragraphs
				leftSideGap += paraFormat.textIndent;
				
				if (curLine.hasNumberLine && elem.getParentByType(ListItemElement).computedFormat.listStylePosition == ListStylePosition.INSIDE)
				{
					var textLine:TextLine = curLine.getTextLine(true);
					var numberLine:TextLine = TextFlowLine.findNumberLine(textLine)
					leftSideGap += TextFlowLine.getNumberLineInsideLineWidth(numberLine);
				}
			}
			
			do 
			{
				leftSideGap += _blockProgression == BlockProgression.TB ? elem.getEffectivePaddingLeft() + elem.getEffectiveBorderLeftWidth() +  elem.getEffectiveMarginLeft() : elem.getEffectivePaddingTop() + elem.getEffectiveBorderTopWidth() + elem.getEffectiveMarginTop();
				elem = elem.parent;
			} while (!(elem is TextFlow))
			return leftSideGap;
		}
		
		/** @private */
		private function calculateLineAlignmentAndBounds(textLine:TextLine, numberLine:TextLine, alignData:AlignData):AlignData
		{
			var lineWidth:Number = textLine.textWidth;
			if (GlobalSettings.alwaysCalculateWhitespaceBounds || _parcelList.explicitLineBreaks)
				lineWidth = calculateLineWidthExplicit(textLine);
			
			var rightSideGap:Number = _lineSlug.rightMargin;
			var leftSideGap:Number = _lineSlug.leftMargin;
			var delta:Number = 0;
			
			CONFIG::debug 
			{ 
				if (textLine.userData != null && _curParcel.controller.numFloats == 0 && ! _curLine.paragraph.isInTable())
				{
					var tmpRightGap:Number = getRightSideGap(_curLine, _curLine.alignment != TextAlign.LEFT);
					assert(rightSideGap == getRightSideGap(_curLine, _curLine.alignment != TextAlign.LEFT),"mismatched rightSideGap"); 
					
					var tmpLeftGap:Number = getLeftSideGap(_curLine);
					assert(leftSideGap  == getLeftSideGap(_curLine), "mismatched leftSideGap");
				}
			}
			
			CONFIG::debug { assert(textLine.userData == null || textLine.userData == _curLine,"Bad TextFlowLine in calculateLineAlignmentAndBounds"); }

			if (alignData)
			{
				alignData.rightSideGap = rightSideGap;
				alignData.leftSideGap = leftSideGap;
				alignData.lineWidth = lineWidth;
				alignData.textIndent = _curParaFormat.textIndent;
				
				var extraSpace:Number;
				var coord:Number;
				var adjustedLogicalRight:Number;
				
				
				if (_blockProgression == BlockProgression.TB)
				{		
					CONFIG::debug { assert(_curParcel.controller.measureWidth == _measuring,"Bad measuring initialization"); }
					if (!_measuring)
					{
						var textLineWidth:Number = textLine.textWidth;
						/*if (numberLine && TextFlowLine.getNumberLineListStylePosition(numberLine) == ListStylePosition.INSIDE)
							textLineWidth += TextFlowLine.getNumberLineInsideLineWidth(numberLine);*/
						extraSpace = _curParcel.width - leftSideGap - rightSideGap - textLineWidth;
						if (alignData.textAlign != TextAlign.LEFT)
						{
							delta = (alignData.textAlign == TextAlign.CENTER ? extraSpace / 2 : extraSpace);
							coord = _curParcel.x + leftSideGap + delta;
						}
						else	// used for RTL numberLine alignment of a left aligned textLine
							coord = _curParcel.x + leftSideGap + extraSpace;
						
						if (alignData.textAlign != TextAlign.LEFT)
						{
							_curLine.x = coord;
							textLine.x = coord;
						}
						else
							textLine.x = _curLine.x;
						
						if (numberLine && TextFlowLine.getNumberLineListStylePosition(numberLine) == ListStylePosition.OUTSIDE)
						{
							numberLine.x = computeNumberLineAlignment(alignData,textLine.textWidth,textLine.x,numberLine,coord,delta,extraSpace);
							CONFIG::debug { assert(alignData.textFlowLine == _curLine, "Mismatched alignData/curLine"); }
							_curLine.numberLinePosition = numberLine.x;
						}
						
						releaseAlignData(alignData);
						alignData = null;
					}
				}
				else 
				{
					CONFIG::debug { assert(_curParcel.controller.measureHeight == _measuring,"Bad measuring initialization"); }
					
					if (!_measuring)
					{						
						extraSpace = _curParcel.height - leftSideGap - rightSideGap -  textLine.textWidth;
						if (alignData.textAlign != TextAlign.LEFT)
						{
							delta = (alignData.textAlign == TextAlign.CENTER ? extraSpace / 2 : extraSpace);
							coord = _curParcel.y + leftSideGap + delta;
						}
						else	// used for RTL numberLine alignment of a left aligned textLine
							coord = _curParcel.y + leftSideGap + extraSpace;							
						
						if (alignData.textAlign != TextAlign.LEFT)
						{					
							_curLine.y = coord;
							textLine.y = coord;
						}
						else
							textLine.y = _curLine.y;
							
						if (numberLine && TextFlowLine.getNumberLineListStylePosition(numberLine) == ListStylePosition.OUTSIDE)
						{
							numberLine.y = computeNumberLineAlignment(alignData,textLine.textWidth,textLine.y,numberLine,coord,delta,extraSpace);
							CONFIG::debug { assert(alignData.textFlowLine == _curLine, "Mismatched alignData/curLine"); }
							_curLine.numberLinePosition = numberLine.y;
						}
	
						releaseAlignData(alignData);
						alignData = null;
					}	
				}
			}
			
			// extent from the left margin
			var lineExtent:Number = lineWidth + leftSideGap + rightSideGap + delta;
			// logical extent of the line
			_curLine.lineExtent = lineExtent;
			_workingContentLogicalExtent = Math.max(_workingContentLogicalExtent, lineExtent);
			_curLine.accumulatedLineExtent = Math.max(_contentLogicalExtent, _workingContentLogicalExtent);
			if (!alignData)
			{				
				// calculate this number - we're not measuring - otherwise its not really interesting
				var edgeAdjust:Number = _curParaFormat.direction == Direction.LTR ? Math.max(_curLine.lineOffset, 0) : _curParaFormat.paragraphEndIndent;
				edgeAdjust = _blockProgression == BlockProgression.RL ? _curLine.y - edgeAdjust : _curLine.x - edgeAdjust;
				if (numberLine)
				{
					var numberLineStart:Number = _blockProgression == BlockProgression.TB ? numberLine.x+_curLine.x : numberLine.y+_curLine.y;
					edgeAdjust = Math.min(edgeAdjust,numberLineStart);
					
					if (TextFlowLine.getNumberLineListStylePosition(numberLine) == ListStylePosition.OUTSIDE)
					{
						var numberLineMaxExtent:Number = numberLineStart + TextFlowLine.getNumberLineInsideLineWidth(numberLine);
						numberLineMaxExtent -= lineExtent; //  + 2 * (_blockProgression == BlockProgression.RL ? _curLine.y : _curLine.x);
						/*numberLineMaxExtent -= _blockProgression == BlockProgression.RL ? _curLine.y : _curLine.x;
						numberLineMaxExtent -= lineExtent-_curLine.x;*/
						if (numberLineMaxExtent > 0)
							delta += numberLineMaxExtent;
					}
				}
				_workingContentExtent = Math.max(_workingContentExtent, lineWidth + leftSideGap + Math.max(0,rightSideGap) + delta);

				_curLine.accumulatedMinimumStart = _accumulatedMinimumStart = Math.min(_accumulatedMinimumStart, edgeAdjust);
			}
	
			// first line
			if (_curLine.absoluteStart == _curParcelStart && isNaN(_workingParcelLogicalTop))
				_workingParcelLogicalTop = computeTextFlowLineMinimumLogicalTop(_curLine,textLine);

			return alignData;
		}
		
		/** @private - align the numberline so that its position is independent of the textAlign property */
		tlf_internal static function computeNumberLineAlignment(alignData:AlignData,textLineWidth:Number,textLineOffset:Number,numberLine:TextLine,coord:Number,delta:Number,extraSpace:Number):Number
		{
			var rslt:Number;
			
			if (alignData.textAlign == TextAlign.CENTER)
			{
				if (TextFlowLine.getNumberLineParagraphDirection(numberLine) == Direction.LTR)
					rslt = -(numberLine.textWidth + TextFlowLine.getListEndIndent(numberLine) + delta) - alignData.textIndent;
				else
					rslt = textLineWidth + TextFlowLine.getListEndIndent(numberLine) + (TextFlowLine.getNumberLineInsideLineWidth(numberLine)-numberLine.textWidth) + (coord - delta + extraSpace - textLineOffset) + alignData.textIndent;							
			}
			else if (alignData.textAlign == TextAlign.RIGHT)
			{
				if (TextFlowLine.getNumberLineParagraphDirection(numberLine) == Direction.LTR)
					rslt = -(numberLine.textWidth + TextFlowLine.getListEndIndent(numberLine) + delta) - alignData.textIndent;
				else
					rslt = textLineWidth + TextFlowLine.getListEndIndent(numberLine) + (TextFlowLine.getNumberLineInsideLineWidth(numberLine)-numberLine.textWidth) + alignData.textIndent;
			}
			else
			{
				if (TextFlowLine.getNumberLineParagraphDirection(numberLine) == Direction.LTR)
					rslt = -(numberLine.textWidth + TextFlowLine.getListEndIndent(numberLine)) - alignData.textIndent;
				else
					rslt = textLineWidth + TextFlowLine.getListEndIndent(numberLine) + (TextFlowLine.getNumberLineInsideLineWidth(numberLine)-numberLine.textWidth) + (coord - textLineOffset) + alignData.textIndent;
			}
			return rslt;
		}


		protected function composeNextLine():TextLine
		{
			CONFIG::debug { throw new Error("composeNextLine requires override"); }		
			return null;
		}
		
		// fills in _lineSlug
		protected function fitLineToParcel(textLine:TextLine, isNewLine:Boolean, numberLine:TextLine):Boolean
		{
			var composeYCoord:Number = _lineSlug.depth;
			_curLine.setController(_curParcel.controller,_curParcel.columnIndex);
			
			// If we are at the last parcel, we let text be clipped if that's specified in the configuration. At the point where no part of text can be accommodated, we go overset.
			// If we are not at the last parcel, we let text flow to the next parcel instead of getting clipped.
			var spaceBefore:Number = Math.max(_curLine.spaceBefore, _paragraphSpaceCarried);
			for (;;)
			{
				finishComposeLine(textLine, numberLine);	
				if (_parcelList.getLineSlug(_lineSlug, spaceBefore + (_parcelList.atLast() && _textFlow.configuration.overflowPolicy != OverflowPolicy.FIT_DESCENDERS ? _curLine.height-_curLine.ascent : _curLine.height+_curLine.descent), 1, _textIndent, _curParaFormat.direction == Direction.LTR))
				{
					// slug has moved, but the line is the same width; recalculate line position 
					// if the line width has changed, fitLineToParcel return false, and we regenerate the line
					if ((Twips.to(_lineSlug.width) == _curLine.outerTargetWidthTW) && (_lineSlug.depth != composeYCoord))
					{
						finishComposeLine(textLine, numberLine);	
					}
					break;
				}
				spaceBefore = _curLine.spaceBefore;
				if (_pushInFloats && _parcelList.currentParcel.fitAny && _pushInFloats.length > 0)		// force line to fit because the float fits, and we can scroll to the line
					break;
				
				for (;;)
				{
					advanceToNextParcel();
					if (!_curLine || _parcelList.atEnd() || _parcelList.currentParcel.isTableParcel)
						return false;
					if (_parcelList.getLineSlug(_lineSlug,0, 1, _textIndent, _curParaFormat.direction == Direction.LTR))
					{
						composeYCoord = _lineSlug.depth;
						break;
					}
				}
				_curLine.setController(_curParcel.controller,_curParcel.columnIndex);
			}
			
			// check to see if we got a good line
			if (Twips.to(_lineSlug.width) != _curLine.outerTargetWidthTW)
				return false;
			
			if(isNewLine)
			{
				if (numberLine)
					TextFlowLine.initializeNumberLinePosition(numberLine, _listItemElement, _curParaElement, textLine.textWidth);
				_curLine.createAdornments(_blockProgression,_curElement,_curElementStart, textLine, numberLine);
			}
			
			return true;
		}
		
		
		// Calculate paramters used in line height calculations for _curLine. The meaning of these parameters depends on the leading model (_curLineLeadingModel).
		// For LeadingModel.BOX, the first parameter is the bottom of the CSS line box, while the second parameter is the top of the CSS line box (both relative to Roman Baseline)
		// For all other leading models, the first parameter is the maximum computed lineHeight. The second parameter is ignored (0).
		// In all cases, _curLineLeading is updated to equal the first paramter, while the second parameter is returned.
		protected function calculateLeadingParameters (curElement:FlowLeafElement, curElementStart:int, numberLine:TextLine=null):Number
		{
			var effectiveListMarkerFormat:ITextLayoutFormat;
			if (numberLine)
				effectiveListMarkerFormat = TextFlowLine.getNumberLineSpanFormat(numberLine);
			
			if (_curLineLeadingModel == LeadingModel.BOX)
			{
				// Get the CSS "line box" for the current line. 
				var lineBox:Rectangle = _curLine.getCSSLineBox(_blockProgression, curElement, curElementStart, _textFlow.flowComposer.swfContext, effectiveListMarkerFormat, numberLine);
				_curLineLeading = lineBox ? lineBox.bottom : 0;
				return lineBox ? -lineBox.top : 0;	 
			}
			
			_curLineLeading = _curLine.getLineLeading(_blockProgression,curElement,curElementStart);
				
			// adjust for the NumberLine
			if (effectiveListMarkerFormat)
				_curLineLeading = Math.max(_curLineLeading,TextLayoutFormat.lineHeightProperty.computeActualPropertyValue(effectiveListMarkerFormat.lineHeight, effectiveListMarkerFormat.fontSize));
			
			return 0;
		}
	
		// Calculate the logical vertical position of the line, taking into account the leading (or firstBaselineOffset), 
		// and setting up the lineHeight and leading model info for the next line.
		protected function finishComposeLine(curTextLine:TextLine, numberLine:TextLine):void
		{      	
			var lineHeight:Number = 0;
			//replace X and Y with rise and run.  
			//	rise - the offset within a line relative to block progressiong.  For RL this is X, for TB Y
			//	run - the indentation of the line.  For RL this is Y, TB X
			var rise:Number;
			var run:Number;
			if (_blockProgression == BlockProgression.RL)
			{
				rise = (_curParcel.x + _curParcel.width) - _lineSlug.depth;
				run = _curParcel.y;
			}
			else
			{
				rise = _curParcel.y + _lineSlug.depth;
				run = _curParcel.x;
			}
			
		/*	if (_curParaFormat.direction == Direction.LTR)
				run += _curLine.lineOffset;
			else 
				run += _curLine.outerTargetWidth - _curLine.lineOffset - _curLine.targetWidth; */
			run += _lineSlug.leftMargin;
			
			_curLineLeadingModel = _curParaElement.getEffectiveLeadingModel();
			// Calculate leading parameters: _curLineLeading and secondaryLeadingParameter (the latter is currently only used for LeadingModel.BOX) 
			var secondaryLeadingParameter:Number = calculateLeadingParameters (_curElement, _curElementStart, numberLine);
			
			if (_curLineLeadingModel == LeadingModel.BOX)
			{
				lineHeight += _atColumnStart ? 0 : _lastLineDescent; // contribution from the previous line (if one exists): its "effective" descent
				lineHeight += secondaryLeadingParameter;			 // contribution from this line: the top of the CSS line box 	
			}
			else
			{
				var containerAttrs:ITextLayoutFormat = _curParcel.controller.computedFormat;		
				var baselineType:Object = BaselineOffset.LINE_HEIGHT;
				if (_atColumnStart)
				{
					// If we're at the top of the column, we need to check the container properties to see
					// what the firstBaselineOffset should be. This tells us how to treat the line.
					// However, when vertical alignment is center or bottom, ignore the firstBaselineOffset setting
					// and treat them as the BaselineOffset.AUTO case
					if (containerAttrs.firstBaselineOffset != BaselineOffset.AUTO && containerAttrs.verticalAlign != VerticalAlign.BOTTOM && containerAttrs.verticalAlign != VerticalAlign.MIDDLE) 
					{
						baselineType = containerAttrs.firstBaselineOffset;
						// The first line's offset is specified relative firstBaselineOffsetBasis, which used to be, but no longer is, a container-level property
						// Now it is implicitly deduced based on the container-level locale in the following manner: 
						// IDEOGRAPHIC_BOTTOM for ja and zh locales (this is the same locale set for which the default LeadingModel is IDEOGRAPHIC_TOP_DOWN)
						// ROMAN for all other locales
						var firstBaselineOffsetBasis:String = LocaleUtil.leadingModel(containerAttrs.locale) == LeadingModel.IDEOGRAPHIC_TOP_DOWN ?  TextBaseline.IDEOGRAPHIC_BOTTOM : TextBaseline.ROMAN;
						lineHeight -= curTextLine.getBaselinePosition(firstBaselineOffsetBasis);		
					}
					else
					{
						if (_curLineLeadingModel == LeadingModel.APPROXIMATE_TEXT_FIELD)
						{
							// Reinterpret AUTO when APPROXIMATE_TEXT_FIELD leading model is used. 
							// Align the "enhanced ascent" (an approximation of TextField's notion of ascent baseline, 
							// which differs from FTEs notion of the same by an amount equal to the line's descent) with the container top inset
							lineHeight += Math.round(curTextLine.descent) + Math.round(curTextLine.ascent);
							
							// Ensure Roman baseline will fall at an integer position. This is desirable for all leading models, 
							// but only APPROXIMATE_TEXT_FIELD requires it now. In a future release, this code can be moved below and lineX/lineY rounded off directly. 
							if (_blockProgression == BlockProgression.TB)
								lineHeight = Math.round(rise + lineHeight) - rise;
							else
								lineHeight = rise - Math.round(rise - lineHeight);
							
							baselineType = 0; // No further adjustments    
						}
						else
						{
							// The AUTO case requires aligning line top to container top inset. This efect can be achieved by using firstBaselineOffset=ASCENT
							// and firstBaselineOffsetBasis=ROMAN 
							baselineType = BaselineOffset.ASCENT;
							
							if(curTextLine.hasGraphicElement)
							{
								var firstLineAdjustment:LeadingAdjustment = getLineAdjustmentForInline(curTextLine, _curLineLeadingModel, true);
								if(firstLineAdjustment != null)
								{
									if(_blockProgression == BlockProgression.RL)
									{
										firstLineAdjustment.rise = -(firstLineAdjustment.rise);
									}
									_curLineLeading += firstLineAdjustment.leading;
									rise += firstLineAdjustment.rise;
								}
							}
							
							lineHeight -= curTextLine.getBaselinePosition(flash.text.engine.TextBaseline.ROMAN);
						}
					}
				}
						
				//getTextLineTypographicAscent
				if (baselineType == BaselineOffset.ASCENT)
				{
					CONFIG::debug { assert(_curElementStart == _textFlow.findLeaf(_curLine.absoluteStart).getAbsoluteStart(), "Bad _curElementStart"); }
					var curLineAscent:Number = _curLine.getLineTypographicAscent(_curElement,_curElementStart,curTextLine);
					if (numberLine)
					{
						// if numberlines support ilgs then additional information will be needed here to compute the typographic ascent
						CONFIG::debug { assert(!numberLine.hasGraphicElement, "numberline with graphic element unexpected"); }
						lineHeight += Math.max(curLineAscent,TextFlowLine.getTextLineTypographicAscent(numberLine,null,0,0));
					}
					else
						lineHeight += curLineAscent;
				}
				else 
				{
					if (baselineType == BaselineOffset.LINE_HEIGHT)
					{
						if (_curLineLeadingModel == LeadingModel.APPROXIMATE_TEXT_FIELD)
						{
							// Position the "enhanced ascent" (see above) at a distance of leading from the previous line's descent
							lineHeight += Math.round(_lastLineDescent) + Math.round(curTextLine.ascent) + Math.round(curTextLine.descent) + Math.round(_curLineLeading);
						}
						else if (_curLineLeadingModel == LeadingModel.ASCENT_DESCENT_UP)
						{
							lineHeight += _lastLineDescent + curTextLine.ascent + _curLineLeading;
						} 
						else
						{
							// Leading direction is irrelevant for the first line. Treat it as (UP, UP)
							// TODO-9/3/2008-It may be better to handle Middle/Last lines separately because we know that the previous line also belongs in the same para 
							var curLeadingDirectionUp:Boolean = _atColumnStart ? true : ParagraphElement.useUpLeadingDirection(_curLineLeadingModel);
							
							var prevLeadingDirectionUp:Boolean = _atColumnStart || _lastLineLeadingModel == "" ? true : 
								ParagraphElement.useUpLeadingDirection(_lastLineLeadingModel);
							
							var prevLineFirstElement:FlowLeafElement;
							
							if (curLeadingDirectionUp)
							{	
								//TODO-9/12/2008-The above behavior is the InDesign behavior but raises some questions about selection shapes.
								//Should selection code associate leading with the influencing line? That would be weird. InDesign only
								//supports alternate leading directions in the J feature set, where leading is never included in selection,
								//so this question does not arise. We take the unambiguous route: ignore leading DOWN at the end of a para
								lineHeight += _curLineLeading;
							}
							else
							{
								if (!prevLeadingDirectionUp)
								{
									// Same leading directions; use previous line's leading setting.
									lineHeight += _lastLineLeading;
								}
								else
								{
									// Make NO leading adjustments. Set lines solid.
									lineHeight += _lastLineDescent + curTextLine.ascent;
								}
							}	
						}
					}
					else
						lineHeight += Number(baselineType);		// fixed offset
				}
				
				//baselineType will be BaselineOffset.ASCENT for fixed leading
				if(curTextLine.hasGraphicElement && baselineType != BaselineOffset.ASCENT)
				{
					var adjustment:LeadingAdjustment = getLineAdjustmentForInline(curTextLine, _curLineLeadingModel, false);
					if(adjustment != null)
					{	
						if(_blockProgression == BlockProgression.RL)
						{
							adjustment.rise = -(adjustment.rise);
						}
						_curLineLeading += adjustment.leading;
						rise += adjustment.rise;
					}
				}
			}
            
            _firstLineDescentAndLeading = _blockProgression == BlockProgression.RL ? -(lineHeight) : lineHeight - curTextLine.ascent;
            
			//don't know why, but ascent only needs to be removed from horizontal text.  Hmm, that seems
			//odd to me - gak 12.15.09
			//NOTE:9/27/10 - The ascent is added back for horizontal text in TextFlowLine.createShapeY
			rise += _firstLineDescentAndLeading;
			
			// handle space before by adjusting y position of line
			// Space before does not apply to the first line, unless LeadingModel.BOX is used
			// Space carried never applies to the first line
			var spaceBefore:Number  = _atColumnStart && (_curLineLeadingModel != LeadingModel.BOX) ? 0 : _curLine.spaceBefore;
			var spaceCarried:Number = _atColumnStart ? 0 : _paragraphSpaceCarried;
			if (spaceBefore != 0 || spaceCarried != 0)
			{
				var spaceAdjust:Number = Math.max(spaceBefore, spaceCarried);	
				rise += _blockProgression == BlockProgression.RL ? -spaceAdjust :spaceAdjust;
			}
			
			if(_blockProgression == BlockProgression.TB)
				_curLine.setXYAndHeight(run,rise,lineHeight);
			else
				_curLine.setXYAndHeight(rise,run,lineHeight);
		}

		/** Delayed application of alignment when measuring */
		private function applyTextAlign(effectiveParcelWidth:Number):void
		{
			var textLine:TextLine;
			var numberLine:TextLine;
			var line:TextFlowLine;
			var alignData:AlignData;
			
			var coord:Number;
			var delta:Number;
			var adjustedLogicalRight:Number;
			var extraSpace:Number;
			var leftSideGap:Number;
			var rightSideGap:Number;
			var numberLineMetric:Number
			
			if (_blockProgression == BlockProgression.TB)
			{
				for each (alignData in _alignLines) 
				{
					textLine = alignData.textLine;
					
					rightSideGap = alignData.rightSideGap;
					leftSideGap = alignData.leftSideGap;
					
					extraSpace = effectiveParcelWidth - leftSideGap - rightSideGap -  textLine.textWidth;
					delta = (alignData.textAlign == TextAlign.CENTER ? extraSpace / 2 : extraSpace);
					coord = _curParcel.x + leftSideGap + delta;
					
					if (alignData.textAlign != TextAlign.LEFT)
					{
						line = textLine.userData as TextFlowLine;
						if (line)
							line.x = coord;
						textLine.x = coord;
					}

					adjustedLogicalRight = alignData.lineWidth + coord + Math.max(rightSideGap, 0);
					_parcelRight = Math.max(adjustedLogicalRight , _parcelRight);
					
					numberLine = TextFlowLine.findNumberLine(textLine);
					if (numberLine && TextFlowLine.getNumberLineListStylePosition(numberLine) == ListStylePosition.OUTSIDE)
					{
						numberLine.x = computeNumberLineAlignment(alignData,textLine.textWidth,textLine.x,numberLine,coord,delta,extraSpace);
						alignData.textFlowLine.numberLinePosition = numberLine.x;
						// adjust parcel bounds for the numberLine
						
						// the start
						numberLineMetric = numberLine.x+textLine.x;
						if (numberLineMetric < _parcelLeft)
							_parcelLeft = numberLineMetric;
						
						// the extent
						numberLineMetric += TextFlowLine.getNumberLineInsideLineWidth(numberLine);
						if (numberLineMetric > _parcelRight)
							_parcelRight = numberLineMetric;
					}
				}
			}
			else
			{
				for each (alignData in _alignLines) 
				{
					textLine = alignData.textLine;

					rightSideGap = alignData.rightSideGap;
					leftSideGap = alignData.leftSideGap;
					
					extraSpace = effectiveParcelWidth - leftSideGap - rightSideGap -  textLine.textWidth;
					delta = (alignData.textAlign == TextAlign.CENTER ? extraSpace / 2 : extraSpace);
					coord = _curParcel.y + leftSideGap + delta;
					
					if (alignData.textAlign != TextAlign.LEFT)
					{
						line = textLine.userData as TextFlowLine;
						if (line)
							line.y = coord;
						textLine.y = coord;
					}
					
					adjustedLogicalRight = alignData.lineWidth + coord + Math.max(rightSideGap, 0);
					_parcelBottom = Math.max(adjustedLogicalRight,_parcelBottom);
					
					numberLine = TextFlowLine.findNumberLine(textLine);
					if (numberLine && TextFlowLine.getNumberLineListStylePosition(numberLine) == ListStylePosition.OUTSIDE)
					{
						numberLine.y = computeNumberLineAlignment(alignData,textLine.textWidth,textLine.y,numberLine,coord,delta,extraSpace);
						alignData.textFlowLine.numberLinePosition = numberLine.y;	
						// adjust parcel bounds for the numberLine
						
						// the start
						numberLineMetric = numberLine.y+textLine.y;
						if (numberLineMetric < _parcelTop)
							_parcelTop = numberLineMetric;
						
						// the extent
						numberLineMetric += TextFlowLine.getNumberLineInsideLineWidth(numberLine);
						if (numberLineMetric > _parcelBottom)
							_parcelBottom = numberLineMetric;
					}
				}
			}
		}
		
		protected function commitLastLineState(curLine:TextFlowLine):void
		{
			// Remember leading-related state that may be used for laying out the next line
			_lastLineDescent = _curLineLeadingModel == LeadingModel.BOX ? _curLineLeading : curLine.descent;
			_lastLineLeading = _curLineLeading;
			_lastLineLeadingModel = _curLineLeadingModel;
		}
		
		protected function doVerticalAlignment(canVerticalAlign:Boolean,nextParcel:Parcel):void	// No PMD
		{
			// stub for required override
			CONFIG::debug { assert(false, "override in derived class"); }
		}
		
		protected function finalParcelAdjustment(controller:ContainerController):void	// No PMD
		{
			// stub for required override
			CONFIG::debug { assert(false, "finalParcelAdjustment missing override in derived class"); }
		}
		
		protected function finishParcel(controller:ContainerController,nextParcel:Parcel):Boolean
		{
			if (_curParcelStart == _curElementStart+_curElementOffset)		// empty parcel -- nothing composed into it
			{
				CONFIG::debug { assert(_contentLogicalExtent == 0,"bad contentlogicalextent on empty container"); }
				return false;
			}
			
			// Figure out the contents bounds information for the parcel we just finished composing
			
			// Content logical height is parcel depth, plus descenders of last line
			var totalDepth:Number = _parcelList.totalDepth;
			if (_textFlow.configuration.overflowPolicy == OverflowPolicy.FIT_DESCENDERS && !isNaN(_lastLineDescent))
				totalDepth += _lastLineDescent;
			totalDepth = Math.max(totalDepth, _contentCommittedHeight);
			
			// Initialize the parcel bounds
			// note we can later optimize away the adjustements
			if (_blockProgression == BlockProgression.TB)
			{
				_parcelLeft = _curParcel.x;
				_parcelTop = _curParcel.y;
				_parcelRight = _contentCommittedExtent+_curParcel.x;
				_parcelBottom = totalDepth+_curParcel.y;
			}
			else
			{
				// Push the values up to the controller running min/max, if they are bigger
				_parcelLeft = _curParcel.right-totalDepth;
				_parcelTop = _curParcel.y;
				_parcelRight = _curParcel.right;
				_parcelBottom = _contentCommittedExtent+_curParcel.y;
			}
			
			// delayed textalignment for horizontal lines
			if (_alignLines && _alignLines.length > 0)
			{
				CONFIG::debug 
				{ assert(_blockProgression == BlockProgression.TB && controller.measureWidth || controller.measureHeight,"finishParcel has lines to align and not measuring"); }
				applyTextAlign(_contentLogicalExtent);
				releaseAlignData(_alignLines[0]);
				_alignLines.length = 0;
			}
			
			// If we're measuring, then don't do vertical alignment
			var canVerticalAlign:Boolean = false;
			if (_blockProgression == BlockProgression.TB)
			{
				if (!controller.measureHeight && (!_curParcel.fitAny || _curElementStart + _curElementOffset >= _textFlow.textLength))
					canVerticalAlign = true;
			}
			else
			{
				if (!controller.measureWidth && (!_curParcel.fitAny || _curElementStart + _curElementOffset >= _textFlow.textLength))
					canVerticalAlign = true;
			}
			
			// need to always call this function because internal variables may need resetting
			doVerticalAlignment(canVerticalAlign,nextParcel);
			
			// This last adjustment is for two issues
			// 1) inline graphics that extend above the top (any ILGS I expect)
			// 2) negative first line indents (stil a worry here?)
			// If neither of these are present it can be skipped - TODO optimization
			// trace("BEF finalParcelAdjustment",_parcelLeft,_parcelRight,_parcelTop,_parcelBottom);
			finalParcelAdjustment(controller);
			// trace("AFT finalParcelAdjustment",_parcelLeft,_parcelRight,_parcelTop,_parcelBottom);
			_contentLogicalExtent = 0;
			_contentCommittedExtent = 0;
			_contentCommittedHeight = 0;
			_accumulatedMinimumStart = TextLine.MAX_LINE_WIDTH;
			
			return true;
		}
		
		/** apply vj and adjust the parcel bounds */
		protected function applyVerticalAlignmentToColumn(controller:ContainerController,vjType:String,lines:Array,beginIndex:int,numLines:int,beginFloatIndex:int,endFloatIndex:int):void
		{
			var firstLine:IVerticalJustificationLine = lines[beginIndex];
			var lastLine:IVerticalJustificationLine = lines[beginIndex+numLines-1]
			var firstLineCoord:Number;
			var lastLineCoord:Number;
			
			if (_blockProgression == BlockProgression.TB)
			{
				firstLineCoord = firstLine.y;
				lastLineCoord  = lastLine.y;
			}
			else
			{
				firstLineCoord = firstLine.x;
				lastLineCoord = lastLine.x;
			}
			
			var firstLineAdjustment:Number = VerticalJustifier.applyVerticalAlignmentToColumn(controller,vjType,lines,beginIndex,numLines, beginFloatIndex, endFloatIndex);
			
			if (!isNaN(_parcelLogicalTop))
				_parcelLogicalTop += firstLineAdjustment;
			
			if (_blockProgression == BlockProgression.TB)
			{
				_parcelTop += firstLine.y-firstLineCoord;
				_parcelBottom += lastLine.y-lastLineCoord;
			}
			else
			{
				_parcelRight += firstLine.x-firstLineCoord;
				_parcelLeft += lastLine.x-lastLineCoord;
			}
		}
		
		protected function finishController(controller:ContainerController):void
		{	
			var controllerTextLength:int = _curElementStart + _curElementOffset - controller.absoluteStart;
			var nextCC:ContainerController = _flowComposer.getControllerAt(_flowComposer.getControllerIndex(controller) + 1);
			if ( nextCC && nextCC.absoluteStart != 0 && _correctTextLength )
				controllerTextLength = nextCC.absoluteStart - controller.absoluteStart;
			
			if (controllerTextLength != 0)
			{
				// Leave room for the padding. If the content overlaps the padding, don't count the padding twice.
				var paddingLeft:Number = controller.getTotalPaddingLeft();
				var paddingTop:Number = controller.getTotalPaddingTop();
				var paddingRight:Number = controller.getTotalPaddingRight();
				var paddingBottom:Number = controller.getTotalPaddingBottom();
				if (_blockProgression == BlockProgression.TB)
				{
					if (_controllerLeft > 0)
					{
						if (_controllerLeft < paddingLeft)
							_controllerLeft = 0;
						else 
							_controllerLeft -= paddingLeft;
					}
					
					if (_controllerTop > 0)
					{
						if (_controllerTop < paddingTop)
							_controllerTop = 0;
						else 
							_controllerTop -= paddingTop;
					}
					
					if (isNaN(controller.compositionWidth))
						_controllerRight += paddingRight;		 				
					else if (_controllerRight < controller.compositionWidth)
					{
						if (_controllerRight > controller.compositionWidth - paddingRight)
							_controllerRight = controller.compositionWidth;
						else 
							_controllerRight += paddingRight;
					}
					_controllerBottom += paddingBottom;	
				}
				else
				{
					_controllerLeft -= paddingLeft;
					if (_controllerTop > 0)
					{
						if (_controllerTop < paddingTop)
							_controllerTop = 0;
						else 
							_controllerTop -= paddingTop;
					}
					if (_controllerRight < 0)
					{
						if (_controllerRight > -paddingRight)
						{
							_controllerRight = 0;
						}
						else
							_controllerRight += paddingRight;
					}
					if (isNaN(controller.compositionHeight))
						_controllerBottom += paddingBottom;
					else if (_controllerBottom < controller.compositionHeight)
					{
						if (_controllerBottom > controller.compositionHeight - paddingBottom)
							_controllerBottom = controller.compositionHeight;
						else 
							_controllerBottom += paddingBottom;
					}
				}
				controller.setContentBounds(_controllerLeft, _controllerTop, _controllerRight-_controllerLeft, _controllerBottom-_controllerTop);
			}
			else
				controller.setContentBounds(0,0,0,0);
			
			controller.setTextLength(controllerTextLength);
			controller.finalParcelStart = _curParcelStart;
		}
		
		private function clearControllers(oldController:ContainerController, newController:ContainerController):void
		{
			// any controller between oldController and up to and including newController gets cleared
			var firstToClear:int = oldController ? _flowComposer.getControllerIndex(oldController)+1 : 0;
			var lastToClear:int  = newController ? _flowComposer.getControllerIndex(newController) : _flowComposer.numControllers-1;
			while (firstToClear <= lastToClear)
			{
				var controllerToClear:ContainerController = ContainerController(_flowComposer.getControllerAt(firstToClear));
				controllerToClear.setContentBounds(0, 0, 0, 0);
				controllerToClear.setTextLength(0);
				controllerToClear.clearComposedLines(controllerToClear.absoluteStart);
				controllerToClear.clearFloatsAt(controllerToClear.absoluteStart);
				firstToClear++;
			}
		}
		
		protected function advanceToNextParcel():void
		{
			parcelHasChanged(_parcelList.atLast() ? null : _parcelList.getParcelAt(_parcelList.currentParcelIndex + 1));
			_parcelList.next();
			//trace ("Advance to Next Parcel: ", _parcelList.currentParcelIndex) ;
		}
		/** Go to next container
		 */
		protected function advanceToNextContainer(): void
		{
			var newParcel:Parcel = (_parcelList.atLast() ? null : _parcelList.getParcelAt(_parcelList.currentParcelIndex + 1)) ;
			
			var oldController:ContainerController = _curParcel ? ContainerController(_curParcel.controller) : null;
			var newController:ContainerController ;
			
			for(;!_parcelList.atLast();_parcelList.next())
			{
				newParcel = (_parcelList.atLast() ? null : _parcelList.getParcelAt(_parcelList.currentParcelIndex + 1)) ;
				newController = newParcel  ? ContainerController(newParcel.controller)  : null;
				if (oldController != newController)
					break ;
			}
			parcelHasChanged(_parcelList.atLast() ? null : _parcelList.getParcelAt(_parcelList.currentParcelIndex + 1)) ;
			_parcelList.next() ;
			//trace ("Next Container Parcel:", _parcelList.currentParcelIndex) ;
		}
		/** This is called when the parcel has changed 
		 * @param oldParcel - the parcel we had before (you can get the new parcel from the parcel list)
		 */
		protected function parcelHasChanged(newParcel:Parcel):void
		{
			//trace("Move parcel to ", _parcelList.currentParcelIndex) ;
			var oldController:ContainerController = _curParcel ? ContainerController(_curParcel.controller) : null;
			var newController:ContainerController = newParcel  ? ContainerController(newParcel.controller)  : null;
			
			if (oldController != null && _lastGoodStart != -1)
			{
				oldController.clearFloatsAt(_lastGoodStart);
				_curLine = null;
				_linePass = 0;
				_pushInFloats.length = 0;
				// backup to lastGoodStart and try in next controller
			}
			
			/* if (newParcel)
			trace("parcelHasChanged newParcel: ",newParcel.clone().toString()); */
			
			if (_curParcel != null)
			{
				if (finishParcel(oldController,newParcel))
				{
					if (_parcelLeft < _controllerLeft)
						_controllerLeft = _parcelLeft;
					if (_parcelRight > _controllerRight)
						_controllerRight = _parcelRight;
					if (_parcelTop < _controllerTop)
						_controllerTop = _parcelTop;
					if (_parcelBottom > _controllerBottom)
						_controllerBottom = _parcelBottom;
				}
			}
			
			// update parcel data			
			if (oldController != newController)		// we're going on to the next controller in the chain
			{
				if (oldController)
					finishController(oldController);
				
				resetControllerBounds();
				
				if (_flowComposer.numControllers > 1)
				{
					if (oldController == null && _startController)
						clearControllers(_startController, newController);
					else if ( ! _curParcel.isTableParcel )
						clearControllers(oldController, newController);
				}
				if (newController)
				{
					CONFIG::debug 
					{ 
						if ( ! newParcel.isTableParcel )
							assert(!oldController || newController.absoluteStart == oldController.absoluteStart + oldController.textLength, "newController not yet set up");
					}
					if (oldController)		// advance the start pos to the next controller if newController isn't the first controller
						_startComposePosition = newController.absoluteStart;
					_curInteractiveObjects = newController.interactiveObjects;
					calculateControllerVisibleBounds(newController);
				}
					
				// Parcel list will set totalDepth to newController's paddingTop
			}
			_curParcel = newParcel;
			_curParcelStart = _curElementStart+_curElementOffset;
			_atColumnStart = true;
			_workingTotalDepth = 0;
			if (newController)
			{
				_verticalSpaceCarried = (_blockProgression == BlockProgression.RL) ? newController.getTotalPaddingRight() : newController.getTotalPaddingTop();
				_measuring = _blockProgression == BlockProgression.TB && newController.measureWidth || _blockProgression == BlockProgression.RL && newController.measureHeight;
			}
		}
		
		/** Figure out which part of the controller is currently visible, based on the controller's current size and scroll position. 
		 * These values are used later to determine which lines are going to be visible.
		 */
		private function calculateControllerVisibleBounds(controller:ContainerController):void
		{
			// Similar computations also done in ContainerController.gatherVisibleLines
			var width:Number = controller.measureWidth ? Number.MAX_VALUE : controller.compositionWidth;
			var xScroll:Number = controller.horizontalScrollPosition;

			_controllerVisibleBoundsXTW = Twips.roundTo((_blockProgression == BlockProgression.RL) ? xScroll - width : xScroll);
			_controllerVisibleBoundsYTW = Twips.roundTo(controller.verticalScrollPosition);
			_controllerVisibleBoundsWidthTW = controller.measureWidth ? int.MAX_VALUE : Twips.to(controller.compositionWidth);
			_controllerVisibleBoundsHeightTW = controller.measureHeight ? int.MAX_VALUE : Twips.to(controller.compositionHeight); 
		}
		
		/** @private */
		private function getLineAdjustmentForInline(curTextLine:TextLine, curLeadingDir:String, isFirstLine:Boolean):LeadingAdjustment
		{
			var adjustment:LeadingAdjustment = null;
			var para:ParagraphElement = _curLine.paragraph;
			var flowElem:FlowLeafElement = _curElement; //the first element included in this line
			var curPos:int = flowElem.getAbsoluteStart();
			var largestPointSize:Number = flowElem.getEffectiveFontSize();
			var largestImg:Number = 0;
			
			//walk
			while(flowElem && curPos < _curLine.absoluteStart + _curLine.textLength)
			{
				if(curPos >= _curLine.absoluteStart || curPos + flowElem.textLength >= _curLine.absoluteStart)
				{	
					if(flowElem is InlineGraphicElement)
					{
						var inlineImg:InlineGraphicElement = flowElem as InlineGraphicElement;
						//we can ignore TCY for leading adjustments
						if (inlineImg.effectiveFloat == Float.NONE && !(_blockProgression == BlockProgression.RL && (flowElem.parent is TCYElement)))
						{
							//if the largest found img is smaller than the current image, we need new data
							if(largestImg < inlineImg.getEffectiveFontSize())
							{
								largestImg = inlineImg.getEffectiveFontSize();
								//only get this if the img is as large or larger than the largest found text
								if(largestImg >= largestPointSize)
								{
									largestImg = largestImg;
									var domBaseline:String = flowElem.computedFormat.dominantBaseline;
									if(domBaseline == FormatValue.AUTO)
										domBaseline = LocaleUtil.dominantBaseline(para.computedFormat.locale);
									
									//we are only making the adjustment for ideo-center, all others are to be ignored...
									if(domBaseline == TextBaseline.IDEOGRAPHIC_CENTER)
									{
										var curAdjustment:LeadingAdjustment = calculateLinePlacementAdjustment(curTextLine, domBaseline, curLeadingDir, inlineImg, isFirstLine);
										if(!adjustment || Math.abs(curAdjustment.rise) > Math.abs(adjustment.rise) || Math.abs(curAdjustment.leading) > Math.abs(adjustment.leading))
										{
											if(adjustment)
											{
												adjustment.rise = curAdjustment.rise;
												adjustment.leading = curAdjustment.leading;
											}
											else
												adjustment = curAdjustment;
										}
									}
								}
							}
						}
					}
					else
					{
						var tempSize:Number = flowElem.getEffectiveFontSize();
						if(largestPointSize <= tempSize)
						{
							largestPointSize = tempSize;
						}
						
						//if the largest image is smaller than this element, zero out the adjustment
						if(adjustment && largestImg < largestPointSize)
						{
							adjustment.leading = 0;
							adjustment.rise = 0;
						}
					}
				}
				
				//advance the position and get the next element
				curPos += flowElem.textLength;
				flowElem = flowElem.getNextLeaf(para);
			}
			return adjustment;
		}


		public function get swfContext():ISWFContext
		{ 
			var composerContext:ISWFContext = _flowComposer.swfContext;
			return composerContext ? composerContext : GlobalSWFContext.globalSWFContext; 
		}

		/** @private */
		private function calculateLinePlacementAdjustment(curTextLine:TextLine, domBaseline:String, curLeadingDir:String, inlineImg:InlineGraphicElement, isFirstLine:Boolean):LeadingAdjustment
		{
			var curAdjustment:LeadingAdjustment = new LeadingAdjustment();
			//get the leading height for the img
			var imgHeight:Number = inlineImg.getEffectiveLineHeight(_blockProgression);
			//get the leading as if the line contains no imgs.  We'll need this to adjust the total adjustments
			var lineLeading:Number = TextLayoutFormat.lineHeightProperty.computeActualPropertyValue(inlineImg.computedFormat.lineHeight, curTextLine.textHeight)
			
			//this is a redundant check, but will be needed in the future, so we're leaving it in. - gak 12.16.09
			if(domBaseline == TextBaseline.IDEOGRAPHIC_CENTER)
			{
				if(!isFirstLine)
				{
					//for non-first lines, we want to offset the rise of the line
					curAdjustment.rise += (imgHeight - lineLeading)/2;
				}
				else
				{
					//for the first line, the offset will be right, but hte leading wrong.
					curAdjustment.leading -= (imgHeight - lineLeading)/2;
				}
			}
			
			return curAdjustment;
		}
		
		protected function pushInsideListItemMargins(numberLine:TextLine):void
		{
			CONFIG::debug { assert(_listItemElement != null,"Bad call to pushInsideListItemMargins"); }
			if (numberLine && _listItemElement.computedFormat.listStylePosition == ListStylePosition.INSIDE)
			{
				var numberLineWidth:Number = TextFlowLine.getNumberLineInsideLineWidth(numberLine);
				_parcelList.pushInsideListItemMargin(numberLineWidth);
			}
		}
		
		protected function popInsideListItemMargins(numberLine:TextLine):void
		{
			CONFIG::debug { assert(numberLine == null || _listItemElement != null,"Bad call to pushInsideListItemMargins"); }
			if (numberLine && _listItemElement.computedFormat.listStylePosition == ListStylePosition.INSIDE)
			{
				var numberLineWidth:Number = TextFlowLine.getNumberLineInsideLineWidth(numberLine);
				_parcelList.popInsideListItemMargin(numberLineWidth);
			}
		}
		
		private function gotoParcel(index:int, depth:Number = 0):Boolean
		{
			parcelHasChanged(_parcelList.getParcelAt(index));
			return _parcelList.gotoParcel(index, depth);
		}
	}
}

import flash.text.engine.TextLine;

import flashx.textLayout.compose.ISWFContext;
import flashx.textLayout.compose.TextFlowLine;
import flashx.textLayout.debug.Debugging;
import flashx.textLayout.debug.assert;
import flashx.textLayout.formats.TextAlign;
import flashx.textLayout.tlf_internal;

use namespace tlf_internal;

class AlignData 
{	public function AlignData(tfl:TextFlowLine)
	{ textFlowLine = tfl; }
	public var textFlowLine:TextFlowLine;
	public var textLine:TextLine;
	public var lineWidth:Number;
	public var textAlign:String;
	public var leftSideGap:Number;
	public var rightSideGap:Number;
	public var textIndent:Number;
}


class GlobalSWFContext implements ISWFContext
{
	static public const globalSWFContext:GlobalSWFContext = new GlobalSWFContext();

	public function GlobalSWFContext()
	{ }
	
	public function callInContext(fn:Function, thisArg:Object, argsArray:Array, returns:Boolean=true):*
	{
		CONFIG::debug
		{
			var rslt:*
			try
			{
				if (returns)
					rslt = fn.apply(thisArg, argsArray);

				else
					fn.apply(thisArg, argsArray);
					
				if (thisArg)
				{
					var traceArgs:Array;
					// later make this table driven
					if (thisArg.hasOwnProperty("createTextLine") && fn == thisArg["createTextLine"])
					{
						traceArgs = [rslt,thisArg,"createTextLine"]
						traceArgs.push.apply(traceArgs, argsArray);
						Debugging.traceFTECall.apply(null,traceArgs);
					}
					else if (thisArg.hasOwnProperty("recreateTextLine") && fn == thisArg["recreateTextLine"])
					{
						traceArgs = [rslt,thisArg,"recreateTextLine"]
						traceArgs.push.apply(traceArgs, argsArray);
						Debugging.traceFTECall.apply(null,traceArgs);
					}
				}
			}
			catch(e:Error)
			{
				// trace(e);
				throw(e);
			}
			return rslt;
		}
		CONFIG::release
		{
			if (returns)
				return fn.apply(thisArg, argsArray);
			fn.apply(thisArg, argsArray);
		}
	}
}

class LeadingAdjustment
{
	public var rise:Number = 0;
	public var leading:Number = 0;
	public var lineHeight:Number = 0;
}


