////////////////////////////////////////////////////////////////////////////////
//
//  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 flash.accessibility.AccessibilityImplementation;
    import flash.display.Sprite;
    import flash.events.IMEEvent;
    import flash.system.Capabilities;
    import flash.text.ime.IIMEClient;

    import flashx.textLayout.accessibility.TextAccImpl;
    import flashx.textLayout.compose.StandardFlowComposer;
    import flashx.textLayout.container.ContainerController;
    import flashx.textLayout.conversion.ConversionType;
    import flashx.textLayout.conversion.TextConverter;
    import flashx.textLayout.edit.EditManager;
    import flashx.textLayout.edit.SelectionManager;
    import flashx.textLayout.elements.Configuration;
    import flashx.textLayout.elements.GlobalSettings;
    import flashx.textLayout.elements.ParagraphElement;
    import flashx.textLayout.elements.TextFlow;
    import flashx.textLayout.formats.TextLayoutFormat;
    import flashx.textLayout.tlf_internal;

    import mx.containers.Canvas;

    import org.flexunit.asserts.assertTrue;

    use namespace tlf_internal;

    [TestCase(order=3)]
    public class AccessibilityMethodsTest extends VellumTestCase
    {
        private var textFlow:TextFlow;
        private var container:Sprite;

        private const Markup:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' fontSize='14' " +
                "textIndent='0' paragraphSpaceBefore='6' paddingTop='4' paddingBottom='4' fontFamily='Times New Roman'>" +
                "<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" +
                "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 " +
                "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:p paragraphSpaceAfter='15'>" +
                "<flow:span>" +
                "The man who now watched the fire was of a different order, and troubled himself with no " +
                "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:p paragraphSpaceAfter='15'>" +
                "<flow:span>" +
                "The man who now watched the fire was of a different order, and troubled himself with no " +
                "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:p paragraphSpaceAfter='15'>" +
                "<flow:span>" +
                "The man who now watched the fire was of a different order, and troubled himself with no " +
                "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:p paragraphSpaceAfter='15'>" +
                "<flow:span>" +
                "The man who now watched the fire was of a different order, and troubled himself with no " +
                "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:p paragraphSpaceAfter='15'>" +
                "<flow:span>" +
                "The man who now watched the fire was of a different order, and troubled himself with no " +
                "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:p paragraphSpaceAfter='15'>" +
                "<flow:span>" +
                "The man who now watched the fire was of a different order, and troubled himself with no " +
                "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>";

        public function AccessibilityMethodsTest()
        {
            super("", "AccessibilityMethodsTest", TestConfig.getInstance());
        }

        [Before]
        override public function setUpTest():void
        {
            super.setUpTest();
            cleanUpTestApp();
            TestDisplayObject = testApp.getDisplayObject();
            createTextFlow(getFileData("simple.xml"));
            TestFrame = textFlow.flowComposer.getControllerAt(0);	//pacify assert in tearDown  */
        }

        [After]
        override public function tearDownTest():void
        {
            super.tearDownTest();
            if (container.parent)		// this should've been done already
                container.parent.removeChild(container);
            container = null;
            textFlow = null;
        }

        [Test]
        public function selectionReportingTests():void
        {

            var accessibilityObject:AccessibilityImplementation = getAccessibilityImplementation();

            //start with no interaction - should return false
            textFlow.interactionManager = null;

            //we no longer have a selection manager, so there should be no selection.  Make sure
            //that we report -1 for anchor and active.
            assertTrue("selectionActiveIndex should report -1 when there is no Manager or EditingMode is READ_ONLY!", accessibilityObject["selectionActiveIndex"] == -1);
            assertTrue("selectionAnchorIndex should report -1 when there is no Manager or EditingMode is READ_ONLY!", accessibilityObject["selectionAnchorIndex"] == -1);

            textFlow.interactionManager = new SelectionManager();
            textFlow.interactionManager.selectRange(25, 50);
            assertTrue("selectionActiveIndex should report 50 but is " + accessibilityObject["selectionActiveIndex"], accessibilityObject["selectionActiveIndex"] == 50);
            assertTrue("selectionAnchorIndex should report 25 but is " + accessibilityObject["selectionAnchorIndex"], accessibilityObject["selectionAnchorIndex"] == 25);
            assertTrue("selectionActiveIndex should match. SelMgr reports " + textFlow.interactionManager.activePosition +
                    " but container reports " + accessibilityObject["selectionActiveIndex"], textFlow.interactionManager.activePosition == accessibilityObject["selectionActiveIndex"]);
            assertTrue("selectionAnchorIndex should match. SelMgr reports " + textFlow.interactionManager.anchorPosition +
                    " but container reports " + accessibilityObject["selectionAnchorIndex"], textFlow.interactionManager.anchorPosition == accessibilityObject["selectionAnchorIndex"]);

            textFlow.interactionManager = new EditManager();
            textFlow.interactionManager.selectRange(15, 10);
            assertTrue("selectionActiveIndex should report 10 but is " + accessibilityObject["selectionActiveIndex"], accessibilityObject["selectionActiveIndex"] == 10);
            assertTrue("selectionAnchorIndex should report 15 but is " + accessibilityObject["selectionAnchorIndex"], accessibilityObject["selectionAnchorIndex"] == 15);
            assertTrue("selectionActiveIndex should match. EditMgr reports " + textFlow.interactionManager.activePosition +
                    " but container reports " + accessibilityObject["selectionActiveIndex"], textFlow.interactionManager.activePosition == accessibilityObject["selectionActiveIndex"]);
            assertTrue("selectionAnchorIndex should match. EditMgr reports " + textFlow.interactionManager.anchorPosition +
                    " but container reports " + accessibilityObject["selectionAnchorIndex"], textFlow.interactionManager.anchorPosition == accessibilityObject["selectionAnchorIndex"]);
        }

        [Test]
        public function textReportingTests():void
        {
            // Construct an IMEClient just for testing its getTextInRange in isolation.
            var editManager:EditManager = new EditManager();
            textFlow.interactionManager = editManager;
            var imeClient:IIMEClient = createIMEClient();

            //textFlow.textLength includes all para terminators.  However, we dont' include the final one for the last
            //paragraph when getting text - since there may not be a carriage return on it
            var textLen:int = textFlow.textLength - 1;

            var totalText:String = imeClient.getTextInRange(-1, -1);
            assertTrue("getTextInRange with default values should get all text in the Flow, but only got " + totalText.length
                    + " characters out of " + textLen + ".", totalText.length == textLen);

            var para:ParagraphElement = textFlow.getFirstLeaf().getParagraph();
            var paraEnd:int = para.textLength - 1;
            var selEnd:int = 64 < paraEnd ? 64 : paraEnd;
            var selStart:int = selEnd >= 10 ? selEnd - 10 : 0;
            var expectedLen:int = selEnd - selStart;

            //assert that we have legit values.
            assertTrue(selStart != selEnd, "We need to have text to make this test work!  Where did it go!?");
            //		CONFIG::debug{ assert(selStart != selEnd, "We need to have text to make this test work!  Where did it go!?")};

            var subText:String = imeClient.getTextInRange(selStart, selEnd);
            var outOfOrderText:String = imeClient.getTextInRange(selEnd, selStart);
            assertTrue("getTextInRange with values (" + selStart + ", " + selEnd + ") should have a text length of " + expectedLen
                    + " but is " + subText.length, subText.length == expectedLen);
            assertTrue("getTextInRange with values (" + selEnd + ", " + selStart + ") should have a text length of " + expectedLen
                    + " but is " + outOfOrderText.length, outOfOrderText.length == expectedLen);

            assertTrue("getTextInRange with values both in and out of order should have the same text!",
                    outOfOrderText == subText);

            //get text directly from paragraph.  Since this is the first one, the absolute positions and relative positions should match
            var paraText:String = para.getText().substring(selStart, selEnd);
            assertTrue("getTextInRange did not report the same text as the paragraph!  paraText is \'" + paraText
                    + "\' while result is \'" + subText + "\'.", paraText == subText);

            //get text from second paragraph
            var nextPara:ParagraphElement = para.getNextParagraph();
            if (nextPara)
            {
                var nextAbsStart:int = nextPara.getAbsoluteStart();
                //remember that nextPara.textLength includes the para terminator mark, which will
                //be included in this calculation.  When we pull the paragraph text, we need to decrement the
                //value by 1 to prevent a false negative as getText will not include the terminator.
                selStart = nextAbsStart + nextPara.textLength - 26;
                selEnd = selStart + 25;
                subText = imeClient.getTextInRange(selStart, selEnd);

                //make sure that it is 1 < the absStart.  See note above
                var nextParaText:String = nextPara.getText().substring(selStart - nextAbsStart, selEnd - nextAbsStart);
                assertTrue("getTextInRange did not report the same text as the paragraph!  nextParaText is \'" + nextParaText
                        + "\' while result is \'" + subText + "\'.", nextParaText == subText);

                //perform tests accross para boundaries
                selStart = nextAbsStart - 20;
                selEnd = nextAbsStart + 20;
                var boundaryText:String = imeClient.getTextInRange(selStart, selEnd);

                assertTrue("getTextInRange across boundaries should be 40, but is " + boundaryText.length, boundaryText.length == 40);

                //again, in first para, absolute is same as local indicies - substring - all chars up to endIdx, so CR is not included,
                //which means we only compare the first 19 glyphs of boundaryText
                var firstBoundaryText:String = para.getText().substring(selStart, selStart + 20);
                assertTrue("getTextInRange across boundaries did not report the same text as the first paragraph!  paraText is \'" + firstBoundaryText
                        + "\' while result is \'" + boundaryText.substr(0, 19) + "\'.", firstBoundaryText == boundaryText.substr(0, 19));

                var secondBoundaryText:String = nextPara.getText().substring(0, 20);
                //use a start idx of 20 so we skip the CR
                assertTrue("getTextInRange across boundaries did not report the same text as the second paragraph!  paraText is \'" + secondBoundaryText
                        + "\' while result is \'" + boundaryText.substr(20, 20) + "\'.", secondBoundaryText == boundaryText.substr(20, 20));

            }


            //now do negative tests and make sure we fail properly
            var nullText:String = imeClient.getTextInRange(-2, 0);
            assertTrue("getTextInRange should return null with an invalid startIndex!", nullText == null);

            nullText = imeClient.getTextInRange(0, -23);
            assertTrue("getTextInRange should return null with an invalid endIndex!", nullText == null);

            nullText = imeClient.getTextInRange(textLen + 1, 1);
            assertTrue("getTextInRange should return null with a startIndex > the text length!", nullText == null);

            nullText = imeClient.getTextInRange(0, textLen + 1);
            assertTrue("getTextInRange should return null with an endIndex > the text length!", nullText == null);

            editManager.endIMESession();
        }

        [Test]
        public function searchIndexTests():void
        {
            var accessibilityObject:AccessibilityImplementation = getAccessibilityImplementation();

            var saveEnableSearch:Boolean = GlobalSettings.enableSearch;

            // Turn search index on and check the length and content of the result
            GlobalSettings.enableSearch = true;
            var entireContent:String = accessibilityObject["searchText"];
            assertTrue("length of searchText should match TextFlow length, got " + entireContent.length.toString + " expected " + (textFlow.textLength - 1).toString, entireContent.length == textFlow.textLength - 1);
            var checkContent:String = TextConverter.export(textFlow, TextConverter.PLAIN_TEXT_FORMAT, ConversionType.STRING_TYPE) as String;
            assertTrue("expected content of searchText to match exported plain text", entireContent == checkContent);

            // Turn search index off and check that we get nothing
            GlobalSettings.enableSearch = false;
            entireContent = accessibilityObject["searchText"];
            assertTrue("enableSearchIndex is off, but searchText return result", entireContent == null || entireContent.length == 0);

            GlobalSettings.enableSearch = saveEnableSearch;
        }

        [Test]
        public function textSelectTests():void
        {
            //start with no interaction - should return false
            textFlow.interactionManager = null;
            var imeClient:IIMEClient = createIMEClient();
            assertTrue("imeClient should be null on read-only textFlow", imeClient == null);

            // try a SelectionManager (read-only) should return null
            textFlow.interactionManager = new SelectionManager();
            imeClient = createIMEClient();
            assertTrue("imeClient should be null on read-select textFlow", imeClient == null);

            // Construct an IMEClient just for testing its selectRange in isolation.
            var editManager:EditManager = new EditManager();
            textFlow.interactionManager = editManager;
            imeClient = createIMEClient();
            imeClient.selectRange(15, 10);
            assertTrue("selectionActiveIndex should report 15 but is " + imeClient.selectionActiveIndex, imeClient.selectionActiveIndex == 10);
            assertTrue("selectionAnchorIndex should report 10 but is " + imeClient.selectionAnchorIndex, imeClient.selectionAnchorIndex == 15);

            editManager.endIMESession();
        }

        [Test]
        public function multiParaTest():void
        {
            cleanUpTestApp();

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

            createTextFlow(Markup);
            textFlow.flowComposer = new StandardFlowComposer();
            var editManager:EditManager = new EditManager();
            textFlow.interactionManager = editManager;

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

            //create two containers
            container = new Sprite();
            var container2:Sprite = new Sprite();
            var controllerOne:ContainerController = new ContainerController(container, 200, 500);
            var controllerTwo:ContainerController = new ContainerController(container2, 200, 500);

            addToCanvas(container);
            addToCanvas(container2);
            container.x = 50;
            container.y = 50;
            container2.x = 300;
            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 accessibilityObject:AccessibilityImplementation = getAccessibilityImplementation();

            textFlow.interactionManager = new SelectionManager();
            textFlow.interactionManager.selectRange(200, 2000);
            assertTrue("selectionActiveIndex should report 2000 but is " + accessibilityObject["selectionActiveIndex"], accessibilityObject["selectionActiveIndex"] == 2000);
            assertTrue("selectionAnchorIndex should report 200 but is " + accessibilityObject["selectionAnchorIndex"], accessibilityObject["selectionAnchorIndex"] == 200);
            assertTrue("selectionActiveIndex should match. SelMgr reports " + textFlow.interactionManager.activePosition +
                    " but container reports " + accessibilityObject["selectionActiveIndex"], textFlow.interactionManager.activePosition == accessibilityObject["selectionActiveIndex"]);
            assertTrue("selectionAnchorIndex should match. SelMgr reports " + textFlow.interactionManager.anchorPosition +
                    " but container reports " + accessibilityObject["selectionAnchorIndex"], textFlow.interactionManager.anchorPosition == accessibilityObject["selectionAnchorIndex"]);

            textFlow.interactionManager = new EditManager();
            textFlow.interactionManager.selectRange(200, 2000);
            assertTrue("selectionActiveIndex should report 2000 but is " + accessibilityObject["selectionActiveIndex"], accessibilityObject["selectionActiveIndex"] == 2000);
            assertTrue("selectionAnchorIndex should report 200 but is " + accessibilityObject["selectionAnchorIndex"], accessibilityObject["selectionAnchorIndex"] == 200);
            assertTrue("selectionActiveIndex should match. EditMgr reports " + textFlow.interactionManager.activePosition +
                    " but container reports " + accessibilityObject["selectionActiveIndex"], textFlow.interactionManager.activePosition == accessibilityObject["selectionActiveIndex"]);
            assertTrue("selectionAnchorIndex should match. EditMgr reports " + textFlow.interactionManager.anchorPosition +
                    " but container reports " + accessibilityObject["selectionAnchorIndex"], textFlow.interactionManager.anchorPosition == accessibilityObject["selectionAnchorIndex"]);

            // Construct an IMEClient just for testing its getTextInRange in isolation.
            var imeClient:IIMEClient = createIMEClient();

            var textLen:int = textFlow.textLength - 1;
            var totalText:String = imeClient.getTextInRange(-1, -1);
            assertTrue("getTextInRange with default values should get all text in the Flow, but only got " + totalText.length
                    + " characters out of " + textLen + ".", totalText.length == textLen);


            var firstPara:ParagraphElement = textFlow.getFirstLeaf().getParagraph();
            var secondPara:ParagraphElement = firstPara.getNextParagraph();
            var thirdPara:ParagraphElement = secondPara.getNextParagraph();
            var fourthPara:ParagraphElement = thirdPara.getNextParagraph();
            var secondParaStart:int = secondPara.getAbsoluteStart();
            var thirdParaEnd:int = fourthPara.getAbsoluteStart() - 1;
            var subText:String = imeClient.getTextInRange(secondParaStart, thirdParaEnd);
            var paraText:String = secondPara.getText() + '\n' + thirdPara.getText();

            assertTrue("getTextInRange did not report the same text as the paragraph!  paraText is \'" + paraText
                    + "\' while result is \'" + subText + "\'.", paraText.length == subText.length);
            assertTrue("getTextInRange did not report the same text as the paragraph!  paraText is \'" + paraText
                    + "\' while result is \'" + subText + "\'.", paraText == subText);
            EditManager(textFlow.interactionManager).endIMESession();

            //start with no interaction - should return false
            textFlow.interactionManager = null;

            //we no longer have a selection manager, so there should be no selection.  Make sure
            //that we report -1 for anchor and active.
            assertTrue("textSelectTests should report -1 when there is no Manager or EditingMode is READ_ONLY!", accessibilityObject["selectionActiveIndex"] == -1);
            assertTrue("textSelectTests should report -1 when there is no Manager or EditingMode is READ_ONLY!", accessibilityObject["selectionAnchorIndex"] == -1);

            textFlow.interactionManager = new SelectionManager();
            textFlow.interactionManager.selectRange(200, 2000);
            assertTrue("selectionActiveIndex should report 2000 but is " + accessibilityObject["selectionActiveIndex"], accessibilityObject["selectionActiveIndex"] == 2000);
            assertTrue("selectionAnchorIndex should report 200 but is " + accessibilityObject["selectionAnchorIndex"], accessibilityObject["selectionAnchorIndex"] == 200);


            textFlow.interactionManager = new EditManager();
            textFlow.interactionManager.selectRange(20, 2000);
            assertTrue("selectionActiveIndex should report 2000 but is " + accessibilityObject["selectionActiveIndex"], accessibilityObject["selectionActiveIndex"] == 2000);
            assertTrue("selectionAnchorIndex should report 200 but is " + accessibilityObject["selectionAnchorIndex"], accessibilityObject["selectionAnchorIndex"] == 20);

        }

        private function addToCanvas(sprite:Sprite):void
        {
            TestDisplayObject = testApp.getDisplayObject();
            if (TestDisplayObject is Canvas)
                Canvas(TestDisplayObject).rawChildren.addChild(sprite);
        }

        private function createIMEClient():IIMEClient
        {
            // We're mimicing an IME startComposition event, so that we can get an IME client. But under pre-Argo (10.1) players,
            // there is no imeStartComposition event, so in that case we can't return
            var imeEvent:IMEEvent = new IMEEvent("imeStartComposition");
            // figure out which controller we're targetting and set focus on it so the ime event will be received
            var i:int;
            for (i = 0; i < textFlow.flowComposer.numControllers && textFlow.flowComposer.getControllerAt(i).container != container; ++i)
            {
                // empty loop: prevent compiler warning
            }
            if (textFlow.interactionManager)
                textFlow.interactionManager.selectRange(-1, -1);
            textFlow.flowComposer.getControllerAt(i).setFocus();
            container.dispatchEvent(imeEvent);
            if (imeEvent["imeClient"] !== undefined)
                return imeEvent["imeClient"];
            return null;
        }

        private function createTextFlow(flowData:Object):void
        {
            // We need to create a new TextFlow even if there's a cached one so that we set it up with the correct Configuration
            var configuration:Configuration = TextFlow.defaultConfiguration.clone();
            configuration.enableAccessibility = true;
            textFlow = TextConverter.importToFlow(flowData, TextConverter.TEXT_LAYOUT_FORMAT, configuration);

            // Add a container to attach the accessibility object onto.
            container = new Sprite();
            textFlow.flowComposer.addController(new ContainerController(container, 300, 300));
            var testCanvas:Canvas = testApp.getDisplayObject();
            testCanvas.rawChildren.addChild(container);
        }

        private function getAccessibilityImplementation():AccessibilityImplementation
        {
            // Hack! The accessibilityImplementation may not be on the container if the Player does
            // not detect that accessibility is turned on in the OS/browser. We want the test to run
            // even in that case, so we push the accessibility implementation in anyway. If accessibility
            // is turned on, we should not hit this case -- accImpl should be there already
            if (container.accessibilityImplementation == null &&
                    textFlow.flowComposer.getControllerAt(0).container == container)
            {
                assertTrue("Accessibility object wasn't added to container", !Capabilities.hasAccessibility);
                container.accessibilityImplementation = new TextAccImpl(container, textFlow);
            }

            return container.accessibilityImplementation;
        }
    }
}
