////////////////////////////////////////////////////////////////////////////////
//
//  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.TestConfigurationLoader;
    import UnitTest.ExtendedClasses.VellumTestCase;
    import UnitTest.Fixtures.TestCaseVo;
    import UnitTest.Fixtures.TestConfig;

    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import flash.events.*;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.system.*;
    import flash.text.engine.*;

    import flashx.textLayout.compose.IFlowComposer;
    import flashx.textLayout.compose.StandardFlowComposer;
    import flashx.textLayout.compose.TextFlowLine;
    import flashx.textLayout.container.ContainerController;
    import flashx.textLayout.container.TextContainerManager;
    import flashx.textLayout.conversion.TextConverter;
    import flashx.textLayout.edit.EditManager;
    import flashx.textLayout.edit.EditingMode;
    import flashx.textLayout.edit.IEditManager;
    import flashx.textLayout.edit.SelectionState;
    import flashx.textLayout.elements.*;
    import flashx.textLayout.formats.ITextLayoutFormat;
    import flashx.textLayout.formats.TextLayoutFormat;
    import flashx.textLayout.utils.NavigationUtil;

    import mx.containers.Canvas;

    import org.flexunit.asserts.assertTrue;
    import org.flexunit.asserts.fail;

    [TestCase(order=11)]
    [RunWith("org.flexunit.runners.Parameterized")]
    public class ContainerTypeTest extends VellumTestCase
    {
        [DataPoints(loader=clickLinkedContainerTestLoader)]
        [ArrayElementType("UnitTest.Fixtures.TestCaseVo")]
        public static var clickLinkedContainerTestDp:Array;

        public static var clickLinkedContainerTestLoader:TestConfigurationLoader = new TestConfigurationLoader("../../test/testCases/ContainerTypeTests.xml", "clickLinkedContainerTest");

        [DataPoints(loader=checkContainerAttributesAfterTextInsertionLoader)]
        [ArrayElementType("UnitTest.Fixtures.TestCaseVo")]
        public static var checkContainerAttributesAfterTextInsertionDp:Array;

        public static var checkContainerAttributesAfterTextInsertionLoader:TestConfigurationLoader = new TestConfigurationLoader("../../test/testCases/ContainerTypeTests.xml", "checkContainerAttributesAfterTextInsertion");

        [DataPoints(loader=navigateByLineTestLoader)]
        [ArrayElementType("UnitTest.Fixtures.TestCaseVo")]
        public static var navigateByLineTestDp:Array;

        public static var navigateByLineTestLoader:TestConfigurationLoader = new TestConfigurationLoader("../../test/testCases/ContainerTypeTests.xml", "navigateByLineTest");

        [DataPoints(loader=singleTextLineStaticLoader)]
        [ArrayElementType("UnitTest.Fixtures.TestCaseVo")]
        public static var singleTextLineStaticDp:Array;

        public static var singleTextLineStaticLoader:TestConfigurationLoader = new TestConfigurationLoader("../../test/testCases/ContainerTypeTests.xml", "singleTextLineStatic");

        [DataPoints(loader=clickMultiLinkedContainerTestLoader)]
        [ArrayElementType("UnitTest.Fixtures.TestCaseVo")]
        public static var clickMultiLinkedContainerTestDp:Array;

        public static var clickMultiLinkedContainerTestLoader:TestConfigurationLoader = new TestConfigurationLoader("../../test/testCases/ContainerTypeTests.xml", "clickMultiLinkedContainerTest");

        [DataPoints(loader=selectionChangeFocusTestLoader)]
        [ArrayElementType("UnitTest.Fixtures.TestCaseVo")]
        public static var selectionChangeFocusTestDp:Array;

        public static var selectionChangeFocusTestLoader:TestConfigurationLoader = new TestConfigurationLoader("../../test/testCases/ContainerTypeTests.xml", "SelectionChangeFocusTest");

        [DataPoints(loader=draggingSelectionOneFlowToAnotherTestLoader)]
        [ArrayElementType("UnitTest.Fixtures.TestCaseVo")]
        public static var draggingSelectionOneFlowToAnotherTestDp:Array;

        public static var draggingSelectionOneFlowToAnotherTestLoader:TestConfigurationLoader = new TestConfigurationLoader("../../test/testCases/ContainerTypeTests.xml", "draggingSelectionOneFlowToAnotherTest");

        [DataPoints(loader=containerRecomposeAndConsistenceTestLoader)]
        [ArrayElementType("UnitTest.Fixtures.TestCaseVo")]
        public static var containerRecomposeAndConsistenceTestDp:Array;

        public static var containerRecomposeAndConsistenceTestLoader:TestConfigurationLoader = new TestConfigurationLoader("../../test/testCases/ContainerTypeTests.xml", "containerRecomposeAndConsistenceTest");

        [DataPoints(loader=autoAndDragScrollingTestLoader)]
        [ArrayElementType("UnitTest.Fixtures.TestCaseVo")]
        public static var autoAndDragScrollingTestDp:Array;

        public static var autoAndDragScrollingTestLoader:TestConfigurationLoader = new TestConfigurationLoader("../../test/testCases/ContainerTypeTests.xml", "autoAndDragScrollingTest");

        private var TestCanvas:Canvas = null;
        private var ItemsToRemove:Array;
        private var hostFormat:TextLayoutFormat;

        private var markup:String;

        public function ContainerTypeTest()
        {
            super("", "ContainerTypeTest2", TestConfig.getInstance());
            //super(methodName, testID, testConfig, testCaseXML);
            //reset containerType and ID
            containerType = "custom";
            metaData = {};
            // Note: These must correspond to a Watson product area (case-sensitive)
            metaData.productArea = "Text Container";
            markup = getTestMarkup();
        }

        [Before]
        override public function setUpTest():void
        {
            super.setUpTest();
            cleanUpTestApp();
            ItemsToRemove = [];
            TestDisplayObject = testApp.getDisplayObject();
            if (TestDisplayObject)
            {
                TestCanvas = Canvas(TestDisplayObject);
            }
            else
            {
                fail("Did not get a blank canvas to work with");
            }
        }

        [After]
        override public function tearDownTest():void
        {
            super.tearDownTest();
        }

        /**
         * Have a single TextLine on the canvas instead of a vellum container
         */
        [Test]
        public function singleTextLine():void
        {
            var cf:ElementFormat = new ElementFormat();
            cf.fontSize = 24;
            var fd:FontDescription = new FontDescription("Times New Roman")
            cf.fontDescription = fd;
            var te:TextElement = new TextElement("A TextLine on the Canvas", cf);
            var tb:TextBlock = new TextBlock();
            tb.content = te;
            var tl1:TextLine = tb.createTextLine(null, 400);
            tl1.x = 50;
            tl1.y = 50;
            //need to keep track of what I've added in order to remove at teardown?
            TestCanvas.rawChildren.addChild(DisplayObject(tl1));
            ItemsToRemove.push(tl1);
            System.gc();
            System.gc();	//garbage collect at end so we can compare memory usage versus static lines
        }

        /**
         * Have ten TextLines on the canvas instead of a vellum container
         */
        [Test]
        public function tenTextLines():void
        {
            for (var i:int = 0; i < 10; i++)
            {
                var cf:ElementFormat = new ElementFormat();
                cf.fontSize = 24;
                var fd:FontDescription = new FontDescription("Times New Roman")
                cf.fontDescription = fd
                var te:TextElement = new TextElement("TextLine " + i, cf);
                var tb:TextBlock = new TextBlock();
                tb.content = te;
                var tl1:TextLine = tb.createTextLine(null, 400);
                tl1.x = 40;
                tl1.y = 40 + (40 * i);
                //need to keep track of what I've added in order to remove at teardown?
                TestCanvas.rawChildren.addChild(DisplayObject(tl1));
                ItemsToRemove.push(tl1);
            }
            System.gc();
            System.gc();	//garbage collect at end so we can compare memory usage versus static lines
        }

        /**
         * Have one hundred TextLines on the canvas instead of a vellum container
         */
        [Test]
        public function oneHundredTextLines():void
        {
            for (var i:int = 0; i < 100; i++)
            {
                var cf:ElementFormat = new ElementFormat();
                cf.fontSize = 2.4;
                var fd:FontDescription = new FontDescription("Times New Roman");
                cf.fontDescription = fd;
                var te:TextElement = new TextElement("TextLine " + i, cf);
                var tb:TextBlock = new TextBlock();
                tb.content = te;
                var tl1:TextLine = tb.createTextLine(null, 400);
                tl1.x = 40;
                tl1.y = 40 + (4 * i);
                //need to keep track of what I've added in order to remove at teardown?
                TestCanvas.rawChildren.addChild(DisplayObject(tl1));
                ItemsToRemove.push(tl1);
            }
            System.gc();
            System.gc();	//garbage collect at end so we can compare memory usage versus static lines
        }

        [Test(dataProvider=singleTextLineStaticDp)]
        public function singleTextLineStatic(testCaseVo:TestCaseVo):void
        {
            singleTextLine();
            TextLine(ItemsToRemove[0]).validity = TextLineValidity.STATIC;
            System.gc();
            System.gc();	//garbage collect at end so we can compare memory usage versus static lines
        }

        [Test]
        public function tenTextLinesStatic():void
        {
            tenTextLines();
            for (var i:int = 0; i < ItemsToRemove.length; i++)
            {
                TextLine(ItemsToRemove[i]).validity = TextLineValidity.STATIC;
            }
            System.gc();
            System.gc();	//garbage collect at end so we can compare memory usage versus static lines
        }

        [Test]
        public function oneHundredTextLinesStatic():void
        {
            oneHundredTextLines();
            for (var i:int = 0; i < ItemsToRemove.length; i++)
            {
                TextLine(ItemsToRemove[i]).validity = TextLineValidity.STATIC;
            }
            System.gc();
            System.gc();	//garbage collect at end so we can compare memory usage versus static lines
        }

        [Test(dataProvider=clickLinkedContainerTestDp)]
        public function clickLinkedContainerTest(testCaseVo:TestCaseVo):void
        {
            var posOfSelection:int = testCaseVo.posOfSelection;
            var format:TextLayoutFormat = new TextLayoutFormat();
            format.paddingLeft = 20;
            format.paddingRight = 20;
            format.paddingTop = 20;
            format.paddingBottom = 20;

            var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            textFlow.flowComposer = new StandardFlowComposer();
            var editManager:IEditManager = new EditManager();
            textFlow.interactionManager = editManager;

            format.firstBaselineOffset = "auto";
            editManager.applyContainerFormat(format);
            editManager.applyFormatToElement(editManager.textFlow, format);
            editManager.selectRange(0, 0);

            //create two containers
            var container1:Sprite = new Sprite();
            var container2:Sprite = new Sprite();
            var controllerOne:ContainerController = new ContainerController(container1, 200, 250);
            var controllerTwo:ContainerController = new ContainerController(container2, 150, 300);

            TestCanvas.rawChildren.addChild(container1);
            TestCanvas.rawChildren.addChild(container2);
            container1.x = 25;
            container1.y = 50;
            container2.x = 280;
            container2.y = 50;

            // add the controllers to the text flow and update them to display the text
            textFlow.flowComposer.addController(controllerOne);
            textFlow.flowComposer.addController(controllerTwo);
            textFlow.flowComposer.updateAllControllers();

            var tfl:TextFlowLine = textFlow.flowComposer.findLineAtPosition(posOfSelection);
            var adjustedPosOfSelection:int = posOfSelection - tfl.absoluteStart;
            var tl:TextLine = tfl.getTextLine();
            var bounds:Rectangle = tl.getAtomBounds(adjustedPosOfSelection);

            var mouseX:Number = 0;
            var mouseY:Number = 0;

            if (testCaseVo.id == "clickLeftToLinkedContainer")
            {
                mouseX = bounds.x - 1;
                mouseY = tl.y;
            }
            else if (testCaseVo.id == "clickRightToLinkedContainer")
            {
                mouseX = bounds.x + 1;
                mouseY = tl.y;
            }
            else if (testCaseVo.id == "clickTopLinkedContainer")
            {
                mouseX = bounds.x;
                mouseY = tl.y - 1;
            }
            else if (testCaseVo.id == "clickBottomLinkedContainer")
            {
                mouseX = bounds.x;
                mouseY = tl.y + 1;
            }

            editManager.setFocus();
            var mEvent:MouseEvent;
            mEvent = new MouseEvent(MouseEvent.MOUSE_DOWN, true, false, mouseX, mouseY);
            container1.dispatchEvent(mEvent);
            editManager.setFocus();

            editManager.flushPendingOperations();
            var posAfterClick:int = editManager.activePosition;

            assertTrue("Position changed after click." + " Position of selected is: " + posOfSelection
                    + " Position of after Click: " + posAfterClick,
                    posOfSelection == posAfterClick);

        }

        /**
         * linked containers,  check if attribute changed after texts insertion
         */
        [Test(dataProvider=checkContainerAttributesAfterTextInsertionDp)]
        public function checkContainerAttributesAfterTextInsertion(testCaseVo:TestCaseVo):void
        {
            var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            textFlow.flowComposer = new StandardFlowComposer();
            var editManager:IEditManager = new EditManager();
            textFlow.interactionManager = editManager;

            //create two linked containers containers
            var container1:Sprite = new Sprite();
            var container2:Sprite = new Sprite();
            var controllerOne:ContainerController = new ContainerController(container1, 200, 250);
            var controllerTwo:ContainerController = new ContainerController(container2, 150, 300);

            TestCanvas.rawChildren.addChild(container1);
            TestCanvas.rawChildren.addChild(container2);
            container1.x = 25;
            container1.y = 50;
            container2.x = 280;
            container2.y = 50;

            // add the controllers to the text flow and update them to display the text
            textFlow.flowComposer.addController(controllerOne);
            textFlow.flowComposer.addController(controllerTwo);
            textFlow.flowComposer.updateAllControllers();

            editManager.selectRange(0, 0);
            editManager.setFocus();

            var format:TextLayoutFormat = new TextLayoutFormat();
            format.paddingLeft = 20;
            format.paddingRight = 20;
            format.paddingTop = 20;
            format.paddingBottom = 20;

            format.firstBaselineOffset = "auto";
            editManager.applyContainerFormat(format);
            editManager.applyFormatToElement(editManager.textFlow, format);
            textFlow.flowComposer.updateAllControllers();

            //get container attributes before insertion
            var containerAtts_before:ITextLayoutFormat = controllerOne.format;
            var paddingLeft_before:Number = containerAtts_before.paddingLeft;
            var paddingRight_before:Number = containerAtts_before.paddingRight;
            var paddingTop_before:Number = containerAtts_before.paddingTop;
            var paddingBottom_before:Number = containerAtts_before.paddingBottom;

            var firstContStart:int = controllerOne.absoluteStart;
            var firstContLen:int = controllerOne.textLength;
            var firstContEnd:int = firstContStart + firstContLen;

            //get the insertion position
            if (testCaseVo.id == "insertionEndOf1stContainer")
            {
                editManager.selectRange(firstContEnd - 1, firstContEnd - 1);
            }
            else if (testCaseVo.id == "insertionBeginOf2ndContainer")
            {
                editManager.selectRange(firstContEnd, firstContEnd);
            }
            editManager.insertText("BBB");
            textFlow.flowComposer.updateAllControllers();

            //check attributes after insertion
            var containerAtts_after:ITextLayoutFormat = controllerOne.format;
            var paddingLeft_after:Number = containerAtts_after.paddingLeft;
            var paddingRight_after:Number = containerAtts_after.paddingRight;
            var paddingTop_after:Number = containerAtts_after.paddingTop;
            var paddingBottom_after:Number = containerAtts_after.paddingBottom;

            //check if attributes changed after insertion
            assertTrue("Attributes have been changed after insertion to end of 1st container.",
                    paddingLeft_before === paddingLeft_after &&
                            paddingRight_before === paddingRight_after &&
                            paddingTop_before === paddingTop_after &&
                            paddingBottom_before === paddingBottom_after);
        }

        private var firstFlow:TextFlow;
        private var secondFlow:TextFlow;
        private var firstController:ContainerController;
        private var secondController:ContainerController;

        private function resizeHandler(event:Event):void
        {
            const verticalGap:Number = 25;
            const stagePadding:Number = 16;
            var stageWidth:Number = TestCanvas.width - stagePadding;
            var stageHeight:Number = TestCanvas.height - stagePadding;
            var firstContaierWidth:Number = stageWidth;
            var firstContaierHeight:Number = stageHeight;
            // Initial compose to get height of headline after resize
            firstController.setCompositionSize(firstContaierWidth, firstContaierHeight);
            firstFlow.flowComposer.compose();
            var rect:Rectangle = firstController.getContentBounds();
            firstContaierHeight = rect.height;
            // Resize and place headline text container
            // Call setCompositionSize() again with updated headline height
            firstController.setCompositionSize(firstContaierWidth, firstContaierHeight);
            firstController.container.x = stagePadding / 2;
            firstController.container.y = stagePadding / 2;
            firstFlow.flowComposer.updateAllControllers();
            // Resize and place second text container
            var secondContainerHeight:Number = (stageHeight - verticalGap -
                    firstContaierHeight);
            secondController.setCompositionSize(stageWidth, secondContainerHeight);
            secondController.container.x = (stagePadding / 2);
            secondController.container.y = (stagePadding / 2) + firstContaierHeight +
                    verticalGap;
            secondFlow.flowComposer.updateAllControllers();
        }

        [Test(dataProvider=selectionChangeFocusTestDp)]
        public function SelectionChangeFocusTest(testCaseVo:TestCaseVo):void
        {

            const firstMarkup:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008'>" +
                    "<flow:p>" + "<flow:span fontSize='14'>first text flow: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</flow:span>" +
                    "</flow:p>" +
                    "</flow:TextFlow>";
            const secondMarkup:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' fontSize='14'> " +
                    "<flow:p>" +
                    "<flow:span>second text flow: " +
                    "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.</flow:span>" +
                    "</flow:p>" +
                    "</flow:TextFlow>";
            var posOfSelection1:int = testCaseVo.posOfSelection1;
            var posOfSelection2:int = testCaseVo.posOfSelection2;

            TestCanvas.addEventListener(Event.RESIZE, resizeHandler);

            //create first text flow, import first text, and assign composer
            firstFlow = new TextFlow();
            firstFlow = TextConverter.importToFlow(firstMarkup, TextConverter.TEXT_LAYOUT_FORMAT);
            firstFlow.flowComposer = new StandardFlowComposer();
            //create second text flow, import second text, and assign flow composer
            secondFlow = new TextFlow();
            secondFlow = TextConverter.importToFlow(secondMarkup, TextConverter.TEXT_LAYOUT_FORMAT);
            secondFlow.flowComposer = new StandardFlowComposer();
            // create first container, add controller, position container and add to stage
            var firstContainer:Sprite = new Sprite();
            firstController = new ContainerController(firstContainer, 300, 50);
            var editManager1:IEditManager = new EditManager();
            firstFlow.interactionManager = editManager1;
            firstFlow.flowComposer.addController(firstController);
            firstContainer.x = 120;
            firstContainer.y = 20;
            TestCanvas.rawChildren.addChild(firstContainer);
            firstFlow.flowComposer.updateAllControllers();

            // create container for second text and position it
            var secondContainer:Sprite = new Sprite();
            secondController = new ContainerController(secondContainer, 300, 200);
            secondContainer.x = 125;
            secondContainer.y = 185;
            var editManager2:IEditManager = new EditManager();
            secondFlow.interactionManager = editManager2;
            // add controller, add container to stage, and display second text
            secondFlow.flowComposer.addController(secondController);
            TestCanvas.rawChildren.addChild(secondContainer);
            secondFlow.flowComposer.updateAllControllers();

            //get focus for first flow
            editManager1.selectRange(posOfSelection1, posOfSelection1);
            editManager1.flushPendingOperations();
            editManager1.setFocus();

            assertTrue("Selection Focus doesn't change after selection change from Text Flow 1 to Text Flow 2. ",
                    posOfSelection1 == editManager1.activePosition);

            //get focus for second flow
            editManager2.selectRange(posOfSelection2, posOfSelection2);
            editManager2.flushPendingOperations();
            editManager2.setFocus();

            assertTrue("Selection Focus doesn't change properly after selection change from Text Flow 1 to Text Flow 2. "
                    + ". The expected focus poisiton should be in second text flow at: " + posOfSelection2
                    + " and the actual text flow focus poisiton is: " + editManager2.activePosition,
                    posOfSelection2 == editManager2.activePosition);
        }

        [Test(dataProvider=clickMultiLinkedContainerTestDp)]
        public function clickMultiLinkedContainerTest(testCaseVo:TestCaseVo):void
        {
            var posOfSelection:int = testCaseVo.posOfSelection;
            var format:TextLayoutFormat = new TextLayoutFormat();
            format.paddingLeft = 20;
            format.paddingRight = 20;
            format.paddingTop = 20;
            format.paddingBottom = 20;
            var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            textFlow.flowComposer = new StandardFlowComposer();
            var editManager:IEditManager = new EditManager();
            textFlow.interactionManager = editManager;
            format.firstBaselineOffset = "auto";
            editManager.applyContainerFormat(format);
            editManager.applyFormatToElement(editManager.textFlow, format);
            editManager.selectRange(0, 0);

            //create five containers
            var container1:Sprite = new Sprite();
            var container2:Sprite = new Sprite();
            var container3:Sprite = new Sprite();
            var container4:Sprite = new Sprite();
            var container5:Sprite = new Sprite();
            var controller1:ContainerController = new ContainerController(container1, 200, 200);
            var controller2:ContainerController = new ContainerController(container2, 200, 200);
            var controller3:ContainerController = new ContainerController(container3, 200, 200);
            var controller4:ContainerController = new ContainerController(container4, 200, 200);
            var controller5:ContainerController = new ContainerController(container5, 200, 200);
            TestCanvas.rawChildren.addChild(container1);
            TestCanvas.rawChildren.addChild(container2);
            TestCanvas.rawChildren.addChild(container3);
            TestCanvas.rawChildren.addChild(container4);
            TestCanvas.rawChildren.addChild(container5);
            container1.x = 25;
            container1.y = 50;
            container2.x = 280;
            container2.y = 50;
            container3.x = 535;
            container3.y = 50;
            container4.x = 790;
            container4.y = 50;
            container5.x = 1045;
            container5.y = 50;
            // add the controllers to the text flow and update them to display the text
            textFlow.flowComposer.addController(controller1);
            textFlow.flowComposer.addController(controller2);
            textFlow.flowComposer.addController(controller3);
            textFlow.flowComposer.addController(controller4);
            textFlow.flowComposer.addController(controller5);
            textFlow.flowComposer.updateAllControllers();
            var tfl:TextFlowLine = textFlow.flowComposer.findLineAtPosition(posOfSelection);
            var adjustedPosOfSelection:int = posOfSelection - tfl.absoluteStart;
            var tl:TextLine = tfl.getTextLine();
            var bounds:Rectangle = tl.getAtomBounds(adjustedPosOfSelection);
            var mouseX:Number = 0;
            var mouseY:Number = 0;
            if (testCaseVo.id == "clickLeftToMultiLinkedContainer")
            {
                mouseX = bounds.x - 1;
                mouseY = tl.y;
            }
            else if (testCaseVo.id == "clickRightToMultiLinkedContainer")
            {
                mouseX = bounds.x + 1;
                mouseY = tl.y;
            }
            else if (testCaseVo.id == "clickTopMultiLinkedContainer")
            {
                mouseX = bounds.x;
                mouseY = tl.y - 1;
            }
            else if (testCaseVo.id == "clickBottomMultiLinkedContainer")
            {
                mouseX = bounds.x;
                mouseY = tl.y + 1;
            }
            editManager.setFocus();
            var mEvent:MouseEvent;
            mEvent = new MouseEvent(MouseEvent.MOUSE_DOWN, true, false, mouseX, mouseY);
            container1.dispatchEvent(mEvent);
            editManager.setFocus();
            editManager.flushPendingOperations();
            var posAfterClick:int = editManager.activePosition;
            assertTrue("Position changed after click." + " Position of selected is: " + posOfSelection
                    + " Position of after Click: " + posAfterClick,
                    posOfSelection == posAfterClick);

        }

        /*****************************************************************
         Drag selection using mouse events and verify the selected range.
         ******************************************************************/
            //two text flows, two containers
        [Test]
        [Ignore]
        public function draggingSelectioinMultiFlows():void
        {
            //create the first text flow, import texts from markups, and assign flow composer to a container
            var flow_1:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            flow_1.flowComposer = new StandardFlowComposer();
            var container_1:Sprite = new Sprite();
            var controller_1:ContainerController = new ContainerController(container_1, 300, 250);
            container_1.x = 25;
            container_1.y = 25;

            //Create EditManager to manage edting changes in TextFlow
            var eManager_1:IEditManager = new EditManager();
            flow_1.interactionManager = eManager_1;
            eManager_1.selectRange(0, 0);

            //add controllers to the first text flow and update all controller to display texts
            flow_1.flowComposer.addController(controller_1);
            TestCanvas.rawChildren.addChild(container_1);
            flow_1.flowComposer.updateAllControllers();

            //set points for the selection beginning and end
            var startFlowLine:TextFlowLine = flow_1.flowComposer.getLineAt(2);
            var startLine:TextLine = startFlowLine.getTextLine();
            var endFlowLine:TextFlowLine = flow_1.flowComposer.getLineAt(10);
            var endLine:TextLine = endFlowLine.getTextLine();
            var endRect:Rectangle = endLine.getAtomBounds(54);
            var startPoint:Point = new Point(startLine.x, startLine.y);
            var endPoint:Point = new Point(endRect.x, endLine.y);
            var x_point:Number;
            var y_point:Number;

            x_point = startPoint.x;
            y_point = startPoint.y;

            //selection start point in the first text flow
            eManager_1.setFocus();
            var downPoint:MouseEvent = new MouseEvent(MouseEvent.MOUSE_DOWN, true, false, x_point, y_point, container_1);
            container_1.dispatchEvent(downPoint);

            var startInt:int = startFlowLine.absoluteStart;
            var activeInt:int = eManager_1.activePosition;
            var charCount:int = endLine.atomCount;
            var endLineStart:int = endFlowLine.absoluteStart;
            var endInt:int = (endLineStart + charCount) - 1;

            if (startInt == activeInt)
            {
                x_point = endPoint.x;
                y_point = endPoint.y;

                //dragging selection
                eManager_1.setFocus();
                var movePoint:MouseEvent =
                        new MouseEvent(MouseEvent.MOUSE_MOVE, true, false, x_point, y_point, container_1, false, false, false, true);
                container_1.dispatchEvent(movePoint);

                //dragging is done
                var upPoint:MouseEvent =
                        new MouseEvent(MouseEvent.MOUSE_UP, true, false, x_point, y_point, container_1);
                container_1.dispatchEvent(upPoint);
            }

            else
            {
                fail("Mouse down event in the first text flow didn't happen!");
            }

            //create the second text flow, import texts from markups, and assign flow composer to a container
            var flow_2:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            flow_2.flowComposer = new StandardFlowComposer();

            //Create EditManager to manage edting changes in TextFlow
            var eManager_2:IEditManager = new EditManager();
            flow_2.interactionManager = eManager_2;
            eManager_2.selectRange(0, 0);

            var container_2:Sprite = new Sprite();
            var controller_2:ContainerController = new ContainerController(container_2, 300, 250);
            container_2.x = 350;
            container_2.y = 25;

            //add controllers to the second text flow and update all controller to display texts
            flow_2.flowComposer.addController(controller_2);
            TestCanvas.rawChildren.addChild(container_2);
            flow_2.flowComposer.updateAllControllers();

            //set points for the selection beginning and end
            var startFlowLine2:TextFlowLine = flow_2.flowComposer.getLineAt(5);
            var startLine2:TextLine = startFlowLine.getTextLine();
            var endFlowLine2:TextFlowLine = flow_2.flowComposer.getLineAt(13);
            var endLine2:TextLine = endFlowLine2.getTextLine();
            var endRect2:Rectangle = endLine2.getAtomBounds(54);

            var startPoint2:Point = new Point(startLine2.x, startLine2.y);
            var endPoint2:Point = new Point(endRect2.x, endLine2.y);

            var x_point2:Number;
            var y_point2:Number;

            x_point2 = startPoint2.x;
            y_point2 = startPoint2.y;

            //selection start point in the sencond text flow
            eManager_2.setFocus();
            var downPoint2:MouseEvent = new MouseEvent(MouseEvent.MOUSE_DOWN, true, false, x_point2, y_point2, container_2);
            container_2.dispatchEvent(downPoint2);

            x_point2 = endPoint2.x;
            y_point2 = endPoint2.y;

            //dragging selection
            eManager_2.setFocus();
            var movePoint2:MouseEvent =
                    new MouseEvent(MouseEvent.MOUSE_MOVE, true, false, x_point2, y_point2, container_2, false, false, false, true);
            container_2.dispatchEvent(movePoint2);

            //dragging is done
            var upPoint2:MouseEvent =
                    new MouseEvent(MouseEvent.MOUSE_UP, true, false, x_point2, y_point2, container_2);
            container_2.dispatchEvent(upPoint2);

            var charCount2:int = endLine2.atomCount;
            var startInt2:int = startFlowLine2.absoluteStart;
            var endLineStart2:int = endFlowLine2.absoluteStart;
            var endInt2:int = (endLineStart2 + charCount2) - 1;

            var start:int = 101;
            var end:int = 573;
            assertTrue("Selection range for the first text flow should have been from ".concat(start, " to ", end, " but it was from ",
                    startInt, " to ", endInt, startInt == start && endInt == end));

            var start2:int = 252;
            var end2:int = 733;
            assertTrue("Selection range for the second text flow should have been from ".concat(start2, " to ", end2,
                    " but it was from ", startInt2, " to ", endInt2, startInt2 == start2 && endInt2 == end2));
        }

        /**
         * two text flows, two containers, select from one flow to another
         */
        [Test(dataProvider=draggingSelectionOneFlowToAnotherTestDp)]
        public function draggingSelectionOneFlowToAnotherTest(testCaseVo:TestCaseVo):void
        {

            const firstMarkup:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008'>" +
                    "<flow:p>" + "<flow:span fontSize='14'>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</flow:span>" +
                    "</flow:p>" +
                    "</flow:TextFlow>";
            const secondMarkup:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' fontSize='14'> " +
                    "<flow:p>" +
                    "<flow:span>second text flow: " +
                    "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.</flow:span>" +
                    "</flow:p>" +
                    "</flow:TextFlow>";
            var posOfSelection1:int = testCaseVo.posOfSelection1;
            var posOfSelection2:int = testCaseVo.posOfSelection2;

            //create first text flow, import first text, and assign composer
            firstFlow = new TextFlow();
            firstFlow = TextConverter.importToFlow(firstMarkup, TextConverter.TEXT_LAYOUT_FORMAT);
            firstFlow.flowComposer = new StandardFlowComposer();
            //create second text flow, import second text, and assign flow composer
            secondFlow = new TextFlow();
            secondFlow = TextConverter.importToFlow(secondMarkup, TextConverter.TEXT_LAYOUT_FORMAT);
            secondFlow.flowComposer = new StandardFlowComposer();
            // create first container, add controller, position container
            var firstContainer:Sprite = new Sprite();
            firstController = new ContainerController(firstContainer, 300, 50);
            var editManager1:IEditManager = new EditManager();
            firstFlow.interactionManager = editManager1;
            firstFlow.flowComposer.addController(firstController);
            firstContainer.x = 120;
            firstContainer.y = 20;
            TestCanvas.rawChildren.addChild(firstContainer);
            firstFlow.flowComposer.updateAllControllers();

            // create container for second text and position it
            var secondContainer:Sprite = new Sprite();
            secondController = new ContainerController(secondContainer, 300, 200);
            secondContainer.x = 125;
            secondContainer.y = 185;
            var editManager2:IEditManager = new EditManager();
            secondFlow.interactionManager = editManager2;
            // add controller, add container to stage, and display second text
            secondFlow.flowComposer.addController(secondController);
            TestCanvas.rawChildren.addChild(secondContainer);
            secondFlow.flowComposer.updateAllControllers();

            // make selection in first flow and second flow
            editManager1.selectRange(0, 0);
            var tfl1:TextFlowLine = firstFlow.flowComposer.findLineAtPosition(posOfSelection1);
            var adjustedPosOfSelection1:int = posOfSelection1 - tfl1.absoluteStart;
            var tl1:TextLine = tfl1.getTextLine();
            var bounds1:Rectangle = tl1.getAtomBounds(adjustedPosOfSelection1);
            var tfl2:TextFlowLine = secondFlow.flowComposer.findLineAtPosition(posOfSelection2);
            var adjustedPosOfSelection2:int = posOfSelection2 - tfl2.absoluteStart;
            var tl2:TextLine = tfl2.getTextLine();
            var bounds2:Rectangle = tl2.getAtomBounds(adjustedPosOfSelection2);

            var mouseX:Number = bounds1.x;
            var mouseY:Number = tl1.y;

            // mouse down in first container
            editManager1.setFocus();
            var mEventD1:MouseEvent = new MouseEvent(MouseEvent.MOUSE_DOWN, true, false, mouseX, mouseY, firstContainer);
            firstContainer.dispatchEvent(mEventD1);

            // mouse move to second container and mouse up
            mouseX = bounds2.x;
            mouseY = tl2.y;
            editManager2.selectRange(0, 0);
            editManager2.setFocus();
            var mEventM1:MouseEvent = new MouseEvent(MouseEvent.MOUSE_MOVE, true, false, mouseX, mouseY, secondContainer, false, false, false, true);
            secondContainer.dispatchEvent(mEventM1);
            var mEventU1:MouseEvent = new MouseEvent(MouseEvent.MOUSE_UP, true, false, mouseX, mouseY, secondContainer);
            secondContainer.dispatchEvent(mEventU1);

            var activePos:Number = editManager2.activePosition;
            assertTrue("Selection should not extend to second container. ",
                    activePos == 0);

        }

        [Test]
        public function addRemoveMulitiLinkedContainerTest():void
        {
            var format:TextLayoutFormat = new TextLayoutFormat();
            format.paddingLeft = 20;
            format.paddingRight = 20;
            format.paddingTop = 20;
            format.paddingBottom = 20;
            var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            textFlow.flowComposer = new StandardFlowComposer();
            var editManager:IEditManager = new EditManager();
            textFlow.interactionManager = editManager;
            format.firstBaselineOffset = "auto";
            editManager.applyContainerFormat(format);
            editManager.applyFormatToElement(editManager.textFlow, format);
            editManager.selectRange(0, 0);

            //create five containers and hid two
            var container1:Sprite = new Sprite();
            var container2:Sprite = new Sprite();
            var container3:Sprite = new Sprite();
            var container4:Sprite = new Sprite();
            var container5:Sprite = new Sprite();
            var controller1:ContainerController = new ContainerController(container1, 100, 100);
            var controller2:ContainerController = new ContainerController(container2, 200, 200);
            var controller3:ContainerController = new ContainerController(container3, 300, 300);
            var controller4:ContainerController = new ContainerController(container4, 400, 400);
            var controller5:ContainerController = new ContainerController(container5, 500, 500);
            TestCanvas.rawChildren.addChild(container1);
            TestCanvas.rawChildren.addChild(container2);
            TestCanvas.rawChildren.addChild(container3);
            TestCanvas.rawChildren.addChild(container4);
            TestCanvas.rawChildren.addChild(container5);
            container1.x = 25;
            container1.y = 50;
            container2.x = 280;
            container2.y = 50;
            container3.x = 535;
            container3.y = 50;
            container4.x = 790;
            container4.y = 50;
            container5.x = 1045;
            container5.y = 50;
            container4.visible = false;
            container5.visible = false;

            // add the controllers to the text flow and update them to display the text
            textFlow.flowComposer.addController(controller1);
            textFlow.flowComposer.addController(controller2);
            textFlow.flowComposer.addController(controller3);
            textFlow.flowComposer.addController(controller4);
            textFlow.flowComposer.addController(controller5);
            textFlow.flowComposer.updateAllControllers();

            //removeController
            textFlow.flowComposer.removeController(controller5);
            textFlow.flowComposer.updateAllControllers();
            var containerNumAfterRemove:int = textFlow.flowComposer.numControllers;
            assertTrue("Container has not been removed correctly ", containerNumAfterRemove == 4);

            //removeControllerAt
            textFlow.flowComposer.removeControllerAt(2);
            textFlow.flowComposer.updateAllControllers();
            containerNumAfterRemove = textFlow.flowComposer.numControllers;
            assertTrue("Container has not been removed correctly ", containerNumAfterRemove == 3);

            var c1:ContainerController = textFlow.flowComposer.getControllerAt(0);
            var c2:ContainerController = textFlow.flowComposer.getControllerAt(1);
            var c3:ContainerController = textFlow.flowComposer.getControllerAt(2);
            var w1:int = c1.compositionWidth;
            var w2:int = c2.compositionWidth;
            var w3:int = c3.compositionWidth;
            //check if removed correct containers
            assertTrue("Wrong container has been removed ", w1 == 100 && w2 == 200 && w3 == 400);

            //addController
            textFlow.flowComposer.addController(controller5);
            textFlow.flowComposer.updateAllControllers();
            var containerNumAfterAdd:int = textFlow.flowComposer.numControllers;
            assertTrue("Container has not been added correctly ", containerNumAfterAdd == 4);
            //check if correct container added
            var c4:ContainerController = textFlow.flowComposer.getControllerAt(3);
            var w4:int = c4.compositionWidth;
            assertTrue("Wrong container has been removed ", w4 == 500);

            //addControllerAt
            textFlow.flowComposer.addControllerAt(controller3, 3);
            textFlow.flowComposer.updateAllControllers();
            containerNumAfterAdd = textFlow.flowComposer.numControllers;
            assertTrue("Container has not been added correctly ", containerNumAfterAdd == 5);
            //check if correct container added at correct position
            var c5:ContainerController = textFlow.flowComposer.getControllerAt(3);
            var w5:int = c5.compositionWidth;
            assertTrue("Container has not been added at corrent position ", w5 == 300);
            c4 = textFlow.flowComposer.getControllerAt(4);
            w4 = c4.compositionWidth;
            assertTrue("Container has not been added at corrent position ", w4 == 500);
        }

        [Test(dataProvider=containerRecomposeAndConsistenceTestDp)]
        public function containerRecomposeAndConsistenceTest(testCaseVo:TestCaseVo):void
        {
            var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            textFlow.flowComposer = new StandardFlowComposer();
            var editManager:IEditManager = new EditManager();
            textFlow.interactionManager = editManager;
            editManager.selectRange(0, 0);

            //create five containers and hid two
            var container1:Sprite = new Sprite();
            var container2:Sprite = new Sprite();
            var container3:Sprite = new Sprite();
            var container4:Sprite = new Sprite();
            var container5:Sprite = new Sprite();
            var controller1:ContainerController = new ContainerController(container1, 200, 200);
            var controller2:ContainerController = new ContainerController(container2, 200, 200);
            var controller3:ContainerController = new ContainerController(container3, 200, 200);
            var controller4:ContainerController = new ContainerController(container4, 200, 200);
            var controller5:ContainerController = new ContainerController(container5, 200, 200);
            TestCanvas.rawChildren.addChild(container1);
            TestCanvas.rawChildren.addChild(container2);
            TestCanvas.rawChildren.addChild(container3);
            TestCanvas.rawChildren.addChild(container4);
            TestCanvas.rawChildren.addChild(container5);
            container1.x = 25;
            container1.y = 50;
            container2.x = 280;
            container2.y = 50;
            container3.x = 535;
            container3.y = 50;
            container4.x = 790;
            container4.y = 50;
            container5.x = 1045;
            container5.y = 50;
            container4.visible = false;
            container5.visible = false;

            // add the controllers to the text flow and update them to display the text
            textFlow.flowComposer.addController(controller1);
            textFlow.flowComposer.addController(controller2);
            textFlow.flowComposer.addController(controller3);
            textFlow.flowComposer.addController(controller4);
            textFlow.flowComposer.addController(controller5);
            textFlow.flowComposer.updateAllControllers();

            if (testCaseVo.id == "recomposeContainerTest") //to test if container will be re-composed correctly after some container update
            {
                //recompose controller3
                controller3.setCompositionSize(250, 250);

                var comp0:Boolean = textFlow.flowComposer.composeToController(0);
                var comp1:Boolean = textFlow.flowComposer.composeToController(1);   // shoud be true since last line before first damaged  line will be re-composed
                var comp2:Boolean = textFlow.flowComposer.composeToController(2);	// should be true - controller3
                var comp3:Boolean = textFlow.flowComposer.composeToController(3);	// should be true
                var comp4:Boolean = textFlow.flowComposer.composeToController(4);	// true due to overflow bydesign
                textFlow.flowComposer.updateAllControllers();

                assertTrue("composeToController returns wrong flag after re-composite.",
                        comp0 == false && comp1 == true && comp2 == true && comp3 == true && comp4 == true);
            }
            else if (testCaseVo.id == "containerConsistenceTest")
            {
                var posOfSelection:int = testCaseVo.posOfSelection;
                var tfl:TextFlowLine = textFlow.flowComposer.findLineAtPosition(posOfSelection);
                var tfl_abs:Number = tfl.absoluteStart;
                var tfl_textLen:Number = tfl.textLength;
                var controller:ContainerController = tfl.controller;

                var index:int = textFlow.flowComposer.getControllerIndex(controller);
                var con_abs:Number = controller.absoluteStart;
                var con_textLen:Number = controller.textLength;
                var idx:Number = textFlow.flowComposer.findControllerIndexAtPosition(posOfSelection);

                assertTrue("abs start and text length are not consistent for textFlowLines in the container and the container",
                        con_abs <= tfl_abs <= con_textLen && tfl_textLen <= con_textLen && index == idx);
            }
        }

        private function findFirstAndLastVisibleLine(flowComposer:IFlowComposer, controller:ContainerController):Array
        {
            var firstLine:int = flowComposer.findLineIndexAtPosition(controller.absoluteStart);
            var lastLine:int = flowComposer.findLineIndexAtPosition(controller.absoluteStart + controller.textLength - 1);
            var lastColumn:int = 0;
            var firstVisibleLine:int = -1;
            var lastVisibleLine:int = -1;
            for (var lineIndex:int = firstLine; lineIndex <= lastLine; lineIndex++)
            {
                var curLine:TextFlowLine = flowComposer.getLineAt(lineIndex);
                if (curLine.controller != controller)
                    continue;

                // skip until we find the lines in the last column
                if (curLine.columnIndex != lastColumn)
                    continue;

                if (curLine.textLineExists && curLine.getTextLine().parent)
                {
                    if (firstVisibleLine < 0)
                        firstVisibleLine = lineIndex;

                    lastVisibleLine = lineIndex;
                }
            }

            return [firstVisibleLine, lastVisibleLine];
        }

        [Test(dataProvider=autoAndDragScrollingTestDp)]
        public function autoAndDragScrollingTest(testCaseVo:TestCaseVo):void
        {

            var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            textFlow.flowComposer = new StandardFlowComposer();
            var editManager:IEditManager = new EditManager();
            textFlow.interactionManager = editManager;
            editManager.selectRange(0, 0);

            //create three containers
            var container1:Sprite = new Sprite();
            var container2:Sprite = new Sprite();
            var container3:Sprite = new Sprite();
            var controller1:ContainerController = new ContainerController(container1, 200, 200);
            var controller2:ContainerController = new ContainerController(container2, 200, 200);
            var controller3:ContainerController = new ContainerController(container3, 200, 200);

            TestCanvas.rawChildren.addChild(container1);
            TestCanvas.rawChildren.addChild(container2);
            TestCanvas.rawChildren.addChild(container3);

            container1.x = 25;
            container1.y = 50;
            container2.x = 280;
            container2.y = 50;
            container3.x = 535;
            container3.y = 50;

            // add the controllers to the text flow and update them to display the text
            textFlow.flowComposer.addController(controller1);
            textFlow.flowComposer.addController(controller2);
            textFlow.flowComposer.addController(controller3);
            textFlow.flowComposer.updateAllControllers();

            //check first and last visible line in container1 before scrolling
            var beforePosition1:Array = findFirstAndLastVisibleLine(textFlow.flowComposer, controller1);
            var beforeFirstVisibleLine1:int = beforePosition1[0];
            var beforeLastVisibleLine1:int = beforePosition1[1];

            var position1:int = controller1.textLength - 1;
            //try to scroll to end of the container
            controller1.scrollToRange(position1, position1);
            textFlow.flowComposer.updateAllControllers();

            // verify that the first and last visible lines no change after scroll
            var afterPosition1:Array = findFirstAndLastVisibleLine(textFlow.flowComposer, controller1);
            var afterFirstVisibleLine1:int = afterPosition1[0];
            var afterLastVisibleLine1:int = afterPosition1[1];
            assertTrue("the container is scrollable.  Expected not scrollable.",
                    beforeFirstVisibleLine1 == afterFirstVisibleLine1 &&
                            beforeLastVisibleLine1 == afterLastVisibleLine1);

            //check first and last visible line in last container container3 before scrolling
            var beforePosition3:Array = findFirstAndLastVisibleLine(textFlow.flowComposer, controller3);
            var beforeFirstVisibleLine3:int = beforePosition3[0];
            var beforeLastVisibleLine3:int = beforePosition3[1];

            var position3:int = textFlow.textLength - 1;
            if (testCaseVo.id == "dragScrollingTest")
            {
                editManager.selectRange(position3 - 20, position3);
                editManager.setFocus();

            }
            controller3.scrollToRange(position3 - 20, position3);
            textFlow.flowComposer.updateAllControllers();

            // verify that the first and last visible lines changed after scroll
            var afterPosition3:Array = findFirstAndLastVisibleLine(textFlow.flowComposer, controller3);
            var afterFirstVisibleLine3:int = afterPosition3[0];
            var afterLastVisibleLine3:int = afterPosition3[1];
            assertTrue("the last container is not scrollable.  Expected scrollable.",
                    beforeFirstVisibleLine3 < afterFirstVisibleLine3 &&
                            beforeLastVisibleLine3 < afterLastVisibleLine3);

        }

        [Test(dataProvider=navigateByLineTestDp)]
        public function navigateByLineTest(testCaseVo:TestCaseVo):void
        {
            var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            textFlow.flowComposer = new StandardFlowComposer();
            var editManager:IEditManager = new EditManager();
            textFlow.interactionManager = editManager;
            editManager.selectRange(0, 0);

            //create three containers
            var container1:Sprite = new Sprite();
            var container2:Sprite = new Sprite();
            var container3:Sprite = new Sprite();
            var controller1:ContainerController = new ContainerController(container1, 200, 200);
            var controller2:ContainerController = new ContainerController(container2, 200, 200);
            var controller3:ContainerController = new ContainerController(container3, 200, 200);

            TestCanvas.rawChildren.addChild(container1);
            TestCanvas.rawChildren.addChild(container2);
            TestCanvas.rawChildren.addChild(container3);

            container1.x = 25;
            container1.y = 50;
            container2.x = 280;
            container2.y = 50;
            container3.x = 535;
            container3.y = 50;

            // add the controllers to the text flow and update them to display the text
            textFlow.flowComposer.addController(controller1);
            textFlow.flowComposer.addController(controller2);
            textFlow.flowComposer.addController(controller3);
            textFlow.flowComposer.updateAllControllers();

            //try to use previousLine to get to first container and nextLine to get to third container
            var posSecondControllerBegin:int = controller2.absoluteStart;
            var posSecondControllerEnd:int = posSecondControllerBegin + controller2.textLength;
            if (testCaseVo.id == "navigateByPreviousLine")
            {
                //to get the selection range at beginning of second container then previousLine should go to the first container
                editManager.selectRange(posSecondControllerBegin, posSecondControllerBegin + 10);
            }
            else if (testCaseVo.id == "navigateByNextLine")
            {
                //to get the selection range at end of second container then nextLine should go to the third container
                editManager.selectRange(posSecondControllerEnd - 10, posSecondControllerEnd);
            }
            var selRange:SelectionState = editManager.getSelectionState();
            if (testCaseVo.id == "navigateByPreviousLine")
            {
                NavigationUtil.previousLine(selRange, true);
            }
            else if (testCaseVo.id == "navigateByNextLine")
            {
                NavigationUtil.nextLine(selRange, true);
            }

            //composes all the text up-to date.
            textFlow.flowComposer.updateAllControllers();
            var positionAfter:int = selRange.activePosition;
            var curControllerIdx:int = textFlow.flowComposer.findControllerIndexAtPosition(positionAfter);

            if (TestData.id == "navigateByPreviousLine")
            {
                assertTrue("The previousLine didn't get to correct container.", curControllerIdx == 0);
            }
            else if (TestData.id == "navigateByNextLine")
            {
                assertTrue("The previousLine didn't get to correct container.", curControllerIdx == 2);
            }
        }

        [Test]
        public function defaultContextMenuOnTest():void
        {
            var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            textFlow.flowComposer = new StandardFlowComposer();
            var editManager:IEditManager = new EditManager();
            textFlow.interactionManager = editManager;
            editManager.selectRange(0, 0);

            //create a container
            var container:Sprite = new Sprite();
            var controller:ContainerController = new ContainerController(container, 200, 200);
            TestCanvas.rawChildren.addChild(container);

            // add the controller to the text flow and update it to display the text and setFocus to attach contextMenu
            textFlow.flowComposer.addController(controller);
            editManager.setFocus();
            textFlow.flowComposer.updateAllControllers();
            assertTrue("The default Context Menu should be on when editMode=readWrite.", container.contextMenu != null);
        }

        /**
         * Check if the contectMenu is off when editMode=readOnly
         */
        [Test]
        public function contextMenuOffTest():void
        {
            var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
            textFlow.flowComposer = new StandardFlowComposer();
            var editManager:IEditManager = new EditManager();
            textFlow.interactionManager = editManager;
            editManager.selectRange(0, 0);

            //create a container
            var container:Sprite = new Sprite();
            var controller:ContainerController = new ContainerController(container, 200, 200);
            TestCanvas.rawChildren.addChild(container);
            textFlow.flowComposer.addController(controller);
            editManager.setFocus(); //attach default contextMenu
            textFlow.flowComposer.updateAllControllers();
            textFlow.interactionManager = null;	//make editMode=readOnly to disable contextMenu
            assertTrue("The default Context Menu should be off when editMode=readOnly.", container.contextMenu == null);
        }

        [Test]
        public function overrideContextMenuTestNull():void
        {
            var s:Sprite = createInputManagerNull(hostFormat);
            s.dispatchEvent(new FocusEvent(FocusEvent.FOCUS_IN));
            TestCanvas.rawChildren.addChild(s);
            assertTrue("It should be no contextMenu with the override fuction.", s.contextMenu == null);
        }

        static private function createInputManagerNull(hostFormat:ITextLayoutFormat):Sprite
        {
            var s:Sprite = new Sprite();
            var tcm:CustomTextContainerManagerNull = new CustomTextContainerManagerNull(s);
            tcm.compositionWidth = 250;
            tcm.compositionHeight = 100;
            tcm.setText("Hello World");
            tcm.hostFormat = hostFormat;
            tcm.updateContainer();
            return s;
        }

        [Test]
        public function overrideContextMenuTestAll():void
        {
            var s:Sprite = createInputManagerAll(hostFormat);
            s.dispatchEvent(new FocusEvent(FocusEvent.FOCUS_IN));
            TestCanvas.rawChildren.addChild(s);
            assertTrue("The contextMenu should be all true.", s.contextMenu.customItems[0].caption == "PageUp"
                    && s.contextMenu.customItems[1].caption == "PageDown")
        }

        static private function createInputManagerAll(hostFormat:ITextLayoutFormat):Sprite
        {
            var s:Sprite = new Sprite();
            var tcm:CustomTextContainerManagerAll = new CustomTextContainerManagerAll(s);
            tcm.compositionWidth = 250;
            tcm.compositionHeight = 100;
            tcm.setText("Hello World");
            tcm.hostFormat = hostFormat;
            tcm.updateContainer();
            return s;
        }

        /**
         * to test bug 2500307: TCM shouldn't have contextMenu when read-only
         */
        [Test]
        public function contextMenuReadOnly():void
        {
            var s:Sprite = new Sprite();
            s.x = 0;
            s.y = 0;
            TestCanvas.rawChildren.addChild(s);
            var tcm:TextContainerManager = new TextContainerManager(s);
            tcm.compositionWidth = 250;
            tcm.compositionHeight = NaN;
            tcm.setText("Hello World, there should not be a context menu becasue field is read-only");
            var format:TextLayoutFormat = new TextLayoutFormat(TextLayoutFormat.defaultFormat);
            format.fontFamily = "Arial";
            format.fontSize = 14;
            tcm.hostFormat = format;
            tcm.editingMode = EditingMode.READ_ONLY;
            tcm.updateContainer();
            assertTrue("The default Context Menu should be off when editMode=readOnly.", tcm.container.contextMenu == null);
        }

        /**
         * to test bug 2504032: TCM contextMenu when using the factory and READ_SELECT should not enable the edit clipboard items such as cut and paste
         */
        [Test]
        public function contextMenuReadSelect():void
        {
            var s:Sprite = new Sprite();
            s.x = 0;
            s.y = 0;
            var tcm:TextContainerManager = new TextContainerManager(s);
            tcm.compositionWidth = 250;
            tcm.compositionHeight = NaN;
            tcm.setText("Hello World, TCM contextMenu when using the factory and READ_SELECT should not enable the edit clipboard items such as cut and paste");
            var format:TextLayoutFormat = new TextLayoutFormat(TextLayoutFormat.defaultFormat);
            format.fontFamily = "Arial";
            format.fontSize = 14;
            tcm.hostFormat = format;
            tcm.updateContainer();

            //to make textMenu and clipboardMenu enabled
            s.dispatchEvent(new FocusEvent(FocusEvent.FOCUS_IN));
            TestCanvas.rawChildren.addChild(s);
            assertTrue("The edit clipboard items such as cut and paste were disabled when TCM contextMenu NOT using READ_SELECT", tcm.container.contextMenu.clipboardMenu == true);

            //to make textMenu and clipboardMenu disabled
            tcm.editingMode = EditingMode.READ_SELECT;
            tcm.updateContainer();
            assertTrue("The edit clipboard items such as cut and paste were enabled when TCM contextMenu using READ_SELECT", tcm.container.contextMenu == null);
        }

        private function getTestMarkup():String
        {
           return  "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' fontSize='14' " +
                   "textIndent='0' paragraphSpaceBefore='6' paddingTop='4' paddingBottom='4'>" +
                   "<flow:p paragraphSpaceAfter='15' >" +
                   "<flow:span>There are many </flow:span>" +
                   "<flow:span fontStyle='italic'>such</flow:span>" +
                   "<flow:span> 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.</flow:span>" +
                   "</flow:p>" +
                   "<flow:p paragraphSpaceAfter='15'>" +
                   "<flow:span>" +
                   "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 halffrightened 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.</flow:span>" +
                   "</flow:p>" +
                   "</flow:TextFlow>";
        }
    }
}

import flash.display.Sprite;
import flash.events.ContextMenuEvent;
import flash.events.KeyboardEvent;
import flash.ui.ContextMenu;
import flash.ui.ContextMenuItem;
import flash.ui.Keyboard;

import flashx.textLayout.container.TextContainerManager;
import flashx.textLayout.elements.IConfiguration;
import flashx.textLayout.tlf_internal;

use namespace tlf_internal;

class CustomTextContainerManagerNull extends TextContainerManager
{
    public function CustomTextContainerManagerNull(container:Sprite, configuration:IConfiguration = null)
    {
        super(container, configuration);
    }

    override protected function createContextMenu():ContextMenu
    {
        return null;
    }
}


class CustomTextContainerManagerAll extends TextContainerManager
{
    public function CustomTextContainerManagerAll(container:Sprite, configuration:IConfiguration = null)
    {
        super(container, configuration);
    }

    protected override function createContextMenu():ContextMenu
    {
        var menu:ContextMenu = super.createContextMenu();
        var item:ContextMenuItem;
        item = new ContextMenuItem("PageUp");
        menu.customItems.push(item);
        item.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, menuItemSelectHandler);
        item = new ContextMenuItem("PageDown");
        menu.customItems.push(item);
        item.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, menuItemSelectHandler);
        return menu;
    }

    private function menuItemSelectHandler(e:ContextMenuEvent):void
    {
        var key:KeyboardEvent;
        switch (e.currentTarget.caption)
        {
            case "PageUp":
                key = new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, true, 0, Keyboard.PAGE_UP);
                keyDownHandler(key);
                break;
            case "PageDown":
                key = new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, true, 0, Keyboard.PAGE_DOWN);
                keyDownHandler(key);
                break;
        }
    }


}
/******************************************************************************
 Truncation options test for truncation of text composed using TextlineFactory
 This is temporary till creating indepndent test file for truncation options.
 Most of functions are modification from ConpositionTest.as
 ******************************************************************************/
/****
 var lines:Array;
 var textLength:int;
 var bounds:Rectangle;
 var contentTextLength:int = textLength;
 var line0:TextLine = lines[0] as TextLine;
 var line0Extent:Number = TextLineFactory.defaultConfiguration.overflowPolicy == OverflowPolicy.FIT_ANY ? line0.y - line0.ascent : line0.y + line0.descent;
 var line0TextLen:int = line0.rawTextLength;
 var line1:TextLine = lines[1] as TextLine;
 var line1Extent:Number = TextLineFactory.defaultConfiguration.overflowPolicy == OverflowPolicy.FIT_ANY ? line1.y - line1.ascent : line1.y + line1.descent;
 var contentHeight:Number = bounds.height;
 var line:TextLine;
 var lineExtent:Number;
 var testTruncationIndicator:String
 var testFactory:TextLineFactory = new TextLineFactory();
 var originalContentPrefix:String;

 var singleLineText:String = "A single text line for truncation options test.";

 var rtlText:String =
 'مدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسة'+
 'مدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسة'+
 'مدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسة'+
 'مدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسةمدرسة';

 var accentedText:String =
 '\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A' +
 '\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A' +
 '\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A' +
 '\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A' +
 '\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A\u0041\u030A';


 //function to display the text object
 private function Callback(t1:TextLine):void
 {
     textLength += t1.rawTextLength ;
     lines.push(t1);
 }

 public function TruncationOptSingleLineCustom():void
 {
     var bounds:Rectangle = new Rectangle(40,40,100,NaN);
     testTruncationIndicator = "@@@"
 testFactory.text = singleLineText;
 var atMark:String = "@@@"
 var truncatedTxt:String = "A text line fo@@@";
 var truncationIndicatorLength:int;

 testFactory.textLinesFromString(Callback,bounds,new TruncationOptions(testTruncationIndicator,1));
 truncationIndicatorLength = truncatedTxt.lastIndexOf(testTruncationIndicator);
 assertTrue("Truncation indicator, was not @@@!", testTruncationIndicator == atMark);
 assertTrue("Truncation indicator didn't appear at the end of sentence!", truncatedTxt.length == truncationIndicatorLength+testTruncationIndicator.length);
 }

 public function TruncationOptSingleLineDefault():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = NaN; testFactory.text = singleLineText;
     bounds.left = 0; bounds.top = 0;
     testFactory.textLinesFromString(Callback, bounds, new TruncationOptions(null, 2));
     truncationIndicatorIndex = testFactory.truncatedText.lastIndexOf(TruncationOptions.HORIZONTAL_ELLIPSIS);
     assertTrue("Default truncation indicator not present at the end of the truncated string",
     truncationIndicatorIndex+TruncationOptions.HORIZONTAL_ELLIPSIS.length == testFactory.truncatedText.length);
     originalContentPrefix = testFactory.truncatedText.slice(0, truncationIndicatorIndex);
     assertTrue("Original content before truncation indicator mangled", singleLineText.indexOf(originalContentPrefix) == 0);
 }


 public function UnspecifiedWidthTruncation():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = NaN;	bounds.height = NaN;
     bounds.left = 0; bounds.top = 0;
     TextLineFactory.createTextLinesFromString(Callback,singleLineText,bounds,null,null,null,new TruncationOptions(null, 0));
     assertTrue("Caused truncation despite unspecified width", textLength == contentTextLength);
 }

 public function ExplicitLineBreakingTruncation():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = NaN;
     bounds.left = 0; bounds.top = 0;
     var format:TextLayoutFormat = new TextLayoutFormat();
     format.lineBreak = LineBreak.EXPLICIT;
     TextLineFactory.createTextLinesFromString(Callback,singleLineText,bounds,null,null, format,new TruncationOptions(null, 0));
     assertTrue("Caused truncation despite explicit line breaks", textLength == contentTextLength);
 }

 public function ComposeHeightNoLine():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = line0Extent/2;
     bounds.left = 0; bounds.top = 0;
     TextLineFactory.createTextLinesFromString(Callback,singleLineText,bounds,null,null, null,new TruncationOptions());
     assertTrue("Composed one or more lines when compose height allows none", lines.length == 0);
 }

 public function ZeroLineCountLimit():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = contentHeight;
     bounds.left = 0; bounds.top = 0;
     TextLineFactory.createTextLinesFromString(Callback, singleLineText, bounds, null, null, null,new TruncationOptions(null, 0));
     assertTrue("Composed one or more lines when line count limit is 0", lines.length == 0);
 }

 public function UnfitTruncationIndicator():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = contentHeight -1;
     bounds.left = 0; bounds.top = 0;
     TextLineFactory.createTextLinesFromString(Callback,singleLineText,bounds,null, null, null,new TruncationOptions(singleLineText));
     assertTrue("Composed one or more lines when compose height does not allow truncation indicator itself to fit", lines.length == 0);
 }

 public function ComposingFitToBounds():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = NaN;
     bounds.left = 0; bounds.top = 0;
     TextLineFactory.createTextLinesFromString(Callback,singleLineText,bounds,null, null, null,new TruncationOptions(null, 2));
     assertTrue("Invalid truncation results when composing to fit in a line count limit", lines.length == 2);
 }

 public function CompostitngFitLineCountLimit():void
 {
     lines.splice(0); textLength = 0;
     bounds.left = 0; bounds.top = 0;
     TextLineFactory.createTextLinesFromString(Callback,singleLineText,bounds,null, null, null,new TruncationOptions(null, 2));
     assertTrue("Invalid truncation results when multiple truncation criteria provided",lines.length == 1);
     line = lines[0] as TextLine;
     lineExtent = TextLineFactory.defaultConfiguration.overflowPolicy == OverflowPolicy.FIT_ANY ? line.y - line.ascent : line.y + line.descent;
     assertTrue("Invalid truncation results when multiple truncation criteria provided", lineExtent <= line0Extent);
 }

 public function ComposingFitBoundsAndLineCountLimit():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = NaN;
     bounds.left = 0; bounds.top = 0;
     TextLineFactory.createTextLinesFromString(Callback,singleLineText,bounds,null, null, null,new TruncationOptions(null, 2));
     assertTrue("Invalid truncation results when composing to fit in a line count limit", lines.length == 2);
 }

 public function ComposingFitBoundsAndLineCountLimit_2():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = line1Extent;
     bounds.left = 0; bounds.top = 0;
     TextLineFactory.createTextLinesFromString(Callback,singleLineText,bounds,null, null, null,new TruncationOptions(null, 1));
     assertTrue("Invalid truncation results when multiple truncation criteria provided", lines.length == 1);
     line = lines[0] as TextLine;
     lineExtent = TextLineFactory.defaultConfiguration.overflowPolicy == OverflowPolicy.FIT_ANY ? line.y - line.ascent : line.y + line.descent;
     assertTrue("Invalid truncation results when multiple truncation criteria provided", lineExtent <= line1Extent);;
 }

 public function OriginalTextReplacement():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = NaN; testFactory.text = singleLineText;
     bounds.left = 0; bounds.top = 0;
     testTruncationIndicator = '\u200B';
     testFactory.textLinesFromString(Callback, bounds, new TruncationOptions(testTruncationIndicator, 1));
     assertTrue("Replacing more original content than is neccessary", testFactory.truncatedText.length == line0TextLen+customTruncationIndicator.length);
 }

 public function OriginalTextReplacementRTL():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = NaN; testFactory.text = rtlText;
     bounds.left = 0; bounds.top = 0;
     testTruncationIndicator = '\u200B';
     testFactory.textLinesFromString(Callback, bounds, new TruncationOptions(testTruncationIndicator, 1));
 }

 public function TruncationAtomsBoundaries():void
 {
     lines.splice(0); textLength = 0;
     bounds.width = 200; bounds.height = NaN; testFactory.text = accentedText;
     bounds.left = 0; bounds.top = 0;
     testTruncationIndicator = '<' + '\u200A' + '>'; // what precedes and succeeds the hair space is irrelevant
     testFactory.textLinesFromString(Callback, bounds, new TruncationOptions(testTruncationIndicator, 1));
     assertTrue("[Not a code bug] Fix test case so that truncation indicator itself fits", lines.length == 1); // baseline

     var initialTruncationPoint:int =  testFactory.truncatedText.length - testTruncationIndicator.length;
     assertTrue("[Not a code bug] Fix test case so that some of the original content is left behind on first truncation attempt", initialTruncationPoint > 0); // baseline
     assertTrue("Truncation in the middle of an atom!", initialTruncationPoint % 2 == 0);
     var nextTruncationPoint:int;
     do
     {
         bounds.height = NaN;
         // add another hair space in each iteration, making truncation indicator wider (ever so slightly)
         testTruncationIndicator = testTruncationIndicator.replace('\u200A', '\u200A\u200A');
         testFactory.textLinesFromString(Callback, bounds, new TruncationOptions(testTruncationIndicator, 1));

         nextTruncationPoint =  testFactory.truncatedText.length - testTruncationIndicator.length;
         if (nextTruncationPoint != initialTruncationPoint)
         {
             assertTrue("Truncation in the middle of an atom!", nextTruncationPoint % 2 == 0);
             assertTrue("Sub-optimal replacement of original content?", nextTruncationPoint == initialTruncationPoint-2);
             initialTruncationPoint = nextTruncationPoint;
         }

     } while (nextTruncationPoint);
 }
 ****/

