////////////////////////////////////////////////////////////////////////////////
//
//  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.
//
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
//
// This file contains content from Ethan Brand by Nathaniel Hawthorne,
// now in the public domain.
//
////////////////////////////////////////////////////////////////////////////////

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."
           
			// FIXME reed to be replaced
			_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
        {
			// FIXME replace image
            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");

			// FIXME replace image
            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");

			// FIXME replace image
            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
        {
			// FIXME content needs to be replaced
            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);
                        }
            }
        }
    }
}


