////////////////////////////////////////////////////////////////////////////////
//
//  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 UnitTest.Tests
{

    import UnitTest.ExtendedClasses.VellumTestCase;
    import UnitTest.Fixtures.TestConfig;
    import UnitTest.Validation.BoundsChecker;
    import UnitTest.Validation.CompositionResults;

    import flash.display.DisplayObject;
    import flash.display.DisplayObjectContainer;
    import flash.display.Graphics;
    import flash.display.Sprite;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.text.engine.TextLine;
    import flash.ui.KeyLocation;

    import flashx.textLayout.*;
    import flashx.textLayout.compose.IFlowComposer;
    import flashx.textLayout.compose.StandardFlowComposer;
    import flashx.textLayout.compose.TextFlowLine;
    import flashx.textLayout.container.ContainerController;
    import flashx.textLayout.container.ScrollPolicy;
    import flashx.textLayout.conversion.TextConverter;
    import flashx.textLayout.edit.EditManager;
    import flashx.textLayout.edit.ElementRange;
    import flashx.textLayout.edit.IEditManager;
    import flashx.textLayout.edit.ParaEdit;
    import flashx.textLayout.edit.SelectionFormat;
    import flashx.textLayout.edit.SelectionState;
    import flashx.textLayout.edit.TextScrap;
    import flashx.textLayout.elements.*;
    import flashx.textLayout.events.StatusChangeEvent;
    import flashx.textLayout.factory.TextFlowTextLineFactory;
    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.ITextLayoutFormat;
    import flashx.textLayout.formats.LineBreak;
    import flashx.textLayout.formats.TextAlign;
    import flashx.textLayout.formats.TextLayoutFormat;
    import flashx.textLayout.formats.VerticalAlign;

    import mx.containers.Canvas;
    import mx.core.Container;
    import mx.utils.LoaderUtil;

    import org.flexunit.asserts.assertTrue;

    use namespace tlf_internal;

    [TestCase(order=12)]
    public class FloatTest extends VellumTestCase
    {
        // axies
        private static var floatTypeList:Array;
        private static var contentLanguageList:Array = [ _englishContent, _japaneseContent];
        private static var floatWidthList:Array = [ 5, 20, 50, 100, 200, 400 ]
        private static var floatHeightList:Array = [ 5, 20, 50, 100, 200, 400 ];

        private static var _englishContent:String;
        private static var _japaneseContent:String;

        private var _textFlow:TextFlow;
        private var _flowComposer:IFlowComposer;
        private var _editManager:IEditManager;
        private var _testXML:XML;
        private var _currentContent:String;		// content in TextFlow
        private var _disableVerticalCheck:Boolean;	// don't check floats vertical location; tests that force floats down should set this
        private var _floatColor:int;
        private var _disableBoundsCheck:Boolean = false;

        public function FloatTest()
        {
            super("", "FloatTest2", TestConfig.getInstance());
            //   super(methodName, testID, testConfig);
            TestData.fileName = null;
            metaData = {};

            // Note: These must correspond to a Watson product area (case-sensitive)
            metaData.productArea = "Text Composition";
            _floatColor = 0xFF0000;
        }

        [BeforeClass]
        public static function setUpClass():void
        {
            _englishContent = "There are many such lime-kilns in that tract of country, for the purpose of burning the white marble which composes a large part of the substance of the hills. Some of them, built years ago, and long deserted, with weeds growing in the vacant round of the interior, which is open to the sky, and grass and wild-flowers rooting themselves into the chinks of the stones, look already like relics of antiquity, and may yet be overspread with the lichens of centuries to come. Others, where the lime-burner still feeds his daily and nightlong fire, afford points of interest to the wanderer among the hills, who seats himself on a log of wood or a fragment of marble, to hold a chat with the solitary man. It is a lonesome, and, when the character is inclined to thought, may be an intensely thoughtful occupation; as it proved in the case of Ethan Brand, who had mused to such strange purpose, in days gone by, while the fire in this very kiln was burning.\n" +
                    "The man who now watched the fire was of a different order, and troubled himself with no thoughts save the very few that were requisite to his business. At frequent intervals, he flung back the clashing weight of the iron door, and, turning his face from the insufferable glare, thrust in huge logs of oak, or stirred the immense brands with a long pole. Within the furnace were seen the curling and riotous flames, and the burning marble, almost molten with the intensity of heat; while without, the reflection of the fire quivered on the dark intricacy of the surrounding forest, and showed in the foreground a bright and ruddy little picture of the hut, the spring beside its door, the athletic and coal-begrimed figure of the lime-burner, and the half-frightened child, shrinking into the protection of his father's shadow. And when again the iron door was closed, then reappeared the tender light of the half-full moon, which vainly strove to trace out the indistinct shapes of the neighboring mountains; and, in the upper sky, there was a flitting congregation of clouds, still faintly tinged with the rosy sunset, though thus far down into the valley the sunshine had vanished long and long ago."
            _japaneseContent = '文字コードが割り当てられていないグリフの大半は既に文字コードが割り当てられているグリフの異体字です。次のセクションでは、このようなグリフスする方法について解説しまが割り当てられていないグリフの大半は既に文字コードが割り当てられているグリフの異体字です。次のセクす。\n文字コードが割り当てられていないグリフの大半は既に文字コードが割り当てられているグリフの異体字です。次のセクションでは、このようなグリフスする方法について解説しまが割り当てられていないグリフの大半は既に文字コードが割り当てられているグリフの異体字です。次のセクす。\n' +
                    '文字コードが割り当てられていないグリフの大半は既に文字コードが割り当てられているグリフの異体字です。次のセクションでは、このようなグリフスする方法について解説しまが割り当てられていないグリフの大半は既に文字コードが割り当てられているグリフの異体字です。次のセクす。\n文字コードが割り当てられていないグリフの大半は既に文字コードが割り当てられているグリフの異体字です。次のセクションでは、このようなグリフスする方法について解説しまが割り当てられていないグリフの大半は既に文字コードが割り当てられているグリフの異体字です。次のセクす。';

            floatTypeList = [Float.LEFT, Float.RIGHT /*, Float.START, Float.END */];	// start & end disabled to make tests run faster
            contentLanguageList = [ _englishContent, _japaneseContent];
            floatWidthList = [ 5, 20, 50, 100, 200, 400 ];
            floatHeightList = [ 5, 20, 50, 100, 200, 400 ];
        }

        [AfterClass]
        public static function tearDownClass():void
        {
            _englishContent = null;
            _japaneseContent = null;

            floatTypeList = null;
            contentLanguageList = null;
            floatWidthList = null;
            floatHeightList = null;
        }

        [Before]
        override public function setUpTest():void
        {
            super.setUpTest();
            initializeSourceTextFlow();
            initializeFlow(TextConverter.importToFlow(_englishContent, TextConverter.PLAIN_TEXT_FORMAT));
        }

        [After]
        override public function tearDownTest():void
        {
            if (TestFrame && TestFrame.textFlow && !_disableBoundsCheck)
            {
                var s:Sprite = new Sprite();
                testApp.getDisplayObject().rawChildren.addChild(s);
                BoundsChecker.validateAll(TestFrame.textFlow, s, 10, true);
                testApp.getDisplayObject().rawChildren.removeChild(s);
            }
            super.tearDownTest();
        }

        private function initializeFlow(textFlow:TextFlow):void
        {
            _textFlow = textFlow;
            _flowComposer = _textFlow.flowComposer;
            VellumTestCase.testApp.contentChange(_textFlow);
            TestDisplayObject = VellumTestCase.testApp.getDisplayObject();
            TestFrame = _textFlow.flowComposer.getControllerAt(0);
            if (TestFrame.rootElement)
            {
                // Set the writing direction specified by the test
                _textFlow.blockProgression = writingDirection[0];
                _textFlow.direction = writingDirection[1];
                SelManager = EditManager(_textFlow.interactionManager);
                if (SelManager)
                {
                    SelManager.selectRange(0, 0);
                    //make sure there is never any blinking when running these tests
                    setCaretBlinkRate(0);
                }
                _editManager = SelManager;
            }
            _textFlow.flowComposer.updateAllControllers();
        }

        private static var sourceTextFlow:Array;

        private function setUpFlow(content:String):void
        {
            var sourceFlow:TextFlow;
            if (content == _englishContent)
                sourceFlow = sourceTextFlow[0];
            else if (content == _japaneseContent)
                sourceFlow = sourceTextFlow[1];
            else
                sourceFlow = TextConverter.importToFlow(content, TextConverter.PLAIN_TEXT_FORMAT);

            _textFlow.replaceChildren(0, _textFlow.numChildren);
            assertTrue("Empty TextFlow has incorrect ContainerLength", _textFlow.textLength == _textFlow.flowComposer.getControllerAt(0).textLength);
            var newFlow:TextFlow = sourceFlow.deepCopy() as TextFlow;
            var childCount:int = newFlow.numChildren;
            for (var i:int = newFlow.numChildren - 1; i >= 0; --i)
            {
                var child:FlowElement = newFlow.getChildAt(i);
                _textFlow.addChildAt(0, child);
            }
            _textFlow.flowComposer.updateAllControllers();
            _textFlow.interactionManager.selectRange(0, 0);
            _currentContent = content;
        }

        private function initializeSourceTextFlow():void
        {
            sourceTextFlow = [];

            // Create english content
            var englishFlow:TextFlow = TextConverter.importToFlow(_englishContent, TextConverter.PLAIN_TEXT_FORMAT);
            sourceTextFlow.push(englishFlow);

            // Create japanese content
            var japaneseFlow:TextFlow = TextConverter.importToFlow(_japaneseContent, TextConverter.PLAIN_TEXT_FORMAT);
            var textFlowFormat:TextLayoutFormat = new TextLayoutFormat();
            textFlowFormat.locale = "ja";
            japaneseFlow.format = textFlowFormat;
            sourceTextFlow.push(japaneseFlow);
        }

        // Test Cases:
        // float at paragraph start (left, right)
        // float at line start (left, right)
        // float in middle of line (left, right)
        // stacked floats (left, right)
        // multiple (stacked) floats at start
        // floats with no graphic
        // float doesn't fit in container (width/height) (*on end last para height = 400 this happens)
        // float does fit in container, following line does not
        // float at end of container
        // floats in multiple columns
        // float fits, not enough space for text (min-width??)

        private function addFloatAtPosition(position:int, width:Number, height:Number, float:String):DisplayObject
        {
            var secondColor:int = 0;
            switch (_floatColor)
            {
                case 0xFF0000:
                    secondColor = 0x770000;
                    break;
                case 0x00FF00:
                    secondColor = 0x007700;
                    break;
                case 0x0000FF:
                    secondColor = 0x000077;
                    break;
            }

            // Create a simple rectangular display object for the float
            // Rectangle is two tone, to make it easier to know which part you're looking at
            var displayObject:Sprite = new Sprite();
            var g:Graphics = displayObject.graphics;
            g.beginFill(_floatColor);
            g.drawRect(0, 0, width / 2, height);
            g.endFill();
            g.beginFill(secondColor);
            g.drawRect(width / 2, 0, width / 2, height);
            g.endFill();

            // Cycle through colors so multiple floats can be visually disintguished
            switch (_floatColor)
            {
                case 0xFF0000:
                    _floatColor = 0x00FF00;
                    break;
                case 0x00FF00:
                    _floatColor = 0x0000FF;
                    break;
                case 0x0000FF:
                    _floatColor = 0xFF0000;
                    break;
            }

            // Add it to the TextFlow at the specified location
            //	_editManager.insertInlineGraphic(displayObject, width, height, float, new SelectionState(_textFlow, position, position));

            var range:ElementRange = ElementRange.createElementRange(_textFlow, position, position);
            var leafNode:FlowElement = range.firstLeaf;
            var leafNodeParent:FlowGroupElement = leafNode.parent;

            ParaEdit.createImage(leafNodeParent, position - leafNodeParent.getAbsoluteStart(), displayObject, width, height, float, null);
            return displayObject;
        }

        private function atParagraphStartInternal(leaf:FlowLeafElement, width:Number, height:Number, float:String, paragraphSpaceBefore:Number = 0):void
        {
            var paragraph:ParagraphElement = leaf.getParagraph();
            var paraStart:int = paragraph.getAbsoluteStart();
            if (paragraph.computedFormat.paragraphSpaceBefore != paragraphSpaceBefore)
            {
                var paragraphFormat:TextLayoutFormat = new TextLayoutFormat();
                paragraphFormat.paragraphSpaceBefore = paragraphSpaceBefore;
                paragraph.format = paragraphFormat;
            }
            var floatObject:DisplayObject = addFloatAtPosition(paraStart, width, height, float);

            verifyFloatInLine(paraStart, width, height, float, floatObject);
        }

        /**
         * Test adding a float to the start of the first and last paragraphs, with either left or right float, and with
         * spaceBefore either 0 or 15.
         */
        [Test]
        public function atFlowStart():void
        {
            // On the first paragraph, add a float
            callTestMethod("atParagraphStartInternal");
            //atParagraphStartInternal(_textFlow.getFirstLeaf(), width, height, float);
        }

        /**
         *  Test adding a float to the start of the first and last paragraphs, with either left or right float, and with
         * spaceBefore either 0 or 15.
         */
        [Test]
        public function atFlowStartSpaceBefore():void
        {
            // On the first paragraph, add a float
            callTestMethod("atParagraphStartInternal", 15);
            //atParagraphStartInternal(_textFlow.getFirstLeaf(), width, height, float, 15);
        }

        /**
         * Test adding a float to the start of the first and last paragraphs, with either left or right float, and with
         * spaceBefore either 0 or 15.
         */
        [Test]
        public function atParagraphStart():void
        {
            // On the last paragraph, add a float
            callTestMethod("atParagraphStartInternal");
            //atParagraphStartInternal(_textFlow.getLastLeaf(), width, height, float);
        }

        [Test]
        public function atParagraphStartSpaceBefore():void
        {
            // On the last paragraph, add a spaceBefore and a float
            callTestMethod("atParagraphStartInternal", 15);
            //atParagraphStartInternal(_textFlow.getFirstLeaf(), width, height, float, 15);
        }

        // Certify that the float was added to the container
        // Certify that the float appears below the previous line's descenders
        // Check that float appears at the correct horizontal alignment (left or right)
        // If there's an intersecting float that comes before, it would appear to the left or right of that float (i.e., stacked)
        // Look to see if they overlap in the blockProgression direction; if so, they're going to stack if they have the same float property
        // Check the vertical location of the float. It should go below the previous line's descender, and at or above the next line.
        // The EXCEPTION is if the float was displaced lower because it didn't fit on it's natural position (too wide). In that case,
        // float may appear below following lines. Test needs to flag this so we don't assert false positive.
        private function verifyFloatInLine(pos:int, width:Number, height:Number, float:String, floatObject:DisplayObject):void
        {
            if (float == Float.NONE)		// not a float, nothing to check
                return;

            var verticalText:Boolean = _textFlow.blockProgression == BlockProgression.RL;
            _textFlow.flowComposer.updateAllControllers();
            var floatHolder:DisplayObjectContainer = floatObject.parent;
            var lineIndex:int = _textFlow.flowComposer.findLineIndexAtPosition(pos);

            var previousTextFlowLine:TextFlowLine;
            var textFlowLine:TextFlowLine;

            // Certify that the float was added to the container
            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            var firstLine:TextFlowLine = controller.getFirstVisibleLine();
            var lastLine:TextFlowLine = controller.getLastVisibleLine();
            var firstLineIndex:int = firstLine ? _textFlow.flowComposer.findLineIndexAtPosition(firstLine.absoluteStart) : -1;
            var lastLineIndex:int = lastLine ? _textFlow.flowComposer.findLineIndexAtPosition(lastLine.absoluteStart) : -1;
            if (lineIndex >= firstLineIndex && lineIndex <= lastLineIndex)
            {
                assertTrue("Float not added as child of the container", controller.container.contains(floatObject));

                // Certify that the float appears below the previous line's descenders
                if (lineIndex > firstLineIndex)
                {
                    previousTextFlowLine = _textFlow.flowComposer.getLineAt(lineIndex - 1);
                }
                textFlowLine = _textFlow.flowComposer.getLineAt(lineIndex);

                // Check that float appears at the correct horizontal alignment (left or right)
                // If there's an intersecting float that comes before, it would appear to the left or right of that float (i.e., stacked)
                var currentPos:int = textFlowLine.absoluteStart + textFlowLine.textLength;
                var floatRect:Rectangle = new Rectangle(floatHolder.x, floatHolder.y, floatObject.width, floatObject.height);
                var pos:int = 0;
                var paraFormat:ITextLayoutFormat = textFlowLine.paragraph.computedFormat;
                var maxLeft:Number = 0;
                var maxRight:Number = verticalText ? controller.compositionHeight : controller.compositionWidth;
                var otherDirection:String;
                var otherFloatType:String;
                for (var leaf:FlowLeafElement = _textFlow.getFirstLeaf(); leaf && pos < currentPos; leaf = leaf.getNextLeaf())
                {
                    var otherInline:InlineGraphicElement = leaf as InlineGraphicElement;
                    if (otherInline)
                    {
                        if (otherInline.graphic == floatObject)		// this is our float, we're done
                            break;
                        // Look to see if they overlap in the blockProgression direction; if so, they're going to stack if they have the same float property
                        if (verticalText)
                        {
                            if (Math.floor(otherInline.graphic.parent.x) < Math.floor(floatRect.right))
                            {
                                otherDirection = otherInline.getParagraph().computedFormat.direction;
                                otherFloatType = otherInline.computedFloat;
                                if (otherFloatType == Float.START)
                                    otherFloatType = (otherDirection == Direction.LTR) ? Float.LEFT : Float.RIGHT;
                                else if (otherFloatType == Float.END)
                                    otherFloatType = (otherDirection == Direction.RTL) ? Float.LEFT : Float.RIGHT;
                                if (otherFloatType == Float.RIGHT)
                                    maxRight -= otherInline.elementHeight;
                                if (otherFloatType == Float.LEFT)
                                    maxLeft += otherInline.elementHeight;
                            }
                        }
                        else
                        {
                            if (otherInline.graphic.parent.y + otherInline.elementHeight > floatRect.top)
                            {
                                otherDirection = otherInline.getParagraph().computedFormat.direction;
                                otherFloatType = otherInline.computedFloat;
                                if (otherFloatType == Float.START)
                                    otherFloatType = (otherDirection == Direction.LTR) ? Float.LEFT : Float.RIGHT;
                                else if (otherFloatType == Float.END)
                                    otherFloatType = (otherDirection == Direction.RTL) ? Float.LEFT : Float.RIGHT;
                                if (otherFloatType == Float.LEFT)
                                    maxLeft += otherInline.elementWidth;
                                if (otherFloatType == Float.RIGHT)
                                    maxRight -= otherInline.elementWidth;
                            }
                        }
                    }
                    pos += leaf.textLength;
                }

                // Check the vertical location of the float. It should go below the previous line's descender, and at or above the next line.
                // The EXCEPTION is if the float was displaced lower because it didn't fit on it's natural position (too wide). In that case,
                // float may appear below following lines. Test needs to flag this so we don't assert false positive.
                if (!_disableVerticalCheck)
                {
                    var floatAlignsWithPrevious:Boolean = false;
                    if (previousTextFlowLine)
                    {
                        if (verticalText)
                            floatAlignsWithPrevious = Math.abs((floatHolder.x + floatObject.width) - (previousTextFlowLine.x - previousTextFlowLine.descent)) < 1;
                        else
                            floatAlignsWithPrevious = Math.abs(floatHolder.y - (previousTextFlowLine.y + previousTextFlowLine.ascent + previousTextFlowLine.descent)) < 1;
                    }
                    else  // no previous line, so check it against the container logical top (assume 0)
                    if (verticalText)
                        floatAlignsWithPrevious = true;
                    else
                        floatAlignsWithPrevious = Math.abs(floatHolder.y) < 1;
                    var floatAlignsWithSameLine:Boolean = false;
                    if (verticalText)
                        floatAlignsWithSameLine = Math.abs((floatHolder.x + floatObject.width) - (textFlowLine.x - textFlowLine.descent)) < 1;
                    else
                        floatAlignsWithSameLine = Math.abs(floatHolder.y - (textFlowLine.y + textFlowLine.ascent + textFlowLine.descent)) < 1;
                    assertTrue("Float has incorrect logical vertical position", floatAlignsWithPrevious || floatAlignsWithSameLine);
                }

                // Check horizontal location of the float
                if (float == Float.START)
                    float = (paraFormat.direction == Direction.LTR) ? Float.LEFT : Float.RIGHT;
                else if (float == Float.END)
                    float = (paraFormat.direction == Direction.RTL) ? Float.LEFT : Float.RIGHT;
                if (float == Float.LEFT)
                {
                    if (verticalText)
                        assertTrue("Float should be on the left", Math.abs(floatHolder.y - maxLeft) < 1);
                    else
                        assertTrue("Float should be on the left", Math.abs(floatHolder.x - maxLeft) < 1);
                }
                else if (float == Float.RIGHT)
                {
                    if (verticalText)
                        assertTrue("Float should be on the right", Math.abs(floatRect.bottom - maxRight) < 1);
                    else
                        assertTrue("Float should be on the right", Math.abs(floatRect.right - maxRight) < 1);
                }
            }
        }

        private function atLineStartInternal(lineIndex:int, width:Number, height:Number, float:String):void
        {
            var textFlowLine:TextFlowLine = _textFlow.flowComposer.getLineAt(lineIndex);
            var pos:int = textFlowLine.absoluteStart;
            var floatObject:DisplayObject = addFloatAtPosition(pos, width, height, float);

            verifyFloatInLine(pos, width, height, float, floatObject);
        }

        private function atLineMiddleInternal(lineIndex:int, width:Number, height:Number, float:String):void
        {
            var textFlowLine:TextFlowLine = _textFlow.flowComposer.getLineAt(lineIndex);
            if (!textFlowLine)
                return;

            var pos:int = textFlowLine.absoluteStart + (textFlowLine.textLength / 2);
            var floatObject:DisplayObject = addFloatAtPosition(pos, width, height, float);

            verifyFloatInLine(pos, width, height, float, floatObject);		// aligns with next line
        }

        private function atLineEndInternal(lineIndex:int, width:Number, height:Number, float:String):void
        {
            var textFlowLine:TextFlowLine = _textFlow.flowComposer.getLineAt(lineIndex);
            var pos:int = textFlowLine.absoluteStart + textFlowLine.textLength - 1;
            var floatObject:DisplayObject = addFloatAtPosition(pos, width, height, float);

            verifyFloatInLine(pos, width, height, float, floatObject);		// aligns with next line
        }

        /**
         *  Test adding a float at the start of a line, float should appear below and to the left or right of the line.
         */
        [Test]
        public function atLineStart():void
        {
            // At the start of the second line, add a left float
            callTestMethodAtLine("atLineStartInternal");
            //	atLineStartInternal(1, width, height, float);
        }

        [Test]
        public function atLineMiddle():void
        {
            // At the start of the second line, add a left float
            callTestMethodAtLine("atLineMiddleInternal");
            //atLineMiddleInternal(1, width, height, float);
        }

        [Test]
        public function atLineEnd():void
        {
            // At the start of the second line, add a left float
            callTestMethodAtLine("atLineEndInternal");
            //	atLineEndInternal(1, width, height, float);
        }

        private function atParagraphEndInternal(paragraph:ParagraphElement, width:Number, height:Number, float:String):void
        {
            var paragraph:ParagraphElement = _textFlow.getFirstLeaf().getParagraph();
            var pos:int = paragraph.getAbsoluteStart() + paragraph.textLength - 1;
            var lineIndex:int = _textFlow.flowComposer.findLineIndexAtPosition(pos);
            atLineEndInternal(lineIndex, width, height, float);
        }

        [Test]
        public function atParagraphEnd():void
        {
            for each (var content:String in contentLanguageList)
            {
                for each (var floatValue:String in floatTypeList)
                    for each (var floatWidth:String in floatWidthList)
                        for each (var floatHeight:String in floatHeightList)
                        {
                            setUpFlow(content);
                            //	trace(methodName, floatValue, floatWidth.toString(), floatHeight.toString());
                            if (Number(floatHeight) >= 400)
                            {
                                return;
                            }
                            // Add float to the end of the first paragraph
                            atParagraphEndInternal(_textFlow.getFirstLeaf().getParagraph(), Number(floatWidth), Number(floatHeight), floatValue);
                        }
            }

        }

        /**
         * Test multiple floats on successive lines
         */
        [Test]
        public function stackedFloats():void
        {

            callTestMethodAtLine("atLineMiddleInternal", 1, 400);
            //atLineMiddleInternal(1, width, height, float);

            callTestMethodAtLine("atLineMiddleInternal", 2);
            for each (var content:String in contentLanguageList)
            {
                for each (var floatValue:String in floatTypeList)
                    for each (var floatWidth:String in floatWidthList)
                        for each (var floatHeight:String in floatHeightList)
                        {
                            setUpFlow(content);
                            // With a set of wide stacked floats, the second float gets pushed to after the
                            // preceding float, and therefore won't align with previous line's descender.
                            // This is correct, but will assert so we turn off the asserts here.
                            if ((_textFlow.blockProgression == BlockProgression.RL && Number(floatHeight) >= 400) ||
                                    (_textFlow.blockProgression == BlockProgression.TB && Number(floatWidth) >= 400))
                            {
                                _disableVerticalCheck = true; 		// floats get pushed down b/c the second doesn't fit on the line, so don't check
                            }
                            else
                            {
                                _disableVerticalCheck = false;
                            }

                            //	trace(methodName, floatValue, floatWidth.toString(), floatHeight.toString());
                            atLineMiddleInternal(2, Number(floatWidth), Number(floatHeight), floatValue);
                        }
            }
            //	atLineMiddleInternal(2, width, height, float);
        }

        private function flipFloat(float:String):String
        {
            return Float.LEFT ? Float.RIGHT : Float.LEFT;
        }

        /**
         * Test multiple floats on successive lines on each side
         */
        [Test]
        public function onTwoSidesSuccessiveLines():void
        {
            // On successive lines
            callTestMethodAtLine("atLineMiddleInternal", 1, NaN);
            //atLineMiddleInternal(1, width, height, float);

            // With a set of wide stacked floats, the second float gets pushed to after the
            // preceding float, and therefore won't align with previous line's descender.
            // This is correct, but will assert so we turn off the asserts here.
            /*if ((_textFlow.blockProgression == BlockProgression.RL && height >= 400) ||
             (_textFlow.blockProgression == BlockProgression.TB && width >= 400))
             _disableVerticalCheck = true; */
            // floats get pushed down b/c the second doesn't fit on the line, so don't check

            for each (var content:String in contentLanguageList)
            {
                for each (var floatValue:String in floatTypeList)
                    for each (var floatWidth:String in floatWidthList)
                        for each (var floatHeight:String in floatHeightList)
                        {
                            setUpFlow(content);


                            // With a set of wide stacked floats, the second float gets pushed to after the
                            // preceding float, and therefore won't align with previous line's descender.
                            // This is correct, but will assert so we turn off the asserts here.
                            if ((_textFlow.blockProgression == BlockProgression.RL && Number(floatHeight) >= 400) ||
                                    (_textFlow.blockProgression == BlockProgression.TB && Number(floatWidth) >= 400))
                            {
                                _disableVerticalCheck = true; 		// floats get pushed down b/c the second doesn't fit on the line, so don't check
                            }
                            else
                            {
                                _disableVerticalCheck = false;
                            }
                            //	trace(methodName, floatValue, floatWidth.toString(), floatHeight.toString());
                            // this[methodName](2, Number(floatWidth), Number(floatHeight), floatValue);
                            atLineMiddleInternal(2, Number(floatWidth), Number(floatHeight), flipFloat(floatValue));
                        }
            }

            //atLineMiddleInternal(2, width, height, flipFloat(float));
        }

        /**
         * Test multiple floats on the same line, one on each side
         */
        [Test]
        public function onTwoSidesSameLine():void
        {
            // On the same line
            //	atLineMiddleInternal(2, width/2, height/2, float);
            var content:String = null;
            var floatValue:String = null;
            var floatWidth:String = null;
            var floatHeight:String = null;

            for each (content in contentLanguageList)
            {
                for each (floatValue in floatTypeList)
                    for each (floatWidth in floatWidthList)
                        for each (floatHeight in floatHeightList)
                        {
                            setUpFlow(content);

                            //	trace(methodName, floatValue, floatWidth.toString(), floatHeight.toString());
                            atLineMiddleInternal(2, Number(floatWidth) / 2, Number(floatHeight) / 2, floatValue);
                        }
            }

            //	atLineMiddleInternal(2, width, height, flipFloat(float));
            for each (content in contentLanguageList)
            {
                for each (floatValue in floatTypeList)
                    for each (floatWidth in floatWidthList)
                        for each (floatHeight in floatHeightList)
                        {
                            setUpFlow(content);


                            // With a set of wide stacked floats, the second float gets pushed to after the
                            // preceding float, and therefore won't align with previous line's descender.
                            // This is correct, but will assert so we turn off the asserts here.
                            if ((_textFlow.blockProgression == BlockProgression.RL && Number(floatHeight) >= 400) ||
                                    (_textFlow.blockProgression == BlockProgression.TB && Number(floatWidth) >= 400))
                            {
                                _disableVerticalCheck = true; 		// floats get pushed down b/c the second doesn't fit on the line, so don't check
                            }
                            else
                            {
                                _disableVerticalCheck = false;
                            }
                            //	trace(methodName, floatValue, floatWidth.toString(), floatHeight.toString());
                            atLineMiddleInternal(2, Number(floatWidth), Number(floatHeight), flipFloat(floatValue));
                        }
            }
        }

        private function logicalContentHeight(controller:ContainerController, verticalText:Boolean):Number
        {
            return verticalText ? controller.contentWidth : controller.contentHeight;
        }

        private function logicalContentWidth(controller:ContainerController, verticalText:Boolean):Number
        {
            return verticalText ? controller.contentHeight : controller.contentWidth;
        }

        [Test]
        public function contentHeightCheck():void
        {
            var verticalText:Boolean = _textFlow.blockProgression == BlockProgression.RL;

            _textFlow.flowComposer.composeToPosition();
            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            var contentHeight:Number = logicalContentHeight(controller, verticalText);

            // Add a float to the end of the text, make sure it gets taller
            atLineMiddleInternal(_textFlow.flowComposer.numLines - 1, 100, 100, Float.LEFT);

            // The float goes even with the line, so not all the 100 pixels are added into the content height...
            assertTrue("Expected larger content height because of trailing float", logicalContentHeight(controller, verticalText) > contentHeight + 70);
        }

        [Test]
        [Ignore]
        public function contentWidthCheckLongFloat():void
        {	// Should be adapted for RL
            var textFlowFormat:TextLayoutFormat = new TextLayoutFormat(_textFlow.format);
            textFlowFormat.lineBreak = LineBreak.EXPLICIT;
            _textFlow.format = textFlowFormat;
            var verticalText:Boolean = _textFlow.blockProgression == BlockProgression.RL;
            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            _textFlow.flowComposer.updateAllControllers();
            var lineNumber:int;
            var contentWidth:Number = logicalContentWidth(controller, verticalText);
            atLineStartInternal(1, 7000, 115, Float.LEFT);		// insert graphic longer than longest line
            //		assertTrue("Expected larger content width because of trailing float", logicalContentWidth(controller, verticalText) > contentWidth);
        }

        [Test]
        public function noFloatsWithMeasureOrExplicit():void
        {
            // We expect that when text is not wrapping, floats will behave as inlines.

            var oldLinePos:Array;
            var newLinePos:Array;
            var flowComposer:IFlowComposer = _textFlow.flowComposer;
            var controller:ContainerController = flowComposer.getControllerAt(0);
            var textFlowFormat:TextLayoutFormat;
            var width:Number = controller.compositionWidth;
            var height:Number = controller.compositionHeight;

            // Create baseline to compare against, using inlines
            var verticalText:Boolean = _textFlow.blockProgression == BlockProgression.RL;
            textFlowFormat = new TextLayoutFormat(_textFlow.format);
            textFlowFormat.lineBreak = LineBreak.EXPLICIT;
            _textFlow.format = textFlowFormat;
            atLineMiddleInternal(1, 100, 100, Float.NONE);
            atLineMiddleInternal(2, 100, 100, Float.NONE);
            flowComposer.updateAllControllers();
            oldLinePos = getCompositionResults(verticalText, flowComposer);

            // Flip inlines to floats
            for (var leaf:FlowLeafElement = _textFlow.getFirstLeaf(); leaf; leaf = leaf.getNextLeaf())
            {
                if (leaf is InlineGraphicElement)
                    (leaf as InlineGraphicElement).float = Float.LEFT;
            }

            // Test lineBreak=explicit, with floats
            flowComposer.updateAllControllers();
            newLinePos = getCompositionResults(verticalText, flowComposer);
            assertCompositionMatches(oldLinePos, newLinePos);

            // Test with lineBreak=toFit, with measuring
            textFlowFormat = new TextLayoutFormat(_textFlow.format);
            textFlowFormat.lineBreak = LineBreak.TO_FIT;
            _textFlow.format = textFlowFormat;
            if (verticalText)
                controller.setCompositionSize(width, NaN);
            else
                controller.setCompositionSize(NaN, height);
            flowComposer.updateAllControllers();
            newLinePos = getCompositionResults(verticalText, flowComposer);
            assertCompositionMatches(oldLinePos, newLinePos);
        }

        [Test]
        public function hoistFailure():void
            // Test case where a graphic is narrow enough to get a hoist request, but too tall to fit once its composed.
            // Should fall back to pushing to the next parcel.
        {
            var width:Number = 100;
            var height:Number = 100;
            var verticalText:Boolean = _textFlow.blockProgression == BlockProgression.RL;
            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            controller.horizontalScrollPolicy = ScrollPolicy.OFF;
            controller.verticalScrollPolicy = ScrollPolicy.OFF;
            if (verticalText)
                width = controller.compositionWidth;
            else
                height = controller.compositionHeight;

            var textFlowLine:TextFlowLine = _textFlow.flowComposer.getLineAt(1);
            if (!textFlowLine)
                return;

            var pos:int = textFlowLine.absoluteStart + (textFlowLine.textLength / 2);
            var floatObject:DisplayObject = addFloatAtPosition(pos, width, height, Float.LEFT);

            _textFlow.flowComposer.updateAllControllers();

            assertTrue("Expected float to get pushed out of controller, but its a child of container", !controller.container.contains(floatObject));
            assertTrue("Expected float to get pushed out of controller, but its within controller textLength bounds", pos > controller.absoluteStart + controller.textLength);
        }

        [Test]
        public function noEmergencyBreakByFloat():void
        {
            // We should get breaks in the middle of words because a float fills up most but not all of the column.
            // Text should appear below the float if the word doesn't fit next to the float.
            var secondParagraph:ParagraphElement = _textFlow.getChildAt(1) as ParagraphElement;
            var width:Number = (_textFlow.computedFormat.blockProgression == BlockProgression.RL) ? 458 : 807;
            var floatPosition:int = secondParagraph.getAbsoluteStart();
            var floatObject:DisplayObject = addFloatAtPosition(floatPosition, width, 60, Float.START);
            _textFlow.flowComposer.updateAllControllers();
            var textFlowLine:TextFlowLine = _textFlow.flowComposer.findLineAtPosition(floatPosition + 1);
            var lastCharInLine:String = _textFlow.getText(textFlowLine.absoluteStart + textFlowLine.textLength - 1, textFlowLine.absoluteStart + textFlowLine.textLength);
            assertTrue("Line should end with a legal word separator (expected space", lastCharInLine == " ");
        }

        [Test]
        public function fillsColumnRecursion():void
        {
            // Detects an infinite recursion in composition
            // Add a float that almost but not quite fits the whole column
            var secondParagraph:ParagraphElement = _textFlow.getChildAt(1) as ParagraphElement;
            var width:Number = (_textFlow.computedFormat.blockProgression == BlockProgression.RL) ? 458 : 807;
            var floatObject:DisplayObject = addFloatAtPosition(secondParagraph.getAbsoluteStart(), width, 60, Float.START);
            _textFlow.flowComposer.updateAllControllers();
        }

        [Test]
        public function fillsColumn():void
        {
            var width:Number = 100;
            var height:Number = 100;
            var verticalText:Boolean = _textFlow.blockProgression == BlockProgression.RL;
            if (verticalText)
                height = _textFlow.flowComposer.getControllerAt(0).compositionHeight;
            else
                width = _textFlow.flowComposer.getControllerAt(0).compositionWidth;
            atLineMiddleInternal(1, width, height, Float.LEFT);
            _textFlow.flowComposer.updateAllControllers();
        }

        [Test]
        public function atControllerEnd():void
        {
            // Float at the end of a scrollable container should appear in the container even if it
            // would otherwise be too tall.
            var verticalText:Boolean = _textFlow.blockProgression == BlockProgression.RL;
            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            controller.verticalScrollPolicy = ScrollPolicy.ON;
            var width:Number = 50;
            var height:Number = controller.compositionHeight + 50;
            if (verticalText)
            {
                width = controller.compositionWidth + 50;
                height = 50;
            }

            var secondPara:ParagraphElement = _textFlow.getChildAt(1) as ParagraphElement;
            var floatPosition:int = secondPara.getAbsoluteStart();
            var floatObject:DisplayObject = addFloatAtPosition(floatPosition, width, height, Float.START);
            _textFlow.flowComposer.updateAllControllers();
            assertTrue("Float should be in the container", controller.container.contains(floatObject));

            if (verticalText)
                controller.horizontalScrollPolicy = ScrollPolicy.OFF;
            else
                controller.verticalScrollPolicy = ScrollPolicy.OFF;
            _textFlow.flowComposer.updateAllControllers();
            assertTrue("Float should not be composed in the container", controller.absoluteStart + controller.textLength <= floatPosition);
            assertTrue("Float should not be displayed in the container", !controller.container.contains(floatObject));

            // Turning scrolling off changes the basic coordinate system
            if (verticalText)
                _disableBoundsCheck = true;
        }

        [Test]
        public function widerThanColumn():void
        {
            // Float is wider than the container. If the height of the float fits, and there are
            // no preceeding floats, it should still go in the column, and overlap the adjacent
            // columns
            setUpContainers(3);

            var verticalText:Boolean = _textFlow.blockProgression == BlockProgression.RL;

            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            var width:Number = controller.compositionWidth + 50;
            var height:Number = 100;
            if (verticalText)
            {
                width = 100;
                height = controller.compositionHeight + 50;
            }
            _textFlow.flowComposer.updateAllControllers();
            var contentBoundsTextOnly:Rectangle = controller.getContentBounds();

            var floatObject:DisplayObject = addFloatAtPosition(0, width, height, Float.START);
            verifyFloatInLine(0, width, height, Float.START, floatObject);
            _textFlow.flowComposer.updateAllControllers();
            var contentBoundsWithFloat:Rectangle = controller.getContentBounds();
            if (_textFlow.computedFormat.blockProgression == BlockProgression.RL)
            {
                assertTrue("Content bounds with a float wider than the column should be larger than content bounds with just text", contentBoundsWithFloat.height > contentBoundsTextOnly.height);
                assertTrue("Content bounds with a float should be equal to or greater than float alone", contentBoundsWithFloat.height >= height);
            }
            else
            {
                assertTrue("Content bounds with a float wider than the column should be larger than content bounds with just text", contentBoundsWithFloat.width > contentBoundsTextOnly.width);
                assertTrue("Content bounds with a float should be equal to or greater than float alone", contentBoundsWithFloat.width >= width);
            }

            // Check that if the float protrudes past the text it's factored into the content height
            SelManager.deleteText(new SelectionState(_textFlow, 50, int.MAX_VALUE));		// delete so there's not so much text
            _textFlow.flowComposer.updateAllControllers();
            var contentBoundsAfterDelete:Rectangle = controller.getContentBounds();
            if (_textFlow.computedFormat.blockProgression == BlockProgression.RL)
            {
                assertTrue("Content bounds doesn't include logical height of float", contentBoundsAfterDelete.width >= width);
            }
            else
            {
                assertTrue("Content bounds doesn't include height of float", contentBoundsAfterDelete.height >= height);
            }
            SelManager.undo();		// undo the delete of the text

            // Resize the first container smaller, so the float goes overset
            if (verticalText)
                controller.setCompositionSize(width - 1, controller.compositionHeight);
            else
                controller.setCompositionSize(controller.compositionWidth, height - 1);
            _textFlow.flowComposer.updateAllControllers();
            var secondController:ContainerController = _textFlow.flowComposer.getControllerAt(1);
            assertTrue("Expected the float to get pushed to second container", secondController.absoluteStart == 0);
            assertTrue("Float should be in the second container", secondController.container.contains(floatObject));

            // Try it again with columns instead of containers -- should be the same
            setUpContainers(1);
            controller = _textFlow.flowComposer.getControllerAt(0);
            controller.columnCount = 3;
            verifyFloatInLine(0, width, height, Float.START, floatObject);

            // Make the first float smaller, and add a second large float afterwards
            var inlineElement:InlineGraphicElement = _textFlow.findLeaf(0) as InlineGraphicElement;
            inlineElement.width = 50;
            inlineElement.height = 50;
            var secondFloat:DisplayObject = addFloatAtPosition(4, width, height, Float.START);
            _textFlow.flowComposer.updateAllControllers();
            assertTrue("Second float should not appear on the first line", verticalText ? (secondFloat.parent.x < floatObject.parent.x) : (secondFloat.parent.y > floatObject.parent.y));
            assertTrue("Second float should be in the container", controller.container.contains(secondFloat));
        }

        [Test]
        public function widerThanColumnScroll():void		// Watson 2762393
        {
            // Float is wider than the container. If any part of the float is visible, the
            // float should appear in the container. Width of float should be counted in
            // the contentWidth.


            var xml:XML =
                    <TextFlow xmlns='http://ns.adobe.com/textLayout/2008'>
                        <span fontSize="20">Hello, Dear Guest,</span>
                        <p></p>
                        <p>
                            <span>Donec sed risus nec risus elementum cursus eget non nulla. Integer dui mauris, lobortis at varius quis, elementum at justo. Ut lacinia arcu vitae ipsum pulvinar feugiat a ut risus. Vivamus nulla nisi, varius vitae commodo ut, volutpat quis magna. Cras posuere quam magna. Aenean felis purus, pellentesque nec fringilla id, dignissim quis elit. Praesent velit libero, laoreet quis dignissim id, varius quis neque. Suspendisse vulputate placerat purus. Fusce euismod fringilla ornare. Nulla et urna est. Proin a tellus et tortor feugiat iaculis.</span>
                        </p>
                        <p>
                            <span>Donec sed risus nec risus elementum cursus eget non nulla. Integer dui mauris, lobortis at varius quis, elementum at justo. Ut lacinia arcu vitae ipsum pulvinar feugiat a ut risus. Vivamus nulla nisi, varius vitae commodo ut, volutpat quis magna. Cras posuere quam magna. Aenean felis purus, pellentesque nec fringilla id, dignissim quis elit. Praesent velit libero, laoreet quis dignissim id, varius quis neque. Suspendisse vulputate placerat purus. Fusce euismod fringilla ornare. Nulla et urna est. Proin a tellus et tortor feugiat iaculis.</span>
                        </p>
                        <p>
                            <span>Donec sed risus nec risus elementum cursus eget non nulla. Integer dui mauris, lobortis at varius quis, elementum at justo. Ut lacinia arcu vitae ipsum pulvinar feugiat a ut risus. Vivamus nulla nisi, varius vitae commodo ut, volutpat quis magna. Cras posuere quam magna. Aenean felis purus, pellentesque nec fringilla id, dignissim quis elit. Praesent velit libero, laoreet quis dignissim id, varius quis neque. Suspendisse vulputate placerat purus. Fusce euismod fringilla ornare. Nulla et urna est. Proin a tellus et tortor feugiat iaculis.</span>
                        </p>
                        <p>
                            <span>Donec sed risus nec risus elementum cursus eget non nulla. Integer dui mauris, lobortis at varius quis, elementum at justo. Ut lacinia arcu vitae ipsum pulvinar feugiat a ut risus. Vivamus nulla nisi, varius vitae commodo ut, volutpat quis magna. Cras posuere quam magna. Aenean felis purus, pellentesque nec fringilla id, dignissim quis elit. Praesent velit libero, laoreet quis dignissim id, varius quis neque. Suspendisse vulputate placerat purus. Fusce euismod fringilla ornare. Nulla et urna est. Proin a tellus et tortor feugiat iaculis.</span>
                        </p>
                        <p>
                            <span>Donec sed risus nec risus elementum cursus eget non nulla. Integer dui mauris, lobortis at varius quis, elementum at justo. Ut lacinia arcu vitae ipsum pulvinar feugiat a ut risus. Vivamus nulla nisi, varius vitae commodo ut, volutpat quis magna. Cras posuere quam magna. Aenean felis purus, pellentesque nec fringilla id, dignissim quis elit. Praesent velit libero, laoreet quis dignissim id, varius quis neque. Suspendisse vulputate placerat purus. Fusce euismod fringilla ornare. Nulla et urna est. Proin a tellus et tortor feugiat iaculis.</span>
                        </p>
                        <p>
                            <span>Donec sed risus nec risus elementum cursus eget non nulla. Integer dui mauris, lobortis at varius quis, elementum at justo. Ut lacinia arcu vitae ipsum pulvinar feugiat a ut risus. Vivamus nulla nisi, varius vitae commodo ut, volutpat quis magna. Cras posuere quam magna. Aenean felis purus, pellentesque nec fringilla id, dignissim quis elit. Praesent velit libero, laoreet quis dignissim id, varius quis neque. Suspendisse vulputate placerat purus. Fusce euismod fringilla ornare. Nulla et urna est. Proin a tellus et tortor feugiat iaculis.</span>
                        </p>
                        <p>
                            <span>Donec sed risus nec risus elementum cursus eget non nulla. Integer dui mauris, lobortis at varius quis, elementum at justo. Ut lacinia arcu vitae ipsum pulvinar feugiat a ut risus. Vivamus nulla nisi, varius vitae commodo ut, volutpat quis magna. Cras posuere quam magna. Aenean felis purus, pellentesque nec fringilla id, dignissim quis elit. Praesent velit libero, laoreet quis dignissim id, varius quis neque. Suspendisse vulputate placerat purus. Fusce euismod fringilla ornare. Nulla et urna est. Proin a tellus et tortor feugiat iaculis.</span>
                        </p>
                        <p></p>
                        <p></p>
                        <p></p>
                        <p>
                            <span>Donec sed risus nec risus elementum cursus eget non nulla. Integer dui mauris, lobortis at varius quis, elementum at justo. Ut lacinia arcu vitae ipsum pulvinar feugiat a ut risus. Vivamus nulla nisi, varius vitae commodo ut, volutpat quis magna. Cras posuere quam magna. Aenean felis purus, pellentesque nec fringilla id, dignissim quis elit. Praesent velit libero, laoreet quis dignissim id, varius quis neque. Suspendisse vulputate placerat purus. Fusce euismod fringilla ornare. Nulla et urna est. Proin a tellus et tortor feugiat iaculis.</span>
                        </p>
                    </TextFlow>;

            initializeFlow(TextConverter.importToFlow(xml, TextConverter.TEXT_LAYOUT_FORMAT));
            var verticalText:Boolean = _textFlow.blockProgression == BlockProgression.RL;

            // Insert a float wider than the column into the empty second paragraph
            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            var width:Number = controller.compositionWidth + 100;
            var height:Number = controller.compositionHeight + 100;
            var floatPosition:int = _textFlow.getChildAt(1).getAbsoluteStart();
            var floatObject:DisplayObject = addFloatAtPosition(floatPosition, width, height, Float.END);
            _textFlow.flowComposer.updateAllControllers();

            verifyFloatInLine(floatPosition, width, height, Float.END, floatObject);
            assertTrue("Float should be visible", controller.container.contains(floatObject));

            var contentBoundsWithFloat:Rectangle = controller.getContentBounds();
            if (_textFlow.computedFormat.blockProgression == BlockProgression.RL)
            {
                assertTrue("Content bounds with a float wider than the column should be larger than content bounds with just text", contentBoundsWithFloat.height > controller.compositionHeight);
                assertTrue("Content bounds with a float should be equal to or greater than float alone", contentBoundsWithFloat.height >= height);
            }
            else
            {
                assertTrue("Content bounds with a float wider than the column should be larger than content bounds with just text", contentBoundsWithFloat.width > controller.compositionWidth);
                assertTrue("Content bounds with a float should be equal to or greater than float alone", contentBoundsWithFloat.width >= width);
            }

            controller.verticalScrollPosition = contentBoundsWithFloat.height;
            _textFlow.flowComposer.updateAllControllers();
            //		assertTrue("Float should not be visible", !controller.container.contains(floatObject));

            controller.verticalScrollPosition = 0;
            _textFlow.flowComposer.updateAllControllers();
            assertTrue("Float should be visible", controller.container.contains(floatObject));

        }

        [Test]
        public function floatOnly():void
        {
            // TextFlow contains only a single float, no text
            setUpFlow("");
            atParagraphStartInternal(_textFlow.getFirstLeaf(), 100, 100, Float.LEFT);

            // hittest (Watson 2617901)
            // In RTL, we're getting different results from the Player depending on Astro or Argo...
            if (_textFlow.computedFormat.direction == Direction.LTR || Configuration.playerEnablesArgoFeatures)
            {
                SelManager.selectRange(0, 0);
                _flowComposer.updateAllControllers();
                var controller:ContainerController = _flowComposer.getControllerAt(0);
                var mouseEvent:MouseEvent = new MouseEvent(MouseEvent.MOUSE_DOWN, true, false, 200, 200, controller.container, false, false, false, false);
                controller.container.dispatchEvent(mouseEvent);

                assertTrue("Expected insertion point after float", SelManager.absoluteStart == 1);
            }

        }

        public function inlineAndFloat():void
        {
            // Inline as first leaf, followed by float. Watson 2636066

            // TextFlow contains only a single float, no text
            setUpFlow("A");
            var inlineDO:DisplayObject = addFloatAtPosition(0, 100, 100, Float.NONE);
            var floatDO:DisplayObject = addFloatAtPosition(1, 100, 100, Float.LEFT);

        }

        public function convertFloatToInline():void
        {
            var floatValueList:Array = [Float.LEFT, Float.RIGHT , Float.NONE, Float.START, Float.END ];	// start & end disabled to make tests run faster

            // Test switching the float type of an inline graphic element
            var floatValue:String = floatValueList[floatTypeList.length - 1];
            var secondParagraph:FlowElement = _textFlow.getChildAt(1);
            var floatPosition:int = secondParagraph.getAbsoluteStart();
            var floatObject:DisplayObject = addFloatAtPosition(floatPosition, 30, 30, floatValue);
            _textFlow.flowComposer.updateAllControllers();
            var inlineGraphicElement:InlineGraphicElement = _textFlow.findLeaf(floatPosition) as InlineGraphicElement;
            SelManager.selectRange(floatPosition, floatPosition + 1);
            for each (floatValue in floatValueList)
                SelManager.modifyInlineGraphic(inlineGraphicElement.source, inlineGraphicElement.width, inlineGraphicElement.height, floatValue);
        }

        public function verticalAlignInline():void
            // Make sure that vertical alignment (especially justification) is working correctly with inlines. See 2772554
        {
            // TextFlow contains a single line of text with an inline, should be centered vertically
            var verticalText:Boolean = _textFlow.blockProgression == BlockProgression.RL;
            setUpFlow("Vertical align with inlines test");

            // Check for middle
            var textFlowFormat:TextLayoutFormat = new TextLayoutFormat(_textFlow.format);
            textFlowFormat.verticalAlign = VerticalAlign.MIDDLE;
            _textFlow.format = textFlowFormat;
            var floatObject:DisplayObject = addFloatAtPosition(0, 100, 100, Float.NONE);
            _textFlow.flowComposer.updateAllControllers();

            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            var bounds:Rectangle = floatObject.getBounds(controller.container);
            if (verticalText)
                assertTrue("Expected float would be in the middle of the container", Math.abs((controller.compositionWidth + bounds.x) - Math.abs(bounds.x + bounds.width)) < controller.compositionWidth * .1);
            else
                assertTrue("Expected float would be in the middle of the container", Math.abs((bounds.y + (bounds.height / 2)) - (controller.compositionHeight / 2)) < controller.compositionHeight * .1);

            // Check for bottom. Leave a little wiggle room in this test because the inline is on the baseline and not against the bottom
            textFlowFormat.verticalAlign = VerticalAlign.BOTTOM;
            _textFlow.format = textFlowFormat;
            _textFlow.flowComposer.updateAllControllers();
            bounds = floatObject.getBounds(controller.container);
            if (verticalText)
                assertTrue("Expected float would be in the bottom of the container", Math.abs(bounds.x + controller.compositionWidth) < 10);
            else
                assertTrue("Expected float would be in the bottom of the container", Math.abs(bounds.y + bounds.height - controller.compositionHeight) < 10);

            // Check for justify -- this needs multiple lines. Set alignment to TOP, check position, reset to JUSTIFY, position should have changed.
            setUpFlow("Vertical align with inlines test  dlfkj sdlk jsdlfkj sdlkfj dslkfj sdlkfj dlskfj dslkfj lkdsfj ldksfj dlksfj dslkfj dlskjfdslkjf lsdkjf lsdkfj sdlkfj sdlkfj dslkfj dslkfj sdlkfj dslkf jdslkfj sdlkfj sdlkfj ldskfj ldksfj lsdkfjldskfj lsdkfjdslkfj");
            textFlowFormat.verticalAlign = VerticalAlign.TOP;
            _textFlow.format = textFlowFormat;
            floatObject = addFloatAtPosition(0, 100, 100, Float.NONE);
            _textFlow.flowComposer.updateAllControllers();

            controller = _textFlow.flowComposer.getControllerAt(0);
            var topBounds:Rectangle = floatObject.getBounds(controller.container);

            textFlowFormat.verticalAlign = VerticalAlign.JUSTIFY;
            _textFlow.format = textFlowFormat;
            _textFlow.flowComposer.updateAllControllers();
            bounds = floatObject.getBounds(controller.container);
            assertTrue(!bounds.equals(topBounds), "Line should have been moved when vertical justification applied");
        }

        private function verticalAlignMiddle(content:String):void
        {
            // TextFlow contains a single line of text with a float, should be centered vertically
            // Floats extends past the text
            var verticalText:Boolean = _textFlow.blockProgression == BlockProgression.RL;
            setUpFlow(content);
            var textFlowFormat:TextLayoutFormat = new TextLayoutFormat(_textFlow.format);
            textFlowFormat.verticalAlign = VerticalAlign.MIDDLE;
            _textFlow.format = textFlowFormat;
            var floatObject:DisplayObject = addFloatAtPosition(0, 100, 100, Float.LEFT);
            _textFlow.flowComposer.updateAllControllers();
            var floatHolder:DisplayObjectContainer = floatObject.parent;

            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            if (verticalText)
                assertTrue("Expected float would be in the middle of the container", Math.abs((controller.compositionWidth + floatHolder.x) - Math.abs(floatHolder.x + floatObject.width)) < controller.compositionWidth * .1);
            else
                assertTrue("Expected float would be in the middle of the container", Math.abs((floatHolder.y + (floatObject.height / 2)) - (controller.compositionHeight / 2)) < controller.compositionHeight * .1);
        }

        public function verticalAlignMiddleFloatAtEnd():void
        {
            // TextFlow contains a single line of text with a float, should be centered vertically
            // Floats extends past the text
            verticalAlignMiddle("A");
        }

        public function verticalAlignMiddleTextAtEnd():void
        {
            // TextFlow contains a single line of text with a float, should be centered vertically
            // Text extends past the float
            verticalAlignMiddle("A\nBBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB ");
        }

        private function verticalAlignBottom(content:String):void
        {
            // TextFlow contains a single line of text with a float, should be on the bottom of the container
            // Floats extends past the text
            var verticalText:Boolean = _textFlow.blockProgression == BlockProgression.RL;
            setUpFlow(content);
            var textFlowFormat:TextLayoutFormat = new TextLayoutFormat(_textFlow.format);
            textFlowFormat.verticalAlign = VerticalAlign.BOTTOM;
            _textFlow.format = textFlowFormat;
            var floatObject:DisplayObject = addFloatAtPosition(0, 100, 100, Float.LEFT);
            _textFlow.flowComposer.updateAllControllers();
            var floatHolder:DisplayObjectContainer = floatObject.parent;

            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            if (verticalText)
                assertTrue("Expected float would be in the bottom of the container", Math.abs(floatHolder.x + controller.compositionWidth) < 1);
            else
                assertTrue("Expected float would be in the bottom of the container", Math.abs(floatHolder.y + floatObject.height - controller.compositionHeight) < 1);
        }

        public function verticalAlignBottomFloat2636122():void
        {
            // test for bug 2636122 - very similar to verticalAlignBottom, but not quite

            // BoundsChecker fails on this because it sets verticalAlign on controller, BoundsChecker checks whole flow
            _disableBoundsCheck = true;

            var verticalText:Boolean = _textFlow.blockProgression == BlockProgression.RL;
            setUpFlow("A");
            _textFlow.flowComposer.updateAllControllers();
            var floatObject:DisplayObject = addFloatAtPosition(1, 100, 100, Float.LEFT);
            _textFlow.flowComposer.updateAllControllers();
            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            var textFlowFormat:TextLayoutFormat = new TextLayoutFormat(controller.format);
            textFlowFormat.verticalAlign = VerticalAlign.BOTTOM;
            controller.format = textFlowFormat;
            _textFlow.flowComposer.updateAllControllers();
            var floatHolder:DisplayObjectContainer = floatObject.parent;

            if (verticalText)
                assertTrue("Expected float would be in the bottom of the container", Math.abs(floatHolder.x + controller.compositionWidth) < 1);
            else
                assertTrue("Expected float would be in the bottom of the container", Math.abs(floatHolder.y + floatObject.height - controller.compositionHeight) < 1);
            var tfl:TextFlowLine = _textFlow.flowComposer.getLineAt(0);
            if (verticalText)
                assertTrue("Expected line would be in the bottom of the container", Math.abs((tfl.x + tfl.height) - (floatHolder.x + floatHolder.width)) < 1);
            else
                assertTrue("Expected line would be in the bottom of the container", Math.abs(tfl.y + floatObject.height - controller.compositionHeight) < 1);

        }

        public function verticalAlignBottomFloatAtEnd():void
        {
            // TextFlow contains a single line of text with a float, should be centered vertically
            // Floats extends past the text
            verticalAlignBottom("A");
        }

        public function verticalAlignBottomTextAtEnd():void
        {
            // TextFlow contains a single line of text with a float, should be centered vertically
            // Text extends past the float
            verticalAlignBottom("A\nBBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB BBB ");
        }

        private function getCompositionResults(verticalText:Boolean, flowComposer:IFlowComposer):Array
        {
            var linePos:Array = [];
            var numLines:int = flowComposer.numLines;
            for (var i:int = 0; i < numLines; ++i)
            {
                var line:TextFlowLine = flowComposer.getLineAt(i);
                linePos.push(verticalText ? line.x : line.y);
            }
            return linePos;
        }

        private function assertCompositionMatches(oldLineArray:Array, newLineArray:Array):void
        {
            assertTrue("Expected same composition, found different line count", oldLineArray.length == newLineArray.length);
            for (var i:int = 0; i < oldLineArray.length; ++i)
            {
                assertTrue("Expected same composition, found line " + i.toString() + "moved in logical vertical direction", oldLineArray[i] == newLineArray[i]);
            }
        }

        [Test]
        public function noVJ():void
        {
            // We expect that verticalAlign = justify in the presence of floats is identical to verticalAlign = top (i.e.
            // the verticalAlign is ignored.
            var verticalText:Boolean = _textFlow.blockProgression == BlockProgression.RL;
            var flowComposer:IFlowComposer = _textFlow.flowComposer;
            var line:TextFlowLine;
            atLineMiddleInternal(1, 100, 100, Float.LEFT);
            flowComposer.updateAllControllers();
            var oldLinePos:Array = getCompositionResults(verticalText, flowComposer);

            var textFlowFormat:TextLayoutFormat = new TextLayoutFormat(_textFlow.format);
            textFlowFormat.verticalAlign = VerticalAlign.JUSTIFY;
            _textFlow.format = textFlowFormat;
            flowComposer.updateAllControllers();
            var newLinePos:Array = getCompositionResults(verticalText, flowComposer);

            assertCompositionMatches(oldLinePos, newLinePos);
        }

        private function textAlignRight(pos:int):void
        {
            // Test that right-aligned floats do not overlap right aligned lines
            var verticalText:Boolean = _textFlow.blockProgression == BlockProgression.RL;
            var textFlowFormat:TextLayoutFormat = new TextLayoutFormat(_textFlow.format);
            textFlowFormat.textAlign = TextAlign.RIGHT;
            _textFlow.format = textFlowFormat;
            var floatObject:DisplayObject = addFloatAtPosition(pos, 100, 100, Float.RIGHT);
            _textFlow.flowComposer.updateAllControllers();
            var floatHolder:DisplayObjectContainer = floatObject.parent;

            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            var lineIndex:int = _textFlow.flowComposer.findLineIndexAtPosition(pos);
            var textFlowLine:TextFlowLine = _textFlow.flowComposer.getLineAt(lineIndex + 1);
            var textLine:TextLine
            var bbox:Rectangle = textFlowLine.getBounds();
            if (verticalText)
                assertTrue("Expected float would not overlap text", floatHolder.y >= textFlowLine.y + bbox.width);
            else
                assertTrue("Expected float would not overlap text", Math.abs(floatHolder.x - (textFlowLine.x + bbox.width)) < 2);
        }

        [Test]
        public function textAlignRightAtStart():void
        {
            textAlignRight(0);
        }

        [Test]
        public function textAlignRightInMiddle():void
        {
            var textFlowLine:TextFlowLine = _textFlow.flowComposer.getLineAt(3);

            textAlignRight(textFlowLine.absoluteStart + textFlowLine.textLength / 2);
        }

        private const INDENT_AMOUNT:Number = 20;

        [Test]
        public function leftIndent():void
        {
            // Test that floats in indented paragraphs are indented

            // Try a left float with a start indent
            var leaf:FlowLeafElement = _textFlow.getFirstLeaf();
            var firstPara:ParagraphElement = leaf.getParagraph();
            var paragraphFormat:TextLayoutFormat = new TextLayoutFormat(firstPara.format);
            if (firstPara.computedFormat.direction == Direction.LTR)
                paragraphFormat.paragraphStartIndent = INDENT_AMOUNT;
            else
                paragraphFormat.paragraphEndIndent = INDENT_AMOUNT;
            paragraphFormat.textAlign = TextAlign.JUSTIFY;
            firstPara.format = paragraphFormat;
            var floatObject:DisplayObject = addFloatAtPosition(200, 100, 100, Float.LEFT);
            _textFlow.flowComposer.updateAllControllers();
            var floatHolder:DisplayObjectContainer = floatObject.parent;

            if (_textFlow.computedFormat.blockProgression == BlockProgression.RL)
                assertTrue("Expected float to be indented with paragraph", floatHolder.y == INDENT_AMOUNT);
            else
                assertTrue("Expected float to be indented with paragraph", floatHolder.x == INDENT_AMOUNT);
        }

        [Test]
        public function rightIndent():void
        {
            // Test that floats in indented paragraphs are indented

            // Try a right float with a right indent
            var leaf:FlowLeafElement = _textFlow.getFirstLeaf();
            var firstPara:ParagraphElement = leaf.getParagraph();
            var paragraphFormat:TextLayoutFormat = new TextLayoutFormat(firstPara.format);
            if (firstPara.computedFormat.direction == Direction.RTL)
                paragraphFormat.paragraphStartIndent = INDENT_AMOUNT;
            else
                paragraphFormat.paragraphEndIndent = INDENT_AMOUNT;
            paragraphFormat.textAlign = TextAlign.JUSTIFY;
            firstPara.format = paragraphFormat;
            var floatObject:DisplayObject = addFloatAtPosition(200, 100, 100, Float.RIGHT);
            _textFlow.flowComposer.updateAllControllers();
            var floatHolder:DisplayObjectContainer = floatObject.parent;

            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            if (_textFlow.computedFormat.blockProgression == BlockProgression.RL)
                assertTrue("Expected float to be indented with paragraph", Math.abs((floatHolder.y + floatObject.height) - (controller.compositionHeight - INDENT_AMOUNT)) < 1);
            else
                assertTrue("Expected float to be indented with paragraph", Math.abs((floatHolder.x + floatObject.width) - (controller.compositionWidth - INDENT_AMOUNT)) < 1);
        }

        [Test]
        public function leftBigIndent():void
        {
            var indentAmount:Number = 200;  // bigger than float width

            // Add a float, and check that a paragraph with a big indent will wrap to the max of the indent & float
            var leaf:FlowLeafElement = _textFlow.getLastLeaf();
            var secondPara:ParagraphElement = leaf.getParagraph();
            var paragraphFormat:TextLayoutFormat = new TextLayoutFormat(secondPara.format);
            if (secondPara.computedFormat.direction == Direction.LTR)
                paragraphFormat.paragraphStartIndent = indentAmount;
            else
                paragraphFormat.paragraphEndIndent = indentAmount;
            paragraphFormat.textAlign = TextAlign.JUSTIFY;
            secondPara.format = paragraphFormat;

            var floatObject:DisplayObject = addFloatAtPosition(200, 100, 100, Float.LEFT);
            _textFlow.flowComposer.updateAllControllers();

            var lineIndex:int = _textFlow.flowComposer.findLineIndexAtPosition(secondPara.getAbsoluteStart());
            var textFlowLine:TextFlowLine = _textFlow.flowComposer.getLineAt(lineIndex);
            var bbox:Rectangle = textFlowLine.getBounds();
            if (secondPara.computedFormat.direction == Direction.LTR)
            {
                if (_textFlow.computedFormat.blockProgression == BlockProgression.RL)
                    assertTrue("Expected line in second paragraph to have large indent", bbox.top == indentAmount);
                else
                    assertTrue("Expected line in second paragraph to have large indent", bbox.left == indentAmount);
            }
        }

        [Test]
        public function rightBigIndent():void
        {
            var indentAmount:Number = 200;  // bigger than float width

            // Add a float, and check that a paragraph with a big indent will wrap to the max of the indent & float
            var leaf:FlowLeafElement = _textFlow.getLastLeaf();
            var secondPara:ParagraphElement = leaf.getParagraph();
            var paragraphFormat:TextLayoutFormat = new TextLayoutFormat(secondPara.format);
            if (secondPara.computedFormat.direction == Direction.LTR)
                paragraphFormat.paragraphEndIndent = indentAmount;
            else
                paragraphFormat.paragraphStartIndent = indentAmount;
            paragraphFormat.textAlign = TextAlign.JUSTIFY;
            secondPara.format = paragraphFormat;

            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            var floatObject:DisplayObject = addFloatAtPosition(200, 100, 100, Float.RIGHT);
            _textFlow.flowComposer.updateAllControllers();

            var lineIndex:int = _textFlow.flowComposer.findLineIndexAtPosition(secondPara.getAbsoluteStart());
            var textFlowLine:TextFlowLine = _textFlow.flowComposer.getLineAt(lineIndex);
            var bbox:Rectangle = textFlowLine.getBounds();
            if (_textFlow.computedFormat.blockProgression == BlockProgression.RL)
                assertTrue("Expected line in second paragraph to have large indent", Math.abs(bbox.bottom - (controller.compositionHeight - indentAmount)) < 1);
            else
                assertTrue("Expected line in second paragraph to have large indent", Math.abs(bbox.right - (controller.compositionWidth - indentAmount)) < 1);
        }

        [Test]
        public function clearNoPrecedingFloatAll():void
        {
            clearAll(clearNoPrecedingFloat, 0);
        }

        private function clearNoPrecedingFloat(clear:String, floatCount:int):void
        {
            var indentAmount:Number = 200;
            var leaf:FlowLeafElement = _textFlow.getLastLeaf();
            var secondPara:ParagraphElement = leaf.getParagraph();
            _textFlow.flowComposer.updateAllControllers();
            if (_textFlow.computedFormat.blockProgression == BlockProgression.RL)
                var secondPara_x:int = secondPara.getAbsoluteStart();
            else
                var secondPara_y:int = secondPara.getAbsoluteStart();
            var paragraphFormat:TextLayoutFormat = new TextLayoutFormat(secondPara.format);
            paragraphFormat.clearFloats = clear;
            if (secondPara.computedFormat.direction == Direction.LTR)
                paragraphFormat.paragraphEndIndent = indentAmount;
            else
                paragraphFormat.paragraphStartIndent = indentAmount;
            paragraphFormat.textAlign = TextAlign.JUSTIFY;
            secondPara.format = paragraphFormat;

            _textFlow.flowComposer.updateAllControllers();

            if (_textFlow.computedFormat.blockProgression == BlockProgression.RL)
                assertTrue("Second paragraph should not be impacted by clear", secondPara_x == secondPara.getAbsoluteStart());
            else
                assertTrue("Second paragraph should not be impacted by clear", secondPara_y == secondPara.getAbsoluteStart());
        }

        [Test]
        public function leftIndentWithTab():void
        {
            var verticalText:Boolean = _textFlow.blockProgression == BlockProgression.RL;
            SelManager.selectAll();
            SelManager.deleteText();
            SelManager.insertText("\tThis is test");
            _textFlow.flowComposer.updateAllControllers();

            var paragraphFormat:TextLayoutFormat = new TextLayoutFormat(_textFlow.format);
            var leaf:FlowLeafElement = _textFlow.getFirstLeaf();
            var firstPara:ParagraphElement = leaf.getParagraph();
            if (firstPara.computedFormat.direction == Direction.LTR)
                paragraphFormat.paragraphStartIndent = INDENT_AMOUNT;
            else
                paragraphFormat.paragraphEndIndent = INDENT_AMOUNT;
            paragraphFormat.textAlign = TextAlign.JUSTIFY;
            firstPara.format = paragraphFormat;

            var floatObject:DisplayObject = addFloatAtPosition(0, 100, 100, Float.LEFT);
            paragraphFormat.tabStops = "e318";
            SelManager.applyParagraphFormat(paragraphFormat);
            _textFlow.flowComposer.updateAllControllers();
            var floatHolder:DisplayObjectContainer = floatObject.parent;

            var paragraph:ParagraphElement = _textFlow.getFirstLeaf().getParagraph();
            var posStart:int = paragraph.getAbsoluteStart();
            var lineIndex:int = _textFlow.flowComposer.findLineIndexAtPosition(posStart);
            var tfl:TextFlowLine = _textFlow.flowComposer.getLineAt(lineIndex);

            if (verticalText)
                assertTrue("Expected float to be indented with paragraph", floatHolder.x <= tfl.x);
            else
                assertTrue("Expected float to be indented with paragraph", floatHolder.y <= tfl.y);
        }

        [Test]
        public function rightIndentWithTab():void
        {
            var verticalText:Boolean = _textFlow.blockProgression == BlockProgression.RL;
            SelManager.selectAll();
            SelManager.deleteText();
            SelManager.insertText("\tThis is test");
            _textFlow.flowComposer.updateAllControllers();

            var paragraphFormat:TextLayoutFormat = new TextLayoutFormat(_textFlow.format);
            var leaf:FlowLeafElement = _textFlow.getFirstLeaf();
            var firstPara:ParagraphElement = leaf.getParagraph();

            if (firstPara.computedFormat.direction == Direction.RTL)
                paragraphFormat.paragraphStartIndent = INDENT_AMOUNT;
            else
                paragraphFormat.paragraphEndIndent = INDENT_AMOUNT;
            paragraphFormat.textAlign = TextAlign.JUSTIFY;
            firstPara.format = paragraphFormat;
            var floatObject:DisplayObject = addFloatAtPosition(5, 100, 100, Float.RIGHT);
            paragraphFormat.tabStops = "e300";
            SelManager.applyParagraphFormat(paragraphFormat);
            _textFlow.flowComposer.updateAllControllers();
            var floatHolder:DisplayObjectContainer = floatObject.parent;

            var paragraph:ParagraphElement = _textFlow.getFirstLeaf().getParagraph();
            var posStart:int = paragraph.getAbsoluteStart();
            var lineIndex:int = _textFlow.flowComposer.findLineIndexAtPosition(posStart);
            var tfl:TextFlowLine = _textFlow.flowComposer.getLineAt(lineIndex);

            if (verticalText)
                assertTrue("Expected float to be indented with paragraph", (floatHolder.y >= (tfl.y + tfl.textLength)));
            else
                assertTrue("Expected float to be indented with paragraph", (( tfl.x + tfl.textLength ) <= floatHolder.x ));
        }

        private function stackedLeftRightFloats(float:String):void
        {
            var width:Number = 100;
            var height:Number = 100;

            var verticalText:Boolean = _textFlow.blockProgression == BlockProgression.RL;
            SelManager.selectAll();
            SelManager.deleteText();
            SelManager.insertText("AAAAAAAAAAAAAAAAAAAAAA\n");
            SelManager.insertText("BBBBBBBBBBBBBBBBBBBBBB\n");
            _textFlow.flowComposer.updateAllControllers();

            var tlf1:TextFlowLine = _textFlow.flowComposer.getLineAt(1);
            var tlf2:TextFlowLine = _textFlow.flowComposer.getLineAt(2);

            var pos1:int = tlf1.absoluteStart;
            var floatObject1:DisplayObject = addFloatAtPosition(pos1, width, height, float);
            var pos2:int = tlf2.absoluteStart;
            var floatObject2:DisplayObject = addFloatAtPosition(pos2, width, height, float);

            verifyFloatInLine(pos1, width, height, float, floatObject1);
            verifyFloatInLine(pos2, width, height, float, floatObject2);
        }

        [Test]
        public function stackedLeftFloats():void
        {
            var float:String = "left";
            stackedLeftRightFloats(float);
        }

        [Test]
        public function stackedRightFloats():void
        {
            var float:String = "right";
            stackedLeftRightFloats(float);
        }

        private var clearArray:Array = [ ClearFloats.LEFT, ClearFloats.RIGHT, ClearFloats.BOTH, ClearFloats.START, ClearFloats.END ];

        private function clearAll(method:Function, floatCount:int):void
        {
            for each (var content:String in contentLanguageList)
            {
                for each (var clearValue:String in clearArray)
                {
                    setUpFlow(content);
                    method(clearValue, floatCount);
                }
            }
        }

        [Test]
        public function clearOneAll():void
        {
            clearAll(clearFloatTest, 1);
        }

        [Test]
        public function clearTwoAll():void
        {
            clearAll(clearFloatTest, 2);
        }

        private function clearFloatTest(clear:String, floatCount:int):void
        {
            var indentAmount:Number = 200;  // bigger than float width

            // Add a float, and check that a paragraph with a big indent will wrap to the max of the indent & float
            var leaf:FlowLeafElement = _textFlow.getLastLeaf();
            var secondPara:ParagraphElement = leaf.getParagraph();
            var paragraphFormat:TextLayoutFormat = new TextLayoutFormat(secondPara.format);
            paragraphFormat.clearFloats = clear;
            paragraphFormat.textAlign = TextAlign.JUSTIFY;
            secondPara.format = paragraphFormat;

            var floatAttr:String = (clear == ClearFloats.LEFT) || (clear == ClearFloats.START) ? Float.LEFT : Float.RIGHT;
            if (_textFlow.computedFormat.direction == Direction.RTL)
            {
                if (clear == ClearFloats.START) floatAttr = Float.RIGHT;
                if (clear == ClearFloats.END) floatAttr = Float.LEFT;
            }
            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            var floatObject:DisplayObject = addFloatAtPosition(200, 100, 100, floatAttr);
            if (floatCount == 2)
            {
                floatObject = addFloatAtPosition(200, 100, 100, floatAttr);
            }
            _textFlow.flowComposer.updateAllControllers();
            var floatHolder:DisplayObjectContainer = floatObject.parent;

            var lineIndex:int = _textFlow.flowComposer.findLineIndexAtPosition(secondPara.getAbsoluteStart());
            var textFlowLine:TextFlowLine = _textFlow.flowComposer.getLineAt(lineIndex);
            var bbox:Rectangle = textFlowLine.getBounds();

            if (_textFlow.computedFormat.blockProgression == BlockProgression.RL)
            {
                assertTrue("ClearFloat:" + clear + " - Second paragraph should be cleared past float " + floatCount, bbox.x + bbox.width < floatHolder.x);
            }
            else
            {
                assertTrue("ClearFloat:" + clear + " - Second paragraph should be cleared past float " + floatCount, bbox.top > floatHolder.y + floatObject.height);
            }
        }

        private function paddingAndMarginsInternal(float:String, width:Number, height:Number, paddingLeft:Number, paddingTop:Number, paddingRight:Number, paddingBottom:Number):void
        {
            var verticalText:Boolean = (_textFlow.computedFormat.blockProgression == BlockProgression.RL);
            var graphic:DisplayObject = addFloatAtPosition(0, width, height, float);
            var ilgElement:InlineGraphicElement = _textFlow.findLeaf(0) as InlineGraphicElement;
            var format:TextLayoutFormat = new TextLayoutFormat(ilgElement.format);
            format.paddingLeft = paddingLeft;
            format.paddingTop = paddingTop;
            format.paddingRight = paddingRight;
            format.paddingBottom = paddingBottom;
            ilgElement.format = format;
            format = new TextLayoutFormat(_textFlow.format);
            format.textAlign = TextAlign.JUSTIFY;
            _textFlow.format = format;
            _flowComposer.updateAllControllers();
            var floatHolder:DisplayObjectContainer = graphic.parent;
            assertTrue("Expected to get inline inserted", ilgElement != null);
            var tfl:TextFlowLine = _flowComposer.getLineAt(0);
            assertTrue("Expected padding between container edge and float", Math.abs(paddingTop - floatHolder.y) <= 1);
            if (verticalText)
            {
                assertTrue("Expected padding between float and text", Math.abs(floatHolder.y + graphic.height + paddingBottom - tfl.y) <= 1);
                assertTrue("Expected padding between container edge and float", Math.abs(paddingRight + (floatHolder.x + graphic.width)) <= 1);
            }
            else
            {
                assertTrue("Expected padding between float and text", Math.abs(floatHolder.x + graphic.width + paddingRight - tfl.x) <= 1);
                assertTrue("Expected padding between container edge and float", Math.abs(paddingLeft - floatHolder.x) <= 1);
            }

        }

        [Test]
        public function negativePaddingAndMargins():void
        {
            _disableBoundsCheck = true;
            paddingAndMarginsInternal(Float.LEFT, 100, 100, -5, -10, -8, -12);
        }

        [Test]
        public function paddingAndMargins():void
        {
            paddingAndMarginsInternal(Float.LEFT, 100, 100, 20, 30, 40, 50);
        }

        [Test]
        public function lineHeightIgnoredOnFloatingImages():void
        {
            // LineHeight is supposed to be ignored on floating images when calculating line positions. Check that this is so.
            // Insert a float at the start of the paragraph, and set lineheight on it.
            var secondParagraph:ParagraphElement = _textFlow.getChildAt(1) as ParagraphElement;
            var floatPosition:int = secondParagraph.getAbsoluteStart();
            var floatObject:DisplayObject = addFloatAtPosition(floatPosition, 10, 10, Float.START);
            verifyFloatInLine(floatPosition, 10, 10, Float.START, floatObject);
            var lineIndex:int = _textFlow.flowComposer.findLineIndexAtPosition(floatPosition + 1);
            var textFlowLine:TextFlowLine = _textFlow.flowComposer.getLineAt(lineIndex);
            var verticalText:Boolean = (_textFlow.computedFormat.blockProgression == BlockProgression.RL);
            var originalPosition:Number = verticalText ? textFlowLine.x : textFlowLine.y;
            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            var originalContentBounds:Rectangle = new Rectangle(controller.contentLeft, controller.contentTop, controller.contentWidth, controller.contentHeight);
            var format:TextLayoutFormat = new TextLayoutFormat();
            format.lineHeight = 100;
            SelManager.selectRange(floatPosition, floatPosition + 1);
            SelManager.applyLeafFormat(format);
            lineIndex = _textFlow.flowComposer.findLineIndexAtPosition(floatPosition + 1);
            textFlowLine = _textFlow.flowComposer.getLineAt(lineIndex);
            assertTrue("TextLine moved when lineHeight applied to floating graphic", originalPosition == (verticalText ? textFlowLine.x : textFlowLine.y));
            var contentBounds:Rectangle = new Rectangle(controller.contentLeft, controller.contentTop, controller.contentWidth, controller.contentHeight);
            assertTrue("Content bounds changed when lineHeight applied to floating graphic", contentBounds.equals(originalContentBounds));
        }

        private function setUpContainers(containerCount:int):void
        {
            testApp.changeContainerSetup("arrangeSideBySide", 0, containerCount);
        }

        [Test]
        public function smallFloatBigText():void
        {
            // Test case where there is a small initial (leading) float that fits in the container, and a larger line of text that
            // gets pushed to the following container. Both the float and the line should get pushed to the following container.
            try
            {
                setUpContainers(2);
                format = new TextLayoutFormat();
                format.fontSize = 14;
                format.paragraphSpaceAfter = 15;
                format.fontFamily = "Times New Roman";
                SelManager.applyFormatToElement(_textFlow, format);

                _textFlow.flowComposer.updateAllControllers();
                var secondControllerStart:int = _textFlow.flowComposer.getControllerAt(1).absoluteStart;
                var floatObject:DisplayObject = addFloatAtPosition(secondControllerStart - 10, 10, 10, _textFlow.computedFormat.direction == Direction.RTL ? Float.RIGHT : Float.LEFT);
                _textFlow.interactionManager.selectRange(secondControllerStart - 9, secondControllerStart - 8);
                var format:TextLayoutFormat = new TextLayoutFormat();
                format.fontSize = 36;
                SelManager.applyLeafFormat(format);

                // Float should appear in the top of the second container
                var secondController:ContainerController = _textFlow.flowComposer.getControllerAt(1);
                var verticalText:Boolean = _textFlow.computedFormat.blockProgression == BlockProgression.RL;
                assertTrue("Float should appear in the second container", secondController.container.contains(floatObject));
                var inlineHolder:DisplayObject = floatObject.parent;
                assertTrue("Float should appear at the top of the container", verticalText ? (inlineHolder.x == -inlineHolder.width) : (inlineHolder.y == 0));
            }
            finally
            {
                //setUpContainers(1);
            }
        }

        [Test]
        public function cursorByAnchor():void
        {
            // Blinking text cursor should be placed by the anchor point and sized to the line
            // NOT put next to the float and sized to the float -- see bug 2609350

            var secondParagraph:ParagraphElement = _textFlow.getChildAt(1) as ParagraphElement;
            var floatPosition:int = secondParagraph.getAbsoluteStart();
            var floatObject:DisplayObject = addFloatAtPosition(floatPosition, 30, 30, Float.START);

            // Turn on the blinking cursor
            _textFlow.interactionManager.focusedSelectionFormat = new SelectionFormat(0xffffff, 1.0, "difference", 0xffffff, 1.0, "difference", 500);

            _textFlow.interactionManager.selectRange(floatPosition, floatPosition);
            _textFlow.flowComposer.updateAllControllers();
            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            var selectionSprite:DisplayObjectContainer = controller.getSelectionSprite(false);
            assertTrue("Expected there to be a blinking cursor selection drawn", selectionSprite != null);
            var cursorBounds:Rectangle = selectionSprite.getBounds(controller.container);
            var lineIndex:int = _textFlow.flowComposer.findLineIndexAtPosition(floatPosition);
            var textFlowLine:TextFlowLine = _textFlow.flowComposer.getLineAt(lineIndex);
            var textLine:TextLine = textFlowLine.getTextLine();
            var atomIndex:int = textLine.getAtomIndexAtCharIndex(floatPosition - secondParagraph.getAbsoluteStart());
            var atomBounds:Rectangle = textLine.getAtomBounds(atomIndex);
            var atomTopLeft:Point = textLine.localToGlobal(atomBounds.topLeft);
            var atomBottomRight:Point = textLine.localToGlobal(atomBounds.bottomRight);
            atomTopLeft = selectionSprite.parent.globalToLocal(atomTopLeft);
            atomBottomRight = selectionSprite.parent.globalToLocal(atomBottomRight);
            atomBounds.topLeft = atomTopLeft;
            atomBounds.bottomRight = atomBottomRight;

            var verticalText:Boolean = _textFlow.computedFormat.blockProgression == BlockProgression.RL;
            if (verticalText)
            {
                assertTrue("Expected logical left edge of cursor to align with anchor's atom bounds left", Math.abs(cursorBounds.top - atomBounds.top) < 1);
                assertTrue("Expected logical height of cursor to align with anchor's atom height", Math.abs(cursorBounds.width - textFlowLine.height) < 1);
            }
            else
            {
                assertTrue("Expected left edge of cursor to align with anchor's atom bounds left", Math.abs(cursorBounds.left - atomBounds.left) < 1);
                assertTrue("Expected height of cursor to align with anchor's atom height", Math.abs(cursorBounds.height - textFlowLine.height) < 1);
            }
        }

        [Test]
        public function insertTextBeforeFloat():void
        {
            // Test for unreported bug that is caused by retrying lines in composition (backing up to retry floats) and reusing TextLines.
            // Bug is now fixed, this tests the fix.

            // Insert a float about 2/3 way along the second line
            _textFlow.flowComposer.updateAllControllers();
            var textFlowLine:TextFlowLine = _textFlow.flowComposer.getLineAt(1);
            var floatPosition:int = textFlowLine.absoluteStart + ((textFlowLine.textLength * 2) / 3);
            var floatObject:DisplayObject = addFloatAtPosition(floatPosition, 100, 100, Float.RIGHT);

            // Start editing in the previous line, about half way along
            textFlowLine = _textFlow.flowComposer.getLineAt(0);
            var editPosition:int = textFlowLine.absoluteStart + (textFlowLine.textLength / 2);
            SelManager.selectRange(editPosition, editPosition);
            SelManager.allowDelayedOperations = false;
            for (var i:int = 0; i < 100; ++i)
            {
                SelManager.insertText("x");
                SelManager.insertText(" ");
            }
        }

        [Test]
        public function textIndentAfterFloat():void
        {
            var textIndentValue:int = 50;
            var leaf:FlowLeafElement = _textFlow.getFirstLeaf();
            var firstPara:ParagraphElement = leaf.getParagraph();
            var format:TextLayoutFormat = new TextLayoutFormat(firstPara.format);
            format.textIndent = textIndentValue;
            firstPara.format = format;
            var floatObject:DisplayObject = addFloatAtPosition(0, 100, 100, Float.START);
            _textFlow.flowComposer.updateAllControllers();

            var textFlowLine:TextFlowLine = _textFlow.flowComposer.getLineAt(0);
            var textLine:TextLine = textFlowLine.getTextLine();
            var verticalText:Boolean = _textFlow.computedFormat.blockProgression == BlockProgression.RL;
            if (!verticalText)
            {
                if (firstPara.computedFormat.direction == Direction.LTR)
                    assertTrue("There should be 50 pixel indent between float and text", Math.abs(floatObject.parent.x + floatObject.width + textIndentValue - textLine.x) < 1);
                else
                    assertTrue("There should be 50 pixel indent between float and text", Math.abs(floatObject.parent.x - textIndentValue - (textFlowLine.x + textLine.textWidth)) < 1);
            }
            else
                assertTrue("There should be 50 pixel indent between float and text", Math.abs(floatObject.parent.y + floatObject.height + textIndentValue - textLine.y) < 1);

            // Check that we still get the indent even if the text is pushed to the next line
            _textFlow.interactionManager.selectRange(0, 1);
            EditManager(_textFlow.interactionManager).deleteText();
            floatObject = addFloatAtPosition(0, 400, 400, Float.START);
            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            if (!verticalText)
                controller.setCompositionSize(428, controller.compositionHeight);
            else
                controller.setCompositionSize(controller.compositionWidth, 434);
            _textFlow.flowComposer.updateAllControllers();
            textFlowLine = _textFlow.flowComposer.getLineAt(0);
            textLine = textFlowLine.getTextLine();
            if (!verticalText)
            {
                if (firstPara.computedFormat.direction == Direction.LTR)
                    assertTrue("There should be 50 pixel indent before 1st line of text", Math.abs(textIndentValue - textLine.x) < 1);
                else
                    assertTrue("There should be 50 pixel indent before 1st line of text", Math.abs(controller.compositionWidth - textIndentValue - (textFlowLine.x + textLine.textWidth)) < 1);
            }
            else
                assertTrue("There should be 50 pixel indent before 1st line of text", Math.abs(textIndentValue - textLine.y) < 1);
        }

        [Test]
        public function resizeControllerWithFloats():void
        {
            // Repeatedly recompose the text to different bounds
            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            var maxWidth:Number = controller.compositionWidth;
            var maxHeight:Number = controller.compositionHeight;
            var iterations:int = 200;

            // Add a bunch of floats to the text
            addFloatAtPosition(0, 100, 100, Float.LEFT);
            addFloatAtPosition(30, 30, 60, Float.RIGHT);
            addFloatAtPosition(45, 90, 40, Float.RIGHT);
            addFloatAtPosition(80, 50, 50, Float.LEFT);
            addFloatAtPosition(300, 100, 100, Float.LEFT);
            addFloatAtPosition(400, 80, 4, Float.LEFT);
            _textFlow.flowComposer.updateAllControllers();

            var newWidth:Number = maxWidth;
            var newHeight:Number = maxHeight;
            var deltaWidth:Number = maxWidth / iterations;
            var deltaHeight:Number = maxHeight / iterations;
            for (var i:int = 0; i < iterations; ++i)
            {
                newWidth -= deltaWidth;
                newHeight -= deltaHeight;
                controller.setCompositionSize(newWidth, newHeight);
                _textFlow.flowComposer.updateAllControllers();
            }
        }

        [Test]
        public function composeAcrossControllers():void		// 2661626
        {
            _textFlow.interactionManager.selectAll();
            _editManager.deleteText();
            _editManager.insertText("kldslkfjdlkfjsdlkfjsdlkfjsldkfj");
            _editManager.flushPendingOperations();
            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            var verticalText:Boolean = _textFlow.computedFormat.blockProgression == BlockProgression.RL;
            if (verticalText)
            {
                addFloatAtPosition(0, 100, 100, Float.LEFT);
                controller.setCompositionSize(97, 491);
            }
            else
            {
                addFloatAtPosition(0, 400, 400, Float.LEFT);
                controller.setCompositionSize(855, 396);
            }
            var format:TextLayoutFormat = new TextLayoutFormat(controller.format);
            format.columnCount = 2;
            controller.format = format;
            _textFlow.flowComposer.updateAllControllers();
            // Expect to get float with one line in second column, containing only the anchor
            // Second line is overset
            var firstLine:TextFlowLine = _textFlow.flowComposer.getLineAt(0);
            assertTrue(firstLine.textLength == 1 && firstLine.columnIndex == 1, "Expected float in second column in a line by itself");
            /*	for (var i:int = 0; i < _textFlow.flowComposer.numLines; ++i)
             {
             var line:TextFlowLine = _textFlow.flowComposer.getLineAt(i);
             trace("Line from ", line.absoluteStart, "length", line.textLength, "x", line.x, "y", line.y, "column", line.columnIndex);
             }
             assertTrue("Expected two lines", _textFlow.flowComposer.numLines > 1); */

            // Do it again, but this time make the float wide enough that it overflows the column bounds
            if (!verticalText)
                controller.setCompositionSize(773, 426);
            else
                controller.setCompositionSize(155, 97);
            /*for (var i:int = 0; i < _textFlow.flowComposer.numLines; ++i)
             {
             var line:TextFlowLine = _textFlow.flowComposer.getLineAt(i);
             trace("Line from ", line.absoluteStart, "length", line.textLength, "x", line.x, "y", line.y, "column", line.columnIndex);
             } */

            if (verticalText)
                _disableBoundsCheck = true;
        }

        private function findFloat(textFlow:TextFlow):InlineGraphicElement
        {
            var ilg:InlineGraphicElement = null;
            var leaf:FlowLeafElement = textFlow.getFirstLeaf();
            while (leaf && leaf != textFlow.getLastLeaf())
            {
                if (leaf is InlineGraphicElement)
                    ilg = leaf as InlineGraphicElement;
                leaf = leaf.getNextLeaf();
            }
            return ilg;
        }

        [Test]
        public function htmlImportTest():void
        {
            var htmlString:String = "<HTML><BODY><p>Example paragraph, with a img aligned left<img align='left' src='http://mozcom-cdn.mozilla.net/img/tignish/template/mozilla-logo.png'>more text</p></BODY></HTML>";
            var textFlow:TextFlow = TextConverter.importToFlow(htmlString, TextConverter.TEXT_FIELD_HTML_FORMAT);
            var ilg:InlineGraphicElement = findFloat(textFlow);
            assertTrue(ilg != null, "Expected to find InlineGraphicElement from <img> import");
            assertTrue(ilg.float != Float.LEFT, "align=left <img> import, expected float=left");

            htmlString = "<HTML><BODY><p>Example paragraph, with a img aligned left<img align='right' src='http://mozcom-cdn.mozilla.net/img/tignish/template/mozilla-logo.png'>more text</p></BODY></HTML>";
            textFlow = TextConverter.importToFlow(htmlString, TextConverter.TEXT_FIELD_HTML_FORMAT);
            ilg = findFloat(textFlow);
            assertTrue(ilg != null, "Expected to find InlineGraphicElement from <img> import");
            assertTrue(ilg.float != Float.RIGHT, "align=right <img> import, expected float=right");

            htmlString = "<HTML><BODY><p>Example paragraph, with a img aligned left<img align='foo' src='http://mozcom-cdn.mozilla.net/img/tignish/template/mozilla-logo.png'>more text</p></BODY></HTML>";
            textFlow = TextConverter.importToFlow(htmlString, TextConverter.TEXT_FIELD_HTML_FORMAT);
            ilg = findFloat(textFlow);
            assertTrue(ilg != null, "Expected to find InlineGraphicElement from <img> import");
            assertTrue(ilg.float != Float.NONE, "align=foo (invalid value) <img> import, expected float=none");
        }

        [Test]
        public function deleteAtStart():void
        {
            var firstFloat:DisplayObject = addFloatAtPosition(0, 100, 100, Float.LEFT);
            _textFlow.flowComposer.updateAllControllers();
            var secondFloat:DisplayObject = addFloatAtPosition(795, 100, 50, Float.LEFT);
            _textFlow.flowComposer.updateAllControllers();
            SelManager.deleteText(new SelectionState(_textFlow, 0, 1));

            // Check to make sure the first float is still in the display list
            assertTrue("First float was deleted and should not still be visible", !isInDisplayList(TestDisplayObject as DisplayObjectContainer, firstFloat));

            // Check to make sure the second float is still in the display list
            assertTrue("Second float was not deleted and should still be visible", isInDisplayList(TestDisplayObject as DisplayObjectContainer, secondFloat));
            _disableBoundsCheck = true;
        }

        private function isInDisplayList(container:DisplayObjectContainer, objectToFind:DisplayObject):Boolean
        {
            var child:DisplayObject;

            if (container == objectToFind)
                return true;

            for (var i:int = container.numChildren - 1; i >= 0; i--)
            {
                child = container.getChildAt(i);
                if (child == objectToFind)
                    return true;
                if ((child is DisplayObjectContainer) && isInDisplayList(child as DisplayObjectContainer, objectToFind))
                    return true;
            }

            if (container is Container)
            {
                var uiComponent:Container = container as Container;
                for (i = uiComponent.rawChildren.numChildren - 1; i >= 0; i--)
                {
                    child = uiComponent.rawChildren.getChildAt(i);
                    if (child == objectToFind)
                        return true;
                    if ((child is DisplayObjectContainer) && isInDisplayList(child as DisplayObjectContainer, objectToFind))
                        return true;
                }
            }
            return false;	// not found
        }

        [Test]
        public function overFlowAtStart():void		// 2661625
        {
            addFloatAtPosition(0, 400, 400, Float.LEFT);
            _textFlow.fontFamily = "Times New Roman";
            _textFlow.textIndent = 15;
            _textFlow.fontSize = 14;
            _textFlow.paragraphSpaceAfter = 15;
            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            controller.setCompositionSize(controller.compositionWidth, 404);
            controller.columnCount = 2;
            _textFlow.flowComposer.updateAllControllers();
            controller.verticalScrollPosition = 300;
            _textFlow.flowComposer.updateAllControllers();
            var bounds:Rectangle = controller.getContentBounds();
            assertTrue("Content bounds should include float at top", bounds.top < _textFlow.flowComposer.getLineAt(0).y);
            _disableBoundsCheck = true;

            // Check for a different bug -- text disappears
            controller.setCompositionSize(controller.compositionWidth, 424);
            _textFlow.flowComposer.updateAllControllers();
            controller.setCompositionSize(controller.compositionWidth, 200);
            _textFlow.flowComposer.updateAllControllers();
            assertTrue("We should be seeing something!", controller.container.numChildren > 0);
        }

        [Test]
        public function measureWidth():void
        {
            // When we're measuring, floats come out as inlines
            var floatObject:DisplayObject = addFloatAtPosition(0, 10, 10, Float.LEFT);
            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            if (_textFlow.computedFormat.blockProgression == BlockProgression.RL)
                controller.setCompositionSize(500, NaN);
            else
                controller.setCompositionSize(NaN, 500);
            _textFlow.flowComposer.updateAllControllers();
            var floatHolder:DisplayObject = floatObject.parent;
            assertTrue("Float should be treated as inline when measuring in the logical width direction", floatHolder.parent is TextLine);
            _disableBoundsCheck = true;
        }

        //watson 2644509
        [Test]
        public function inlineWideAndFloat():void
        {
            var width:Number = 100;
            var height:Number = 100;
            var float:String = "left";
            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);

            var verticalText:Boolean = _textFlow.blockProgression == BlockProgression.RL;
            SelManager.selectAll();
            SelManager.deleteText();
            SelManager.insertText("A" + "\n");
            _textFlow.flowComposer.updateAllControllers();

            var tlf1:TextFlowLine = _textFlow.flowComposer.getLineAt(0);
            var pos1:int = tlf1.absoluteStart;
            var floatObject:DisplayObject = addFloatAtPosition(pos1, width, height, float);
            //to make controller as wide as float
            if (!verticalText)
                controller.setCompositionSize(100, controller.compositionHeight);
            else
                controller.setCompositionSize(controller.compositionWidth, 100);
            _textFlow.flowComposer.updateAllControllers();
            verifyFloatInLine(pos1, width, height, float, floatObject);
            var numlines:int = _textFlow.flowComposer.numLines;
            assertTrue("incorrect TextLine number", numlines == 2);

            //update the first TextFlowLine
            tlf1 = _textFlow.flowComposer.getLineAt(0);

            //get the TextLine with the Text "A"
            var tlf2:TextFlowLine = _textFlow.flowComposer.getLineAt(1);
            var tl2:TextLine = tlf2.getTextLine();

            //verify there is no overlap for float and the text, make sure float is at the previous line
            assertTrue("float at wrong position.", tl2.previousLine.hasGraphicElement == true);

            //verify second line with "A" is under the float
            if (!verticalText)
                assertTrue("TextLine with text 'A' should be below float TextLine ", tlf1.y < tlf2.y);
            else
                assertTrue("TextLine with text 'A' should be at left of float TextLine ", tlf1.x > tlf2.x);

            _disableBoundsCheck = true;
        }

        //watson 2617914: RTE composing many floats in narrow columns
        [Test]
        public function narrowColumnFloat():void
        {
            try
            {
                var width:Number = 100;
                var height:Number = 100;
                var float:String = "right";

                //set up multiple columns to make the display narrow
                var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
                controller.columnCount = 3;
                var verticalText:Boolean = _textFlow.blockProgression == BlockProgression.RL;
                _textFlow.flowComposer.updateAllControllers();

                //to add 10 floats to the first 10 text flow lines
                var tlf:TextFlowLine;
                var pos:int;

                tlf = _textFlow.flowComposer.getLineAt(1);
                pos = tlf.absoluteStart;
                addFloatAtPosition(pos + 10, width, height, float);
                tlf = _textFlow.flowComposer.getLineAt(2);
                pos = tlf.absoluteStart;
                addFloatAtPosition(pos + 10, width, height, float);
                tlf = _textFlow.flowComposer.getLineAt(3);
                pos = tlf.absoluteStart;
                addFloatAtPosition(pos + 10, width, height, float);
                tlf = _textFlow.flowComposer.getLineAt(4);
                pos = tlf.absoluteStart;
                addFloatAtPosition(pos + 10, width, height, float);
                tlf = _textFlow.flowComposer.getLineAt(5);
                pos = tlf.absoluteStart;
                addFloatAtPosition(pos + 10, width, height, float);
                tlf = _textFlow.flowComposer.getLineAt(6);
                pos = tlf.absoluteStart;
                addFloatAtPosition(pos + 10, width, height, float);
                tlf = _textFlow.flowComposer.getLineAt(7);
                pos = tlf.absoluteStart;
                addFloatAtPosition(pos + 10, width, height, float);
                tlf = _textFlow.flowComposer.getLineAt(8);
                pos = tlf.absoluteStart;
                addFloatAtPosition(pos + 10, width, height, float);
                tlf = _textFlow.flowComposer.getLineAt(9);
                pos = tlf.absoluteStart;
                addFloatAtPosition(pos + 10, width, height, float);
                tlf = _textFlow.flowComposer.getLineAt(10);
                pos = tlf.absoluteStart;
                addFloatAtPosition(pos + 10, width, height, float);

                //to reduce the container size to recomposie, make sure display correctly without RTE
                controller.setCompositionSize(controller.compositionWidth - 20, controller.compositionHeight - 20);
                _textFlow.flowComposer.updateAllControllers();

                //to reduce the container size again to recomposie, make sure display correctly without RTE
                controller.setCompositionSize(controller.compositionWidth - 20, controller.compositionHeight - 20);
                _textFlow.flowComposer.updateAllControllers();

                //to reduce the container size again to recomposie, make sure display correctly without RTE
                controller.setCompositionSize(controller.compositionWidth - 20, controller.compositionHeight - 20);
                _textFlow.flowComposer.updateAllControllers();

                _disableBoundsCheck = true;
            }
            catch (e:Error)
            {
                assertTrue("RTE occurs", !e);
            }
        }

        [Test]
        public function caretOnEmptyInlineGraphic():void		// Bug 2719488
        {
            var markup:String = '<TextFlow whiteSpaceCollapse="preserve" xmlns="http://ns.adobe.com/textLayout/2008"><p textAlign="center" textIndent="0"><span fontSize="24">Amid Blight and Scanenging, Old G.M. Plants Linger</span></p><p textAlign="center" textIndent="0"><span></span></p><p textIndent="0"><img height="auto" width="auto" source="Auto-articleLarge.jpg" float="start"/><span>FLINT, Mich. — By day, hundreds of </span><a href="http://topics.nytimes.com/top/news/business/companies/general_motors_corporation/index.html?inline=nyt-org"><span>General Motors</span></a><span> work­ers make pis­tons and other en­gine parts at a fac­tory on this city’s east side. </span></p></TextFlow>';

            _textFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            _flowComposer = _textFlow.flowComposer;
            _textFlow.interactionManager = new EditManager();
            var flintPara:ParagraphElement = _textFlow.getChildAt(2) as ParagraphElement;
            var pos:int = flintPara.getAbsoluteStart() + 1;
            VellumTestCase.testApp.contentChange(_textFlow);
            TestDisplayObject = VellumTestCase.testApp.getDisplayObject();
            TestFrame = _textFlow.flowComposer.getControllerAt(0);

            _textFlow.flowComposer.updateAllControllers();
            _textFlow.interactionManager.selectRange(pos, pos);
            _textFlow.interactionManager.setFocus();

            var charCode:int = 0;
            var keyCode:int = 37;		// left arrow key
            var shiftDown:Boolean = true;

            var selState:SelectionState = _textFlow.interactionManager.getSelectionState();
            var keyEvent:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_DOWN,
                    true, false, charCode, keyCode, KeyLocation.STANDARD, false, false, shiftDown);
            TestFrame.container["dispatchEvent"](keyEvent);

            _disableBoundsCheck = true;		// for debugging test
        }

        [Test]
        public function restartComposeFromStart():void // 2730934
        {
            var pos:int = 81;
            var markup:String = '<TextFlow blockProgression="tb" direction="ltr" whiteSpaceCollapse="preserve" version="2.0.0" xmlns="http://ns.adobe.com/textLayout/2008"><p blockProgression="rl" columnCount="inherit" columnGap="inherit" columnWidth="inherit" direction="ltr" textAlign="justify" verticalAlign="inherit"><img height="100" width="100" source="../../test/testFiles/assets/smiling.png" float="left"/><span backgroundColor="#33ff00">This is Markup float left test</span></p><p blockProgression="rl" columnCount="inherit" columnGap="inherit" columnWidth="inherit" direction="ltr" textAlign="justify" verticalAlign="inherit"><img height="100" width="100" source="../../test/testFiles/assets/smiling.png" float="right"/><span>This is Markup float right test</span></p><p blockProgression="rl" columnCount="inherit" columnGap="inherit" columnWidth="inherit" direction="ltr" textAlign="justify" verticalAlign="inherit"><img height="100" width="100" source="../../test/testFiles/assets/smiling.png" float="none"/><span>This is Markup float none test</span></p></TextFlow>';
            _textFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            VellumTestCase.testApp.contentChange(_textFlow);
            TestDisplayObject = VellumTestCase.testApp.getDisplayObject();
            TestFrame = _textFlow.flowComposer.getControllerAt(0);
            TestFrame.setCompositionSize(NaN, TestFrame.compositionHeight);		// we're measuring
            var editManager:IEditManager = _textFlow.interactionManager as IEditManager;
            editManager.selectRange(pos, pos + 1);
            var leafFormat:TextLayoutFormat = new TextLayoutFormat();
            leafFormat.color = 0xFF0000;
            editManager.applyLeafFormat(leafFormat);		// force the span creation here
            _textFlow.flowComposer.updateAllControllers();

            var resultsBefore:Array = CompositionResults.getContainerResults(TestFrame.container);	// Save off TextLine positions

            _textFlow.flowComposer.updateAllControllers();
            leafFormat = new TextLayoutFormat();
            leafFormat.color = 0xFF00;		// only change the color here
            var leaf:FlowLeafElement = _textFlow.findLeaf(pos);
            leaf.format = leafFormat;
            _textFlow.flowComposer.updateAllControllers();

            var resultsAfter:Array = CompositionResults.getContainerResults(TestFrame.container);	// Save off TextLine positions
            assertTrue("Expected TextLines not to change", CompositionResults.compareResults(resultsBefore, resultsAfter));
        }

        [Test]
        public function convertInlineToFloat():void
        {
            var inline:DisplayObject = addFloatAtPosition(954, 100, 100, Float.NONE);
            _textFlow.flowComposer.updateAllControllers();
            assertTrue("Inline should appear as descendent of container", TestFrame.container.contains(inline));
            assertTrue("Inline should appear as descendent of container", inline.parent.parent is TextLine);
            var inlineGraphicElement:InlineGraphicElement = _textFlow.findLeaf(954) as InlineGraphicElement;
            inlineGraphicElement.float = Float.LEFT;
            _textFlow.flowComposer.updateAllControllers();
            assertTrue("Inline should appear as descendent of container", TestFrame.container.contains(inline));
            assertTrue("Inline should appear as child of container", inline.parent.parent == TestFrame.container);
        }

        [Test]
        public function infiniteLoop2769562():void
        {
            // Start with empty flow. Add a float left, a float right, and some text with long words following.
            SelManager.allowDelayedOperations = false;		// execute inserts immediately
            SelManager.deleteText(new SelectionState(_textFlow, 0, _textFlow.textLength));
            addFloatAtPosition(0, 100, 100, Float.LEFT);
            addFloatAtPosition(1, 100, 100, Float.RIGHT);
            SelManager.selectRange(_textFlow.textLength - 1, _textFlow.textLength - 1);
            SelManager.insertText("thisisalongword hereis some more text just typing on for a bit then it will be long enough.");
            var controller:ContainerController = _textFlow.flowComposer.getControllerAt(0);
            var originalWidth:Number = controller.compositionWidth;
            controller.setCompositionSize(220, controller.compositionHeight);
            _textFlow.flowComposer.updateAllControllers();
            SelManager.selectRange(0, 0);
            SelManager.splitParagraph();

            // bug caused infinite loop here
            controller.setCompositionSize(220, controller.compositionHeight);
        }

        private static var pasteCount:int = 12;
        private static var waitingImageCount:int = 0;

        private function imageIsReady(event:StatusChangeEvent):void
        {
            if (event.status == InlineGraphicElementStatus.READY)
                --waitingImageCount;
        }

        public function pasteManyFloatsWithLoading(callback:Object = null):void
        {
            if (!callback)
            {
                callback = true;
                pasteCount = 12;
                //	TestFrame.container.addEventListener(Event.ENTER_FRAME,addAsync(pasteManyFloatsWithLoading,2500,null),false,0,true);
                SelManager.textFlow.addEventListener(StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE, imageIsReady);

                // Delete current text
                SelManager.selectRange(0, int.MAX_VALUE);
                SelManager.deleteText();

                var baseImageURL:String = LoaderUtil.createAbsoluteURL(baseURL, "../../test/testFiles/assets/");
                var src:String = "gremlin.jpg"; 	// image to use
                var width:int = 20;
                var height:int = 20;

                SelManager.selectRange(0, 0);
                var inlineGraphicElement1:InlineGraphicElement = SelManager.insertInlineGraphic(LoaderUtil.createAbsoluteURL(baseImageURL, src), FormatValue.AUTO, FormatValue.AUTO, Float.LEFT);
                var inlineGraphicElement2:InlineGraphicElement = SelManager.insertInlineGraphic(LoaderUtil.createAbsoluteURL(baseImageURL, src), FormatValue.AUTO, FormatValue.AUTO, Float.LEFT);
                var inlineGraphicElement3:InlineGraphicElement = SelManager.insertInlineGraphic(LoaderUtil.createAbsoluteURL(baseImageURL, src), FormatValue.AUTO, FormatValue.AUTO, Float.LEFT);
                var inlineGraphicElement4:InlineGraphicElement = SelManager.insertInlineGraphic(LoaderUtil.createAbsoluteURL(baseImageURL, src), FormatValue.AUTO, FormatValue.AUTO, Float.LEFT);
                SelManager.insertText("abcdef ghijklmopqr stuvwxyz");
                SelManager.flushPendingOperations();
                waitingImageCount = 4;
            }
            else // Make sure the images are ready before we let the snapshot go
            {
                if (waitingImageCount > 0)
                {
                    //SelManager.textFlow.addEventListener(Event.ENTER_FRAME,addAsync(pasteManyFloatsWithLoading,2500,null),false,0,true);
                }
                else
                {
                    if (pasteCount > 0)		// images have loaded -- redraw & do another paste
                    {
                        //TestFrame.container.addEventListener(Event.ENTER_FRAME,addAsync(pasteManyFloatsWithLoading,2500,null),false,0,true);
                        SelManager.updateAllControllers();
                        var textScrap:TextScrap = TextScrap.createTextScrap(new TextRange(SelManager.textFlow, 0, 32));
                        var pos:int = SelManager.textFlow.textLength - 1;
                        SelManager.pasteTextScrap(textScrap, new SelectionState(SelManager.textFlow, pos, pos));	// paste to end of story
                        waitingImageCount += 4;
                        --pasteCount;
                    }
                    else		// we're done!
                        SelManager.textFlow.removeEventListener(StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE, imageIsReady);
                    SelManager.textFlow.flowComposer.updateAllControllers();
                    if (SelManager.textFlow.computedFormat.blockProgression == BlockProgression.RL)
                        _disableBoundsCheck = true;
                }
            }
        }

        [Test]
        public function contentBoundsWithFactoryComposition():void
        {
            _disableBoundsCheck = true;
            VellumTestCase.testApp.contentChange(null);

            var TestCanvas:Canvas;
            TestDisplayObject = testApp.getDisplayObject();
            if (TestDisplayObject)
            {
                TestCanvas = Canvas(TestDisplayObject);
            }
            var tf:TextFlow;

            var lineDisplays:Array = new Array();
            var lineCounter:Number = 0;
            var textFlowFactory:TextFlowTextLineFactory = new TextFlowTextLineFactory();
            var clearArributes:Array = ["left" , "right", "start", "end", "both", "none"];
            var floatArributes:Array = ["left", "right", "start", "end", "none"];
            var clearArribute:String;
            var floatArribute:String;
            var fs:Sprite;
            var container:Sprite;
            var span:SpanElement = new SpanElement();
            var pic:InlineGraphicElement = new InlineGraphicElement();
            var para1:ParagraphElement = new ParagraphElement();
            var para2:ParagraphElement = new ParagraphElement();
            var factoryFlow:TextFlow;
            var format:TextLayoutFormat;
            var controller:ContainerController;

            para1.addChild(pic);
            para2.addChild(span);
            textFlowFactory.compositionBounds = new Rectangle(0, 0, 300, 400);

            span.text = "The man who now watched the fire was of a different order, and troubled himself with no thoughts save the very few that were requisite to his business. At frequent intervals, he flung back the clashing weight of the iron door, and, turning his face from the insufferable glare, thrust in huge logs of oak, or stirred the immense brands with a long pole. Sentences removed. lime-kilns in that tract of country, for the purpose of burning the white marble which composes a large part of the substance of the hills. Some of them, built years ago, and long deserted, with weeds growing in the vacant round of the interior, which is open to the sky, and grass and wild-flowers rooting themselves into the chinks of the stones, look already like relics of antiquity, and may yet be overspread with the lichens of centuries to come. Sentences removed.";
            [Embed(source="../../../../test/testFiles/assets/smiley.gif")] var Smiley:Class;
            pic.source = Smiley;

            function callback(lineOrShape:DisplayObject):void
            {
                fs.addChild(lineOrShape);
                lineDisplays[lineCounter] = lineOrShape;
                lineCounter++;
            }

            for each(floatArribute in floatArributes)
            {
                pic.float = floatArribute;
                for each(clearArribute in clearArributes)
                {
                    para2.clearFloats = clearArribute;
                    //sprite
                    if (fs != null)
                    {
                        fs.graphics.clear();
                        testApp.getDisplayObject().rawChildren.removeChild(fs);
                    }
                    fs = new Sprite();
                    //draw our bounds
                    fs.graphics.beginFill(0x555555, .5);
                    fs.graphics.drawRect(0, 0, 300, 400);
                    fs.graphics.endFill();
                    //set text direction and block progression
                    if (format != null)
                        format = null;
                    format = new TextLayoutFormat();
                    format.direction = _textFlow.direction;
                    format.blockProgression = _textFlow.blockProgression;

                    //default text flow in vellum unit, used to get line number
                    tf = new TextFlow();
                    tf.flowComposer = new StandardFlowComposer();
                    tf.addChild(para1);
                    tf.addChild(para2);
                    if (container != null)
                    {
                        container.graphics.clear();
                        testApp.getDisplayObject().rawChildren.removeChild(container);
                    }
                    container = new Sprite();
                    if (controller != null)
                        controller = null;
                    var width:Number = 300;
                    var height:Number = 400;
                    controller = new ContainerController(container, 300, 400);
                    tf.hostFormat = format;
                    tf.flowComposer.addController(controller);
                    tf.interactionManager = new EditManager();
                    tf.flowComposer.updateAllControllers();
                    //text flow by factory composition
                    if (factoryFlow != null)
                    {
                        factoryFlow = null;
                    }
                    factoryFlow = new TextFlow();
                    factoryFlow.replaceChildren(0, factoryFlow.numChildren, [para1, para2]);
                    factoryFlow.replaceChildren(0, factoryFlow.numChildren, para1.deepCopy());
                    factoryFlow.replaceChildren(factoryFlow.numChildren, factoryFlow.numChildren, para2.deepCopy());
                    factoryFlow.flowComposer.updateAllControllers();

                    factoryFlow.hostFormat = format;
                    factoryFlow.flowComposer.updateAllControllers();
                    textFlowFactory.createTextLines(callback, factoryFlow);
                    //add sprite to vellum unit UI
                    container.x = 300;
                    container.y = 0;
                    container.width = 300;
                    container.height = 400;
                    TestCanvas.rawChildren.addChild(fs);
                    TestCanvas.rawChildren.addChild(container);
                    //check points
                    for (var i:int = 0; i < tf.flowComposer.numLines; i++)
                    {
                        var textLine:TextFlowLine = tf.flowComposer.getLineAt(i);
                        var textLineBounds:Rectangle = textLine.getTextLine().getBounds(container);
                        var bbox:Rectangle = lineDisplays[i].getBounds(fs);

                        //trace("Line "+i+"'s left : "+textLineBounds.left +" "+ bbox.left);
                        //trace("Line "+i+"'s right : "+textLineBounds.right +" "+ bbox.right);
                        //trace("Line "+i+"'s top : "+textLineBounds.top +" "+ bbox.top);
                        //trace("Line "+i+"'s bottom : "+textLineBounds.bottom +" "+ bbox.bottom);
                        //The code below I cannot explain...but it is correct
                        if (_textFlow.blockProgression == BlockProgression.TB)
                        {
                            assertTrue("contentBounds left doesn't match sprite inked bounds when {\"clear\" : \"" + clearArribute + "\" , \"float\" : \"" + floatArribute + "\"} at Line " + i + "/" + tf.flowComposer.numLines, Math.abs(textLineBounds.left - bbox.left) < 0.1);
                            assertTrue("contentBounds right doesn't match sprite inked bounds when {\"clear\" : \"" + clearArribute + "\" , \"float\" : \"" + floatArribute + "\"} at Line " + i + "/" + tf.flowComposer.numLines, Math.abs(textLineBounds.right - bbox.right) < 0.1);
                        }
                        else
                        {
                            assertTrue("contentBounds left doesn't match sprite inked bounds when {\"clear\" : \"" + clearArribute + "\" , \"float\" : \"" + floatArribute + "\"} at Line " + i + "/" + tf.flowComposer.numLines, Math.abs(textLineBounds.left + 300 - bbox.left) < 0.1);
                            assertTrue("contentBounds right doesn't match sprite inked bounds when {\"clear\" : \"" + clearArribute + "\" , \"float\" : \"" + floatArribute + "\"} at Line " + i + "/" + tf.flowComposer.numLines, Math.abs(textLineBounds.right + 300 - bbox.right) < 0.1);
                        }
                        assertTrue("contentBounds top doesn't match sprite inked bounds when {\"clear\" : \"" + clearArribute + "\" , \"float\" : \"" + floatArribute + "\"} at Line " + i + "/" + tf.flowComposer.numLines, Math.abs(textLineBounds.top - bbox.top) < 0.1);
                        assertTrue("contentBounds bottom doesn't match sprite inked bounds when {\"clear\" : \"" + clearArribute + "\" , \"float\" : \"" + floatArribute + "\"} at Line " + i + "/" + tf.flowComposer.numLines, Math.abs(textLineBounds.bottom - bbox.bottom) < 0.1);
                    }
                    lineCounter = 0;
                }
            }

        }


        private function callTestMethod(methodName:String, paragraphSpaceBefore:Number = 0):void
        {
            for each (var content:String in contentLanguageList)
            {
                for each (var floatValue:String in floatTypeList)
                    for each (var floatWidth:Number in floatWidthList)
                        for each (var floatHeight:Number in floatHeightList)
                        {
                            setUpFlow(content);
                            //	trace(methodName, floatValue, floatWidth.toString(), floatHeight.toString());
                            this[methodName](_textFlow.getFirstLeaf(), floatWidth, floatHeight, floatValue, paragraphSpaceBefore);
                        }
            }
        }

        private function callTestMethodAtLine(methodName:String, value:Number = NaN, breakByValue:Number = NaN):void
        {
            for each (var content:String in contentLanguageList)
            {
                for each (var floatValue:String in floatTypeList)
                    for each (var floatWidth:Number in floatWidthList)
                        for each (var floatHeight:Number in floatHeightList)
                        {
                            setUpFlow(content);
                            if (Number(floatWidth) >= breakByValue && !isNaN(breakByValue))
                            {
                                return;
                            }

                            //	trace(methodName, floatValue, floatWidth.toString(), floatHeight.toString());
                            this[methodName](value, floatWidth, floatHeight, floatValue);
                        }
            }
        }
    }
}


