http://git-wip-us.apache.org/repos/asf/flex-tlf/blob/d92c169e/automation_tests/src/UnitTest/Tests/GeneralFunctionsTest.as
----------------------------------------------------------------------
diff --git a/automation_tests/src/UnitTest/Tests/GeneralFunctionsTest.as 
b/automation_tests/src/UnitTest/Tests/GeneralFunctionsTest.as
index 134f99c..fd022cb 100644
--- a/automation_tests/src/UnitTest/Tests/GeneralFunctionsTest.as
+++ b/automation_tests/src/UnitTest/Tests/GeneralFunctionsTest.as
@@ -18,33 +18,30 @@
 
////////////////////////////////////////////////////////////////////////////////
 package UnitTest.Tests
 {
-       import UnitTest.ExtendedClasses.TestDescriptor;
-       import UnitTest.ExtendedClasses.TestSuiteExtended;
-       import UnitTest.ExtendedClasses.VellumTestCase;
-       import UnitTest.Fixtures.TestConfig;
-       import UnitTest.Fixtures.TestEditManager;
-       
-       import flash.display.Sprite;
-       import flash.events.*;
-       import flash.text.engine.FontPosture;
-       import flash.text.engine.FontWeight;
-       import flash.ui.Keyboard;
-       import flash.utils.getDefinitionByName;
-       import flash.utils.getQualifiedClassName;
-       
-       import flashx.textLayout.container.ContainerController;
-       import flashx.textLayout.conversion.ITextImporter;
-       import flashx.textLayout.conversion.TextConverter;
-       import flashx.textLayout.edit.EditManager;
-       import flashx.textLayout.elements.*;
-       import flashx.textLayout.events.FlowOperationEvent;
-       import flashx.textLayout.events.SelectionEvent;
-       import flashx.textLayout.events.StatusChangeEvent;
-       import flashx.textLayout.formats.*;
-       import flashx.textLayout.operations.FlowOperation;
-       import flashx.textLayout.operations.UndoOperation;
-       import flashx.textLayout.tlf_internal;
-       import flashx.undo.UndoManager;
+    import UnitTest.ExtendedClasses.VellumTestCase;
+    import UnitTest.Fixtures.TestConfig;
+    import UnitTest.Fixtures.TestEditManager;
+
+    import flash.display.Sprite;
+    import flash.events.*;
+    import flash.text.engine.FontPosture;
+    import flash.text.engine.FontWeight;
+    import flash.ui.Keyboard;
+    import flash.utils.getQualifiedClassName;
+
+    import flashx.textLayout.container.ContainerController;
+    import flashx.textLayout.conversion.ITextImporter;
+    import flashx.textLayout.conversion.TextConverter;
+    import flashx.textLayout.edit.EditManager;
+    import flashx.textLayout.elements.*;
+    import flashx.textLayout.events.FlowOperationEvent;
+    import flashx.textLayout.events.SelectionEvent;
+    import flashx.textLayout.events.StatusChangeEvent;
+    import flashx.textLayout.formats.*;
+    import flashx.textLayout.operations.FlowOperation;
+    import flashx.textLayout.operations.UndoOperation;
+    import flashx.textLayout.tlf_internal;
+    import flashx.undo.UndoManager;
 
     import org.flexunit.asserts.assertTrue;
     import org.flexunit.asserts.fail;
@@ -52,1296 +49,1336 @@ package UnitTest.Tests
     use namespace tlf_internal;
 
 
-       public class GeneralFunctionsTest extends VellumTestCase
-       {
-               public var SelectionChanged:Boolean;
-               private var callback:Boolean;
-
-               public function GeneralFunctionsTest(methodName:String, 
testID:String, testConfig:TestConfig, testXML:XML = null)
-               {
-                       super(methodName, testID, testConfig);
-
-                       // Note: These must correspond to a Watson product area 
(case-sensitive)
-                       metaData.productArea = "Editing";
-               }
-
-               public static function suite(testConfig:TestConfig, 
ts:TestSuiteExtended):void
-               {
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "arrowLeft", testConfig) );
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "arrowRight", testConfig) );
-                       //ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "arrowDown", testConfig) );
-                       //ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "arrowUp", testConfig) );
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "replaceSelectionTest", testConfig) );
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "backSpaceSelectionTest", testConfig) ); 
// KJT
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "backSpaceInsertionPointTest", testConfig) 
);
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "backSpaceLowerLimitTest", testConfig) );
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "deleteSelectionTest", testConfig) );
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "deleteInsertionPointTest", testConfig) );
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "deleteUpperLimitTest", testConfig) );
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "splitParagraphInsertionPointTest", 
testConfig) );
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "splitParagraphSelectionTest", testConfig) 
);
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "splitParagraphFormatTest", testConfig) );
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "unDoOp", testConfig) ); // undo redo// KJT
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "setSelectionRangeTest", testConfig) );// 
select range and listen for change event // KJT
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "insertTextTest", testConfig) ); // KJT
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "joinedBackspaceUndoTest", testConfig) );
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "joinedDeleteUndoTest", testConfig) );
-                       /* Waiting for troubleshooting -*/ ts.addTestDescriptor 
(new TestDescriptor(GeneralFunctionsTest, "joinedInsertUndoTest", testConfig) );
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "joinedSplitParagraphUndoTest", 
testConfig) );
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "undoLimitTest", testConfig) );
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "transParagraphDeleteTest", testConfig) );
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "emptyParagraphTest", testConfig) );
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "splitUTF16Test", testConfig) );
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "splitUTF32Test", testConfig) );
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "undoWithModelChangeTest", testConfig) );
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "doubleClickTest", testConfig) );
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "doubleClickHyphenTest", testConfig) );
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "doubleClickPunctuationTest", testConfig) 
);
-                       ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "undoRedoStackTest", testConfig) );
-                       if (testConfig.writingDirection[0] == 
BlockProgression.TB && testConfig.writingDirection[1] == Direction.LTR)
-                       {
-                               ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "replaceChildrenFlowTest", testConfig) );
-                               ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "resolveInlinesTest", testConfig) );
-                               ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "nestingTest", testConfig) );
-                               ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "errorThrowing", testConfig ) );
-                               ts.addTestDescriptor (new 
TestDescriptor(GeneralFunctionsTest, "AllNestingTest", testConfig ) );
-                       }
-               }
-
-               /**
-               * selecting text from 10 to 20
-               */
-
-               public function selChange(e:Event):void //KJT selection change 
event method
-               {
-                       SelectionChanged = true;
-               }
-
-               public function setSelectionRangeTest():void  //KJT  test 
selection range and change event
-               {
-                       var startIndx:int = 800;
-                       var endIndx:int = 933;
-                       //trace('CALL SET SELECTION');
-
-                       
SelManager.textFlow.addEventListener(SelectionEvent.SELECTION_CHANGE, 
selChange, false, 0, true);
-                       SelManager.selectRange(startIndx,endIndx);
-
-                       assertTrue("beginning index should be 800, but is " + 
SelManager.anchorPosition,
-                                               SelManager.anchorPosition == 
800);
-                       assertTrue("end index should be 933, but is " + 
SelManager.activePosition,
-                                               SelManager.activePosition == 
933);
-                       assertTrue("SelectionChanged returned false", 
SelectionChanged == true);
-               }
-               /**
-                * Select 40 characters and replaces them with new text
-                */
-               public function replaceSelectionTest():void
-               {
-                       var startIndx:int = 10;
-                       var endIndx:int = 50;
-
-                       var attributes:TextLayoutFormat  = new 
TextLayoutFormat();
-                       attributes.fontWeight = FontWeight.BOLD;
-                       attributes.lineThrough = true;
-
-                       SelManager.selectRange(startIndx,endIndx);
-                       SelManager.applyLeafFormat(attributes);
-
-                       SelManager.insertText("New");
-                       SelManager.flushPendingOperations();
-
-                       var leaf:FlowLeafElement = 
SelManager.textFlow.findLeaf(startIndx);
-                       var attributesNew:ITextLayoutFormat = leaf.format;
-                       assertTrue("Invalid point format after block deletion", 
TextLayoutFormat.isEqual(attributes, attributesNew));
-               }
-               /**
-                * Select 40 characters and delete them.
-                */
-               public function backSpaceSelectionTest():void
-               {
-                       var startIndx:int = 10;
-                       var endIndx:int = 50;
-
-                       var attributes:TextLayoutFormat  = new 
TextLayoutFormat();
-                       attributes.fontWeight = FontWeight.BOLD;
-                       attributes.lineThrough = true;
-
-                       SelManager.selectRange(startIndx,endIndx);
-                       SelManager.applyLeafFormat(attributes);
-
-                       var initLength:uint = SelManager.textFlow.textLength;
-                       SelManager.deletePreviousCharacter();
-                       var endLength:uint = SelManager.textFlow.textLength;
-
-                       assertTrue("deleting the selection should have removed 
" +(endIndx - startIndx) +
-                                               " characters.  It actually 
removed " + (initLength - endLength),
-                                               endLength == initLength - 
(endIndx - startIndx) );
-
-                       SelManager.insertText("New");
-                       SelManager.flushPendingOperations();
-
-                       var leaf:FlowLeafElement = 
SelManager.textFlow.findLeaf(startIndx);
-                       var attributesNew:ITextLayoutFormat = leaf.format;
-                       assertTrue("Invalid point format after block deletion", 
TextLayoutFormat.isEqual(attributes, attributesNew));
-               }
-
-               /**
-                * Set the cursor position back ten characters and delete the 
first ten characters.
-                */
-               public function backSpaceInsertionPointTest():void
-               {
-                       var n:int = 10;
-                       SelManager.selectRange(n,n);
-
-                       var initLength:uint = SelManager.textFlow.textLength;
-
-                       for(var i:int = 0; i < n; i++){
-                               SelManager.deletePreviousCharacter();
-                       }
-
-                       var endLength:uint = SelManager.textFlow.textLength;
-
-                       assertTrue("should have removed " + n + " characters.  
Actually removed " +
-                                               (initLength - endLength) , 
endLength == initLength - n);
-               }
-
-               /**
-                * Set the cursor position back nine characters and delete the 
first ten characters.
-                * Ensure that only nine characters are deleted.
-                */
-               public function backSpaceLowerLimitTest():void
-               {
-                       var n:int = 9;
-                       SelManager.selectRange(n,n);
-
-                       var initLength:uint = SelManager.textFlow.textLength;
-
-                       for(var i:int = 0; i <= n; i++){
-                               SelManager.deletePreviousCharacter();
-                       }
-
-                       var endLength:uint = SelManager.textFlow.textLength;
-
-                       assertTrue("should have removed " + n + " characters.  
Actually removed " +
-                                               (initLength - endLength) , 
endLength == initLength - n);
-               }
-
-               /**
-                * Select 40 characters and delete them.
-                */
-               public function deleteSelectionTest():void
-               {
-                       var startIndx:int = 10;
-                       var endIndx:int = 50;
-
-                       SelManager.selectRange(startIndx,endIndx);
-
-                       var initLength:uint = SelManager.textFlow.textLength;
-                       SelManager.deleteNextCharacter();
-                       var endLength:uint = SelManager.textFlow.textLength;
-
-                       assertTrue("should have removed " + (endIndx - 
startIndx) + " characters.  Actually removed " +
-                                               (initLength - endLength) , 
endLength == initLength - (endIndx - startIndx) );
-               }
-
-               /**
-                * Delete the first ten characters.
-                */
-               public function deleteInsertionPointTest():void
-               {
-                       var n:int = 10;
-                       SelManager.selectRange(0,0);
-
-                       var initLength:uint = SelManager.textFlow.textLength;
-
-                       for(var i:int = 0; i < n; i++){
-                               SelManager.deleteNextCharacter();
-                       }
-
-                       var endLength:uint = SelManager.textFlow.textLength;
-
-                       assertTrue("should have removed " + n + " characters.  
Actually removed " +
-                                               (initLength - endLength), 
endLength == initLength - n);
-               }
-
-               /**
-                * Set the cursor position back nine characters and delete the 
first ten characters.
-                * Ensure that only nine characters are deleted.
-                */
-               public function deleteUpperLimitTest():void
-               {
-                       var n:int = 9;
-
-                       var initLength:uint = SelManager.textFlow.textLength;
-                       SelManager.selectRange(initLength - (n+1), initLength - 
(n+1));
-
-                       for(var i:int = 0; i < n; i++){
-                               SelManager.deleteNextCharacter();
-                       }
-
-                       var endLength:uint = SelManager.textFlow.textLength;
-
-                       assertTrue("should have removed " + n + " characters.  
Actually removed " +
-                                               (initLength - endLength) , 
endLength == initLength - n);
-               }
+    public class GeneralFunctionsTest extends VellumTestCase
+    {
+        public static const childParentTable:Array =
+                [
+                    [ "child\parent", TextFlow, DivElement, ParagraphElement, 
LinkElement, TCYElement, SpanElement, InlineGraphicElement, BreakElement, 
TabElement, ListElement, ListItemElement, SubParagraphGroupElement ],
+                    [ TextFlow, "no", "no", "no", "no", "no", "no", "no", 
"no", "no", "no", "no", "no" ],
+                    [ DivElement, "yes", "yes", "no", "no", "no", "no", "no", 
"no", "no", "yes", "yes", "no" ],
+                    [ ParagraphElement, "yes", "yes", "no", "no", "no", "no", 
"no", "no", "no", "yes", "yes", "no" ],
+                    [ LinkElement, "no", "no", "yes", "no", "yes", "no", "no", 
"no", "no", "no", "no", "yes" ],
+                    [ TCYElement, "no", "no", "yes", "yes", "no", "no", "no", 
"no", "no", "no", "no", "yes" ],
+                    [ SpanElement, "no", "no", "yes", "yes", "yes", "no", 
"no", "no", "no", "no", "no", "yes" ],
+                    [ InlineGraphicElement, "no", "no", "yes", "yes", "yes", 
"no", "no", "no", "no", "no", "no", "yes" ],
+                    [ BreakElement, "no", "no", "yes", "yes", "yes", "no", 
"no", "no", "no", "no", "no", "yes" ],
+                    [ TabElement, "no", "no", "yes", "yes", "yes", "no", "no", 
"no", "no", "no", "no", "yes" ],
+                    [ ListElement, "yes", "yes", "no", "no", "no", "no", "no", 
"no", "no", "yes", "yes", "no" ],
+                    [ ListItemElement, "no", "no", "no", "no", "no", "no", 
"no", "no", "no", "yes", "no", "no" ],
+                    [ SubParagraphGroupElement, "no", "no", "yes", "yes", 
"yes", "no", "no", "no", "no", "no", "no", "yes" ]
+                ];
+
+        private static const customResourceDict:Object =
+        {
+            invalidFlowElementConstruct_custom: "Attempted construct of 
invalid FlowElement subclass",
+            badMXMLChildrenArgument_custom: "Bad element of type {0} passed to 
mxmlChildren",
+            malformedTag: "Malformed tag </p/>",
+            XMLParserFailure: "TypeError: Error #1090: XML parser failure: 
element is malformed."
+        };
+
+        /**
+         * pick up the actual operation
+         */
+        private var flowOp:FlowOperation;
+        private var SelectionChanged:Boolean;
+        private var ilgStatus:String;
+
+        public function GeneralFunctionsTest()
+        {
+            super("", "EventOverrideTest", TestConfig.getInstance());
+
+            metaData = {};
+            // Note: These must correspond to a Watson product area 
(case-sensitive)
+            metaData.productArea = "Editing";
+        }
+
+
+        [Before]
+        override public function setUpTest():void
+        {
+            super.setUpTest();
+        }
+
+        [After]
+        override public function tearDownTest():void
+        {
+            super.tearDownTest();
+        }
+
+
+        [Test]
+        public function setSelectionRangeTest():void  //KJT  test selection 
range and change event
+        {
+            var startIndx:int = 800;
+            var endIndx:int = 933;
+            //trace('CALL SET SELECTION');
+
+            
SelManager.textFlow.addEventListener(SelectionEvent.SELECTION_CHANGE, 
selChange, false, 0, true);
+            SelManager.selectRange(startIndx, endIndx);
+
+            assertTrue("beginning index should be 800, but is " + 
SelManager.anchorPosition,
+                    SelManager.anchorPosition == 800);
+            assertTrue("end index should be 933, but is " + 
SelManager.activePosition,
+                    SelManager.activePosition == 933);
+            assertTrue("SelectionChanged returned false", SelectionChanged == 
true);
+        }
+
+        [Test]
+        /**
+         * Select 40 characters and replaces them with new text
+         */
+        public function replaceSelectionTest():void
+        {
+            var startIndx:int = 10;
+            var endIndx:int = 50;
+
+            var attributes:TextLayoutFormat = new TextLayoutFormat();
+            attributes.fontWeight = FontWeight.BOLD;
+            attributes.lineThrough = true;
+
+            SelManager.selectRange(startIndx, endIndx);
+            SelManager.applyLeafFormat(attributes);
+
+            SelManager.insertText("New");
+            SelManager.flushPendingOperations();
+
+            var leaf:FlowLeafElement = SelManager.textFlow.findLeaf(startIndx);
+            var attributesNew:ITextLayoutFormat = leaf.format;
+            assertTrue("Invalid point format after block deletion", 
TextLayoutFormat.isEqual(attributes, attributesNew));
+        }
+
+        [Test]
+        /**
+         * Select 40 characters and delete them.
+         */
+        public function backSpaceSelectionTest():void
+        {
+            var startIndx:int = 10;
+            var endIndx:int = 50;
+
+            var attributes:TextLayoutFormat = new TextLayoutFormat();
+            attributes.fontWeight = FontWeight.BOLD;
+            attributes.lineThrough = true;
+
+            SelManager.selectRange(startIndx, endIndx);
+            SelManager.applyLeafFormat(attributes);
+
+            var initLength:uint = SelManager.textFlow.textLength;
+            SelManager.deletePreviousCharacter();
+            var endLength:uint = SelManager.textFlow.textLength;
+
+            assertTrue("deleting the selection should have removed " + 
(endIndx - startIndx) +
+                    " characters.  It actually removed " + (initLength - 
endLength),
+                    endLength == initLength - (endIndx - startIndx));
+
+            SelManager.insertText("New");
+            SelManager.flushPendingOperations();
+
+            var leaf:FlowLeafElement = SelManager.textFlow.findLeaf(startIndx);
+            var attributesNew:ITextLayoutFormat = leaf.format;
+            assertTrue("Invalid point format after block deletion", 
TextLayoutFormat.isEqual(attributes, attributesNew));
+        }
+
+        [Test]
+        /**
+         * Set the cursor position back ten characters and delete the first 
ten characters.
+         */
+        public function backSpaceInsertionPointTest():void
+        {
+            var n:int = 10;
+            SelManager.selectRange(n, n);
+
+            var initLength:uint = SelManager.textFlow.textLength;
+
+            for (var i:int = 0; i < n; i++)
+            {
+                SelManager.deletePreviousCharacter();
+            }
+
+            var endLength:uint = SelManager.textFlow.textLength;
+
+            assertTrue("should have removed " + n + " characters.  Actually 
removed " +
+                    (initLength - endLength), endLength == initLength - n);
+        }
+
+        [Test]
+        /**
+         * Set the cursor position back nine characters and delete the first 
ten characters.
+         * Ensure that only nine characters are deleted.
+         */
+        public function backSpaceLowerLimitTest():void
+        {
+            var n:int = 9;
+            SelManager.selectRange(n, n);
+
+            var initLength:uint = SelManager.textFlow.textLength;
+
+            for (var i:int = 0; i <= n; i++)
+            {
+                SelManager.deletePreviousCharacter();
+            }
+
+            var endLength:uint = SelManager.textFlow.textLength;
+
+            assertTrue("should have removed " + n + " characters.  Actually 
removed " +
+                    (initLength - endLength), endLength == initLength - n);
+        }
+
+        [Test]
+        /**
+         * Select 40 characters and delete them.
+         */
+        public function deleteSelectionTest():void
+        {
+            var startIndx:int = 10;
+            var endIndx:int = 50;
+
+            SelManager.selectRange(startIndx, endIndx);
+
+            var initLength:uint = SelManager.textFlow.textLength;
+            SelManager.deleteNextCharacter();
+            var endLength:uint = SelManager.textFlow.textLength;
+
+            assertTrue("should have removed " + (endIndx - startIndx) + " 
characters.  Actually removed " +
+                    (initLength - endLength), endLength == initLength - 
(endIndx - startIndx));
+        }
+
+        [Test]
+        /**
+         * Delete the first ten characters.
+         */
+        public function deleteInsertionPointTest():void
+        {
+            var n:int = 10;
+            SelManager.selectRange(0, 0);
+
+            var initLength:uint = SelManager.textFlow.textLength;
+
+            for (var i:int = 0; i < n; i++)
+            {
+                SelManager.deleteNextCharacter();
+            }
+
+            var endLength:uint = SelManager.textFlow.textLength;
+
+            assertTrue("should have removed " + n + " characters.  Actually 
removed " +
+                    (initLength - endLength), endLength == initLength - n);
+        }
+
+        [Test]
+        /**
+         * Set the cursor position back nine characters and delete the first 
ten characters.
+         * Ensure that only nine characters are deleted.
+         */
+        public function deleteUpperLimitTest():void
+        {
+            var n:int = 9;
+
+            var initLength:uint = SelManager.textFlow.textLength;
+            SelManager.selectRange(initLength - (n + 1), initLength - (n + 1));
+
+            for (var i:int = 0; i < n; i++)
+            {
+                SelManager.deleteNextCharacter();
+            }
+
+            var endLength:uint = SelManager.textFlow.textLength;
+
+            assertTrue("should have removed " + n + " characters.  Actually 
removed " +
+                    (initLength - endLength), endLength == initLength - n);
+        }
+
+        [Test]
+        /**
+         * Splits the paragraph after the first fifty characters.
+         * Verifies that there is one more line in the textFlow than it 
started with.
+         * Verifies that the first leaf has only 50 characters in it.
+         */
+        public function splitParagraphInsertionPointTest():void
+        {
+            var insertPoint:int = 50;
+
+            SelManager.selectRange(insertPoint, insertPoint);
+
+            var initLines:int = SelManager.textFlow.flowComposer.numLines;
+            SelManager.splitParagraph();
+            var endLines:int = SelManager.textFlow.flowComposer.numLines;
+
+            assertTrue("expected one additional line after splitting the 
paragraph.  Actually found " +
+                    (endLines - initLines), initLines = endLines - 1);
+
+            var lengthFirst:int = 
SelManager.textFlow.getFirstLeaf().textLength;
+
+            assertTrue("expected the first paragraph would have " + 
insertPoint +
+                    " characters.  Actually found " + lengthFirst, lengthFirst 
= insertPoint);
+        }
+
+        [Test]
+        /**
+         * 1. Sets attributes before (A, B), after (B', C) and at (B'', D) at 
split point.
+         * Splits paragraphs, adds new text and verifies that it has 
attributes (A, B'', C, D)
+         * 2. Tests special case for splitting a paragraph at the end of a 
link; point format is reset in this case
+         */
+        public function splitParagraphFormatTest():void
+        {
+            var insertPoint:int = 50;
+
+            var attributes:TextLayoutFormat = new TextLayoutFormat();
+
+            attributes.fontWeight = FontWeight.BOLD;
+            attributes.lineThrough = true;
+            SelManager.selectRange(insertPoint - 5, insertPoint);
+            SelManager.applyLeafFormat(attributes);
+
+            attributes.fontWeight = undefined;
+            attributes.textDecoration = TextDecoration.UNDERLINE;
+            attributes.fontSize = 72;
+            SelManager.selectRange(insertPoint, insertPoint + 5);
+            SelManager.applyLeafFormat(attributes);
+
+            attributes.textDecoration = TextDecoration.UNDERLINE;
+            attributes.lineThrough = true;
+            attributes.fontFamily = "Verdana";
+            SelManager.selectRange(insertPoint, insertPoint);
+            SelManager.applyLeafFormat(attributes);
+
+            SelManager.splitParagraph();
+
+            SelManager.insertText("New");
+            SelManager.flushPendingOperations();
+
+            var leaf:FlowLeafElement = 
SelManager.textFlow.findLeaf(insertPoint + 1);
+            attributes = new TextLayoutFormat(leaf.format);
+
+            assertTrue("Invalid point format for start of a new paragraph", 
attributes.fontWeight = FontWeight.BOLD);
+            assertTrue("Invalid point format for start of a new paragraph", 
attributes.fontSize = 72);
+            assertTrue("Invalid point format for start of a new paragraph", 
attributes.fontFamily = "Verdana");
+            assertTrue("Invalid point format for start of a new paragraph", 
attributes.textDecoration == TextDecoration.UNDERLINE && 
attributes.lineThrough);
+
+            insertPoint = 40;
+
+            SelManager.selectRange(insertPoint - 10, insertPoint);
+            SelManager.applyLink("http://www.google.com";, "_self", false);
+
+            SelManager.selectRange(insertPoint, insertPoint);
+            SelManager.splitParagraph();
+
+            SelManager.insertText("New");
+            SelManager.flushPendingOperations();
+
+            leaf = SelManager.textFlow.findLeaf(insertPoint + 1);
+            attributes = new TextLayoutFormat(leaf.format);
+            assertTrue("Invalid point format for start of a new paragraph 
after a link", TextLayoutFormat.isEqual(attributes, 
TextLayoutFormat.emptyTextLayoutFormat));
+        }
+
+        [Test]
+        /**
+         * Selects the characters between the 10th and 50th characters and 
splits the paragraph.
+         * Verifies that there is one more line in the textFlow than it 
started with.
+         * Verifies that the first leaf has only 10 characters in it.
+         * Verifies that the final length has 39 less characters in it.
+         */
+        public function splitParagraphSelectionTest():void
+        {
+            var startIndx:int = 10;
+            var endIndx:int = 50;
+
+
+            SelManager.selectRange(startIndx, endIndx);
+
+            var initLength:int = SelManager.textFlow.textLength;
+            var initLines:int = SelManager.textFlow.flowComposer.numLines;
+
+            SelManager.splitParagraph();
+
+            var endLength:int = SelManager.textFlow.textLength;
+            var endLines:int = SelManager.textFlow.flowComposer.numLines;
+
+            assertTrue("expected one additional line after splitting the 
paragraph.  Actually found " +
+                    (endLines - initLines), initLines = endLines - 1);
+
+            var lengthFirst:int = 
SelManager.textFlow.getFirstLeaf().textLength;
+
+            assertTrue("expected the first paragraph would have " + startIndx +
+                    " characters.  Actually found " + lengthFirst, lengthFirst 
= startIndx);
+            assertTrue("expected the entire flow would have " + (initLength - 
(endIndx - startIndx) + 1) +
+                    " characters.  Actually found " + endLength,
+                    endLength == initLength - (endIndx - startIndx) + 1);
+        }
+
+        [Test]
+        /**
+         * Creates a selection area of six characters at the last index of the 
flow root
+         * then inserts " BOOGA" into the selection area and verifies the 
length of the
+         * flow root has increased by 6.
+         */
+        public function insertTextTest():void //KJT
+        {
+            var textLength:uint = SelManager.textFlow.textLength;
+            SelManager.selectRange(textLength - 1, textLength + 5);
+
+            SelManager.insertText(" BOOGA");
+            SelManager.selectRange(textLength - 1, textLength + 5);
+
+            assertTrue("expected to find " + (textLength + 6) + " characters.  
Actually found " +
+                    SelManager.textFlow.textLength, 
SelManager.textFlow.textLength == textLength + 6);
+        }
+
+        [Test]
+        /**
+         * Sets the insertion point at 50, then generates the "0" keyboard 
event
+         * and verifies that the selBegIdx is 49.
+         */
+        public function arrowLeft():void
+        {
+            var event:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_UP, 
true, false, 0, Keyboard.LEFT);
+            SelManager.selectRange(50, 50);
+            SelManager.keyDownHandler(event);
+
+            if (SelManager.textFlow.computedFormat.blockProgression == 
BlockProgression.RL)
+            {
+                //                             assertTrue("expected insertion 
point at position 87. Actually found + " +
+                //                                     
SelManager.anchorPosition, SelManager.anchorPosition == 87);
+            }
+            else
+            {
+                if (SelManager.textFlow.computedFormat.direction == 
Direction.LTR)
+                {
+                    assertTrue("expected insertion point at position 49. 
Actually found + " +
+                            SelManager.activePosition, 
SelManager.activePosition == 49);
+                }
+                else
+                {
+                    assertTrue("expected insertion point at position 51. 
Actually found + " +
+                            SelManager.activePosition, 
SelManager.activePosition == 51);
+                }
+            }
+        }
+
+        [Test]
+        /**
+         * Sets the insertion point at 50, then generates the "0" keyboard 
event
+         * and verifies that the selBegIdx is 51.
+         */
+        public function arrowRight():void
+        {
+            var event:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_UP, 
true, false, 0, Keyboard.RIGHT);
+            SelManager.selectRange(50, 50);
+            SelManager.keyDownHandler(event);
+            if (SelManager.textFlow.computedFormat.blockProgression == 
BlockProgression.RL)
+            {
+                //                             assertTrue("expected insertion 
point at position 11. Actually found + " +
+                //                                     
SelManager.anchorPosition, SelManager.anchorPosition == 11);
+            }
+            else
+            {
+                if (SelManager.textFlow.computedFormat.direction == 
Direction.LTR)
+                {
+                    assertTrue("expected insertion point at position 51. 
Actually found " +
+                            SelManager.activePosition, 
SelManager.activePosition == 51);
+                }
+                else
+                {
+                    assertTrue("expected insertion point at position 49. 
Actually found " +
+                            SelManager.activePosition, 
SelManager.activePosition == 49);
+                }
+            }
+        }
+
+        [Test]
+        /**
+         * Sets the insertion point at 0, then generates the "40" keyboard 
event
+         * and verifies that the cursor is on the second line.
+         */
+        public function arrowDown():void
+        {
+            var event:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_UP, 
true, false, 40);
+            SelManager.selectRange(0, 0);
+            SelManager.keyDownHandler(event);
+            if (SelManager.textFlow.computedFormat.blockProgression == 
BlockProgression.TB)
+            {
+                //NYI
+            }
+            else
+            {
+                var ap:int = SelManager.activePosition;
+                var index:int = 
SelManager.textFlow.findChildIndexAtPosition(ap);
+                assertTrue("expected index at 2. Actually found " + index, 
index == 2);
+            }
+        }
+
+        [Test]
+        /**
+         * Sets the insertion point at the last char, then generates the "38" 
keyboard event
+         * and verifies that the cursor is on the second to last line.
+         */
+        public function arrowUp():void
+        {
+            var event:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_UP, 
true, false, 38);
+            var lastChar:int = SelManager.absoluteEnd;
+            var lastLine:int = 
SelManager.textFlow.findChildIndexAtPosition(lastChar);
+            SelManager.selectRange(lastChar, lastChar);
+            SelManager.keyDownHandler(event);
+            if (SelManager.textFlow.computedFormat.blockProgression == 
BlockProgression.TB)
+            {
+                //NYI
+            }
+            else
+            {
+                var index:int = 
SelManager.textFlow.findChildIndexAtPosition(SelManager.activePosition);
+                assertTrue("expected index at " + (lastChar - 1) +
+                        ". Actually found " + index,
+                        index == (lastChar - 1)
+                );
+            }
+        }
+
+        [Test]
+        /**
+         * Tests the undo and redo stacks by applying typeface changes by 
undoing
+         * and redoing them.
+         */
+        public function unDoOp():void  //KJT
+        {
+            var ca:TextLayoutFormat = new TextLayoutFormat();
+            ca.fontWeight = FontWeight.BOLD;
+            SelManager.applyLeafFormat(ca);
+
+            SelManager.undo();
+            Redo();
+
+            ca.fontStyle = FontPosture.ITALIC;
+            SelManager.applyLeafFormat(ca);
+
+            SelManager.undo();
+            SelManager.undo();
+        }
+
+        [Test]
+        /**
+         * Performs successive backspaces and one undo to see if all the 
deleted content
+         * is returned, then performs a redo to see if the content is 
correctly removed
+         * again.
+         */
+        public function joinedBackspaceUndoTest():void
+        {
+            var n:int = 10;
+            SelManager.selectRange(10, 10);
+
+            var initLength:uint = SelManager.textFlow.textLength;
+
+            for (var i:int = 0; i < n; i++)
+            {
+                var event:KeyboardEvent = new 
KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 8);
+                dispatchEvent(event);
+            }
+
+            var endLength:uint = SelManager.textFlow.textLength;
+
+            SelManager.undo();
+
+            var undoLength:uint = SelManager.textFlow.textLength;
+
+            assertTrue("expected text length before undo to be " + n + " less. 
 Was actually " +
+                    (endLength - initLength) + " less.", endLength == 
initLength - n);
+            assertTrue("expected text length after undo to be identical to the 
start, but it was off by " +
+                    (undoLength - initLength), undoLength == initLength);
+
+            Redo();
+
+            var redoLength:uint = SelManager.textFlow.textLength;
+
+            assertTrue("expected redo length to equal undo length, but found " 
+
+                    redoLength + " and " + endLength, redoLength == endLength);
+        }
+
+        [Test]
+        /**
+         * Performs successive deletes and one undo to see if all the deleted 
content
+         * is returned, then performs a redo to see if the content is 
correctly removed
+         * again.
+         */
+        public function joinedDeleteUndoTest():void
+        {
+            var n:int = 10;
+            SelManager.selectRange(10, 10);
+
+            var initLength:uint = SelManager.textFlow.textLength;
+
+            for (var i:int = 0; i < n; i++)
+            {
+                var event:KeyboardEvent = new 
KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 127, Keyboard.DELETE);
+                dispatchEvent(event);
+            }
+            SelManager.flushPendingOperations();
+
+            var endLength:uint = SelManager.textFlow.textLength;
+
+            SelManager.undo();
+
+            var undoLength:uint = SelManager.textFlow.textLength;
+
+            assertTrue("expected text length before undo to be " + n + " less. 
 Was actually " +
+                    (endLength - initLength) + " less.", endLength == 
initLength - n);
+            assertTrue("expected text length after undo to be identical to the 
start, but it was off by " +
+                    (undoLength - initLength), undoLength == initLength);
+
+            Redo();
+
+            var redoLength:uint = SelManager.textFlow.textLength;
+
+            assertTrue("expected redo length to equal undo length, but found " 
+
+                    redoLength + " and " + endLength, redoLength == endLength);
+        }
+
+        [Test]
+        /**
+         * Places a series of letter a's in and does one undo to see if all 
the a's
+         * are removed, then performs a redo to see if they're returned.
+         */
+        public function joinedInsertUndoTest():void
+        {
+            var n:int = 10;
+            SelManager.selectRange(10, 10);
+
+            var initLength:uint = SelManager.textFlow.textLength;
 
-               /**
-                * Splits the paragraph after the first fifty characters.
-                * Verifies that there is one more line in the textFlow than it 
started with.
-                * Verifies that the first leaf has only 50 characters in it.
-                */
-               public function splitParagraphInsertionPointTest():void
-               {
-                       var insertPoint:int = 50;
-
-                       SelManager.selectRange(insertPoint, insertPoint);
-
-                       var initLines:int = 
SelManager.textFlow.flowComposer.numLines;
-                       SelManager.splitParagraph();
-                       var endLines:int = 
SelManager.textFlow.flowComposer.numLines;
-
-                       assertTrue("expected one additional line after 
splitting the paragraph.  Actually found " +
-                                               (endLines - initLines), 
initLines = endLines - 1);
-
-                       var lengthFirst:int = 
SelManager.textFlow.getFirstLeaf().textLength;
-
-                       assertTrue("expected the first paragraph would have " + 
insertPoint +
-                                               " characters.  Actually found " 
+ lengthFirst, lengthFirst = insertPoint);
-               }
-
-               /**
-                * 1. Sets attributes before (A, B), after (B', C) and at (B'', 
D) at split point.
-                * Splits paragraphs, adds new text and verifies that it has 
attributes (A, B'', C, D)
-            * 2. Tests special case for splitting a paragraph at the end of a 
link; point format is reset in this case
-                */
-               public function splitParagraphFormatTest():void
-               {
-                       var insertPoint:int = 50;
-
-                       var attributes:TextLayoutFormat  = new 
TextLayoutFormat();
-
-                       attributes.fontWeight = FontWeight.BOLD;
-                       attributes.lineThrough = true;
-                       SelManager.selectRange(insertPoint-5, insertPoint);
-                       SelManager.applyLeafFormat(attributes);
-
-                       attributes.fontWeight = undefined;
-                       attributes.textDecoration = 
flashx.textLayout.formats.TextDecoration.UNDERLINE;
-                       attributes.fontSize = 72;
-                       SelManager.selectRange(insertPoint, insertPoint+5);
-                       SelManager.applyLeafFormat(attributes);
-
-                       attributes.textDecoration = 
flashx.textLayout.formats.TextDecoration.UNDERLINE;
-                       attributes.lineThrough = true;
-                       attributes.fontFamily = "Verdana";
-                       SelManager.selectRange(insertPoint, insertPoint);
-                       SelManager.applyLeafFormat(attributes);
-
-                       SelManager.splitParagraph();
-
-                       SelManager.insertText("New");
-                       SelManager.flushPendingOperations();
-
-                       var leaf:FlowLeafElement = 
SelManager.textFlow.findLeaf(insertPoint+1);
-                       attributes = new TextLayoutFormat(leaf.format);
-
-                       assertTrue("Invalid point format for start of a new 
paragraph", attributes.fontWeight = FontWeight.BOLD);
-                       assertTrue("Invalid point format for start of a new 
paragraph", attributes.fontSize = 72);
-                       assertTrue("Invalid point format for start of a new 
paragraph", attributes.fontFamily = "Verdana");
-                       assertTrue("Invalid point format for start of a new 
paragraph", attributes.textDecoration == 
flashx.textLayout.formats.TextDecoration.UNDERLINE && attributes.lineThrough);
-
-                       insertPoint = 40;
-
-                       SelManager.selectRange(insertPoint-10, insertPoint);
-                       SelManager.applyLink("http://www.google.com";, "_self", 
false);
-
-                       SelManager.selectRange(insertPoint, insertPoint);
-                       SelManager.splitParagraph();
-
-                       SelManager.insertText("New");
-                       SelManager.flushPendingOperations();
-
-                       leaf = SelManager.textFlow.findLeaf(insertPoint+1);
-                       attributes = new TextLayoutFormat(leaf.format);
-                       assertTrue("Invalid point format for start of a new 
paragraph after a link", TextLayoutFormat.isEqual(attributes, 
TextLayoutFormat.emptyTextLayoutFormat));
-               }
-
-               /**
-                * Selects the characters between the 10th and 50th characters 
and splits the paragraph.
-                * Verifies that there is one more line in the textFlow than it 
started with.
-                * Verifies that the first leaf has only 10 characters in it.
-                * Verifies that the final length has 39 less characters in it.
-                */
-               public function splitParagraphSelectionTest():void
-               {
-                       var startIndx:int = 10;
-                       var endIndx:int = 50;
-
-
-                       SelManager.selectRange(startIndx, endIndx);
-
-                       var initLength:int = SelManager.textFlow.textLength;
-                       var initLines:int = 
SelManager.textFlow.flowComposer.numLines;
-
-                       SelManager.splitParagraph();
-
-                       var endLength:int = SelManager.textFlow.textLength;
-                       var endLines:int = 
SelManager.textFlow.flowComposer.numLines;
-
-                       assertTrue("expected one additional line after 
splitting the paragraph.  Actually found " +
-                                               (endLines - initLines), 
initLines = endLines - 1);
-
-                       var lengthFirst:int = 
SelManager.textFlow.getFirstLeaf().textLength;
-
-                       assertTrue("expected the first paragraph would have " + 
startIndx +
-                                               " characters.  Actually found " 
+ lengthFirst, lengthFirst = startIndx);
-                       assertTrue("expected the entire flow would have " + 
(initLength - (endIndx - startIndx) + 1) +
-                                               " characters.  Actually found " 
+ endLength,
-                                               endLength == initLength - 
(endIndx - startIndx) + 1);
-               }
-
-               /**
-                * Creates a selection area of six characters at the last index 
of the flow root
-                * then inserts " BOOGA" into the selection area and verifies 
the length of the
-                * flow root has increased by 6.
-                */
-               public function insertTextTest():void //KJT
-               {
-                       var textLength:uint = SelManager.textFlow.textLength;
-                       SelManager.selectRange(textLength - 1, textLength + 5);
-
-                       SelManager.insertText(" BOOGA");
-                       SelManager.selectRange(textLength - 1,textLength + 5);
-
-                       assertTrue("expected to find " + (textLength + 6) + " 
characters.  Actually found " +
-                                               SelManager.textFlow.textLength, 
SelManager.textFlow.textLength == textLength + 6);
-               }
-
-               /**
-                * Sets the insertion point at 50, then generates the "0" 
keyboard event
-                * and verifies that the selBegIdx is 49.
-                */
-               public function arrowLeft():void
-               {
-                       var event:KeyboardEvent = new 
KeyboardEvent(KeyboardEvent.KEY_UP, true, false, 0, Keyboard.LEFT);
-                       SelManager.selectRange(50,50);
-                       SelManager.keyDownHandler(event);
-
-                       if(SelManager.textFlow.computedFormat.blockProgression 
== BlockProgression.RL)
-                       {
-//                             assertTrue("expected insertion point at 
position 87. Actually found + " +
-//                                     SelManager.anchorPosition, 
SelManager.anchorPosition == 87);
-                       }
-                       else
-                       {
-                               if(SelManager.textFlow.computedFormat.direction 
== Direction.LTR)
-                               {
-                                       assertTrue("expected insertion point at 
position 49. Actually found + " +
-                                       SelManager.activePosition, 
SelManager.activePosition == 49);
-                               }
-                               else
-                               {
-                                       assertTrue("expected insertion point at 
position 51. Actually found + " +
-                                       SelManager.activePosition, 
SelManager.activePosition == 51);
-                               }
-                       }
-               }
-
-               /**
-                * Sets the insertion point at 50, then generates the "0" 
keyboard event
-                * and verifies that the selBegIdx is 51.
-                */
-               public function arrowRight():void
-               {
-                       var event:KeyboardEvent = new 
KeyboardEvent(KeyboardEvent.KEY_UP, true, false, 0, Keyboard.RIGHT);
-                       SelManager.selectRange(50,50);
-                       SelManager.keyDownHandler(event);
-                       if(SelManager.textFlow.computedFormat.blockProgression 
== BlockProgression.RL)
-                       {
-//                             assertTrue("expected insertion point at 
position 11. Actually found + " +
-//                                     SelManager.anchorPosition, 
SelManager.anchorPosition == 11);
-                       }
-                       else
-               {
-                       if(SelManager.textFlow.computedFormat.direction == 
Direction.LTR)
-                       {
-                               assertTrue("expected insertion point at 
position 51. Actually found " +
-                                       SelManager.activePosition, 
SelManager.activePosition == 51);
-                       }
-                       else
-                       {
-                               assertTrue("expected insertion point at 
position 49. Actually found " +
-                                       SelManager.activePosition, 
SelManager.activePosition == 49);
-                       }
-               }
-               }
-
-               /**
-                * Sets the insertion point at 0, then generates the "40" 
keyboard event
-                * and verifies that the cursor is on the second line.
-                */
-               public function arrowDown():void
-               {
-                       var event:KeyboardEvent = new 
KeyboardEvent(KeyboardEvent.KEY_UP, true, false,40);
-                       SelManager.selectRange(0,0);
-                       SelManager.keyDownHandler(event);
-                       if(SelManager.textFlow.computedFormat.blockProgression 
== BlockProgression.TB)
-                       {
-                               //NYI
-                       }
-                       else
-               {
-                       var ap:int = SelManager.activePosition;
-                       var index:int = 
SelManager.textFlow.findChildIndexAtPosition(ap);
-                       assertTrue("expected index at 2. Actually found " + 
index, index == 2);
-               }
-               }
-
-               /**
-                * Sets the insertion point at the last char, then generates 
the "38" keyboard event
-                * and verifies that the cursor is on the second to last line.
-                */
-               public function arrowUp():void
-               {
-                       var event:KeyboardEvent = new 
KeyboardEvent(KeyboardEvent.KEY_UP, true, false,38);
-                       var lastChar:int = SelManager.absoluteEnd;
-                       var lastLine:int = 
SelManager.textFlow.findChildIndexAtPosition(lastChar);
-                       SelManager.selectRange(lastChar,lastChar);
-                       SelManager.keyDownHandler(event);
-                       if(SelManager.textFlow.computedFormat.blockProgression 
== BlockProgression.TB)
-                       {
-                               //NYI
-                       }
-                       else
-               {
-                       var index:int = 
SelManager.textFlow.findChildIndexAtPosition(SelManager.activePosition);
-                       assertTrue("expected index at " + (lastChar - 1) +
-                                               ". Actually found " + index,
-                                               index == (lastChar - 1)
-                       );
-               }
-               }
-
-               /**
-                * Tests the undo and redo stacks by applying typeface changes 
by undoing
-                * and redoing them.
-                */
-               public function unDoOp():void  //KJT
-               {
-                       var ca:TextLayoutFormat = new TextLayoutFormat();
-                       ca.fontWeight = FontWeight.BOLD;
-                       SelManager.applyLeafFormat(ca);
-
-                       SelManager.undo();
-                       Redo();
-
-                       ca.fontStyle = FontPosture.ITALIC;
-                       SelManager.applyLeafFormat(ca);
-
-                       SelManager.undo();
-                       SelManager.undo();
-               }
-
-               /**
-                * Performs successive backspaces and one undo to see if all 
the deleted content
-                * is returned, then performs a redo to see if the content is 
correctly removed
-                * again.
-                */
-               public function joinedBackspaceUndoTest():void
-               {
-                       var n:int = 10;
-                       SelManager.selectRange(10,10);
-
-                       var initLength:uint = SelManager.textFlow.textLength;
-
-                       for(var i:int = 0; i < n; i++){
-                               var event:KeyboardEvent = new 
KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 8);
-                               dispatchEvent(event);
-                       }
-
-                       var endLength:uint = SelManager.textFlow.textLength;
-
-                       SelManager.undo();
-
-                       var undoLength:uint = SelManager.textFlow.textLength;
-
-                       assertTrue("expected text length before undo to be " + 
n + " less.  Was actually " +
-                                               (endLength - initLength) + " 
less.", endLength == initLength - n );
-                       assertTrue("expected text length after undo to be 
identical to the start, but it was off by " +
-                                               (undoLength-initLength), 
undoLength == initLength);
-
-                       Redo();
-
-                       var redoLength:uint = SelManager.textFlow.textLength;
-
-                       assertTrue("expected redo length to equal undo length, 
but found " +
-                                               redoLength + " and " + 
endLength, redoLength == endLength);
-               }
-
-               /**
-                * Performs successive deletes and one undo to see if all the 
deleted content
-                * is returned, then performs a redo to see if the content is 
correctly removed
-                * again.
-                */
-               public function joinedDeleteUndoTest():void
-               {
-                       var n:int = 10;
-                       SelManager.selectRange(10,10);
-
-                       var initLength:uint = SelManager.textFlow.textLength;
-
-                       for(var i:int = 0; i < n; i++){
-                               var event:KeyboardEvent = new 
KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 127, Keyboard.DELETE);
-                               dispatchEvent(event);
-                       }
-                       SelManager.flushPendingOperations();
-
-                       var endLength:uint = SelManager.textFlow.textLength;
-
-                       SelManager.undo();
-
-                       var undoLength:uint = SelManager.textFlow.textLength;
-
-                       assertTrue("expected text length before undo to be " + 
n + " less.  Was actually " +
-                                               (endLength - initLength) + " 
less.", endLength == initLength - n );
-                       assertTrue("expected text length after undo to be 
identical to the start, but it was off by " +
-                                               (undoLength-initLength), 
undoLength == initLength);
-
-                       Redo();
-
-                       var redoLength:uint = SelManager.textFlow.textLength;
-
-                       assertTrue("expected redo length to equal undo length, 
but found " +
-                                               redoLength + " and " + 
endLength, redoLength == endLength);
-               }
-
-               /**
-                * Places a series of letter a's in and does one undo to see if 
all the a's
-                * are removed, then performs a redo to see if they're returned.
-                */
-               public function joinedInsertUndoTest():void
-               {
-                       var n:int = 10;
-                       SelManager.selectRange(10,10);
-
-                       var initLength:uint = SelManager.textFlow.textLength;
-
-                       for(var i:int = 0; i < n; i++){
-                               var event:TextEvent = new 
TextEvent(TextEvent.TEXT_INPUT,false,false,"a");
-                               dispatchEvent(event);
-                       }
-
-                       SelManager.flushPendingOperations();
-
-                       var endLength:uint = SelManager.textFlow.textLength;
-
-                       SelManager.undo();
-
-                       var undoLength:uint = SelManager.textFlow.textLength;
-
-                       assertTrue("expected text length before undo to be " + 
n + " more.  Was actually " +
-                                               (endLength - initLength) + " 
less.", endLength == initLength + n );
-                       assertTrue("expected text length after undo to be 
identical to the start, but it was off by " +
-                                               (undoLength-initLength), 
undoLength == initLength);
-                       Redo();
-
-                       var redoLength:uint = SelManager.textFlow.textLength;
-
-                       assertTrue("expected redo length to equal undo length, 
but found " +
-                                               redoLength + " and " + 
endLength, redoLength == endLength);
-               }
-
-               /**
-                * Performs successive enters and one undo to see if all 
paragraph splits are
-                * undone, then performs a redo to see if they're all redone.
-                */
-               public function joinedSplitParagraphUndoTest():void
-               {
-                       var n:int = 10;
-                       SelManager.selectRange(10,10);
-
-                       var initLength:uint = SelManager.textFlow.textLength;
-
-                       for(var i:int = 0; i < n; i++){
-                               var event:KeyboardEvent = new 
KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 13);
-                               dispatchEvent(event);
-                       }
-
-                       var endLength:uint = SelManager.textFlow.textLength;
-
-                       SelManager.undo();
-
-                       var undoLength:uint = SelManager.textFlow.textLength;
-
-                       assertTrue("expected text length before undo to be " + 
n + " more.  Was actually " +
-                                               (endLength - initLength) + " 
less.", endLength == initLength + n );
-                       assertTrue("expected text length after undo to be 
identical to the start, but it was off by " +
-                                               (undoLength-initLength), 
undoLength == initLength);
-
-                       Redo();
-
-                       var redoLength:uint = SelManager.textFlow.textLength;
-
-                       assertTrue("expected redo length to equal undo length, 
but found " +
-                                               redoLength + " and " + 
endLength, redoLength == endLength);
-               }
-
-               /**
-                * Create a new undo manager with an undo limit of ten, then 
perform eleven
-                * undoable operations and see how many times it will let you 
undo.
-                */
-               public function undoLimitTest():void
-               {
-                       var undo:UndoManager = new UndoManager();
-                       var n:int = 10;
-                       undo.undoAndRedoItemLimit = n;
-
-                       var newSM:EditManager = new EditManager(undo);
-                       SelManager = newSM;
-                       TestFrame.rootElement.getTextFlow().interactionManager 
= newSM;
-
-                       //SelManager.selectRange(n,n);
-
-                       for(var i:int = 0; i < n + 1; i++){
-                               SelManager.selectRange(n,n+i);
-                               var event:KeyboardEvent = (i % 2 == 0) ?
-                                       new 
KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 13):
-                                       new 
KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 8);
-                               dispatchEvent(event);
-                               SelManager.selectRange(-1,-1);
-                       }
-
-                       var u:int = 0;
-                       while(undo.canUndo()){
-                               SelManager.undo();
-                               u++;
-                       }
-
-                       assertTrue("expected only " + n + " undos but found " + 
u, u == n);
-               }
-               
-               
-               public function undoRedoStackTest():void
-               {
-                       var undo:UndoManager = new UndoManager();
-                       var n:int = 10;
-                       undo.undoAndRedoItemLimit = n;
-                       
-                       var newSM:EditManager = new EditManager(undo);
-                       SelManager = newSM;
-                       TestFrame.rootElement.getTextFlow().interactionManager 
= newSM;
-                       
-                       //do n operations
-                       for(var i:int = 0; i < n + 1; i++){
-                               SelManager.selectRange(n,n+i);
-                               var event:KeyboardEvent = (i % 2 == 0) ?
-                                       new 
KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 13):
-                                       new 
KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 8);
-                               dispatchEvent(event);
-                               SelManager.selectRange(-1,-1);
-                       }
-                       var testManager:TestEditManager = new 
TestEditManager(undo);
-                       var stackItemNum:int = 
testManager.UndoRedoEntireStack(undo);
-
-                       assertTrue("expected only " + n + " undos but found " + 
stackItemNum, stackItemNum == n);
-               }
-
-               /**
-                * Select a section of text that spans paragraphs then delete 
it and see if the
-                * size of the flow goes down by the appropriate amount.
-                */
-               public function transParagraphDeleteTest():void
-               {
-                       var startLength:int = TestFrame.rootElement.textLength;
-
-                       var flow1:FlowElement;
-                       var flow2:FlowElement;
-
-                       var start:int = 0;
-                       var finish:int = 0;
-
-                       var origParas:int = TestFrame.rootElement.numChildren;
-
-                       //Look for two back to back paragraphs.
-                       for(var i:int = 0; i < 
TestFrame.rootElement.numChildren-1; i++){
-                               flow1 = TestFrame.rootElement.getChildAt(i);
-                               flow2 = TestFrame.rootElement.getChildAt(i+1);
-
-                               if(flow1 is ParagraphElement && flow2 is 
ParagraphElement){
-                                       finish = start + flow1.textLength + 
flow2.textLength/2;
-                                       start = start + flow1.textLength/2;
-                                       break;
-                               }else{
-                                       start = start + flow1.textLength;
-                               }
-                       }
-
-                       assertTrue("expected finish to be in the middle of the 
second para, but it's still 0", finish != 0);
-
-                       var para1:ParagraphElement = flow1 as ParagraphElement;
-                       var para2:ParagraphElement = flow2 as ParagraphElement;
-
-                       var attrib1:ITextLayoutFormat = para1.computedFormat;
-                       var pa:TextLayoutFormat = new TextLayoutFormat();
-                       if(attrib1.textAlign == TextAlign.CENTER)
-                               pa.textAlign = TextAlign.LEFT;
-                       else
-                               pa.textAlign = TextAlign.CENTER;
-
-
-                       
SelManager.selectRange(para2.getAbsoluteStart(),para2.getAbsoluteStart() + 1);
-
-                       SelManager.applyParagraphFormat(pa);
-
-                       var attrib2:ITextLayoutFormat = para2.computedFormat;
-                       assertTrue("para1 and para2 paraAttrs must be different 
for this test to work!",
-                               !TextLayoutFormat.isEqual(attrib1,attrib2)
-                       );
-
-                       SelManager.selectRange(start,finish);
-                       SelManager.deleteNextCharacter();
-                       var finishLength:int = TestFrame.rootElement.textLength;
-
-                       assertTrue("expected " + (finish-start) + " less 
characters but found " +
-                                               (startLength - finishLength) + 
" less", startLength - finishLength == finish - start);
-
-                       /*
-                        * TODO: this tests current behavior. Proper behavior 
would be only one
-                        * remaining paragraph.
-                        */
-
-                       assertTrue("number of paragraphs should have 
decreased!", origParas > TestFrame.rootElement.numChildren);
-
-                       var finalPara:ParagraphElement = 
TestFrame.rootElement.getChildAt(i) as ParagraphElement;
-                       var finalAttrs:ITextLayoutFormat = 
finalPara.computedFormat;
-
-                       assertTrue("paragraph attributes changed and should be 
the same!",TextLayoutFormat.isEqual(attrib1,finalAttrs));
-               }
-
-               /**
-                * Create an empty paragraph and select the 0 position in it.
-                * Then delete all the content on the flow and see if the 
position selected is 0.
-                */
-               public function emptyParagraphTest():void
-               {
-                       SelManager.selectRange(0,0);
-
-                       var returnevent:KeyboardEvent =
-                               new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, 
false, 13);
-                       dispatchEvent(returnevent);
-
-                       SelManager.selectRange(0,0);
-                       assertTrue("did not start with selection at 0,0", 
SelManager.anchorPosition == 0 && SelManager.activePosition == 0);
-                       SelManager.selectAll();
-                       SelManager.deleteNextCharacter();
-                       assertTrue("did not end with selection at 0,0 after 
delete all", SelManager.anchorPosition == 0 && SelManager.activePosition == 0);
-               }
-
-               public function splitUTF16Test():void
-               {
-                       // remove all text
-                       SelManager.selectAll();
-                       SelManager.deleteNextCharacter();
-
-                       var a:uint = 0xD866; var b:uint = 0xDDC1;
-                       var c:uint = 0xD869; var d:uint = 0xDED6;
-                       var e:uint = 0xD8BF; var f:uint = 0xDFFD;
-
-                       var y:String = String.fromCharCode(a,b,c,d,e,f);
-                       SelManager.insertText(y);
-                       SelManager.flushPendingOperations();
-
-                       var begin:int = 0;
-                       var end:int = SelManager.textFlow.textLength;
-                       var middle:int = ((end-1) - begin)/2;
-                       SelManager.selectRange(middle, middle);
-
-                       var gotRangeError:Boolean = false;
-                       try
-                       {
-                               SelManager.splitParagraph();
-                               SelManager.flushPendingOperations();
-                       }
-                       catch ( e:RangeError )
-                       {
-                               gotRangeError = true;
-                       }
-                       /* See bug #1798067 */
-                       assertTrue( "Spliting a surrogate pair did not throw an 
error", gotRangeError );
-
-                       SelManager.selectAll();
-
-                       var charAttr:TextLayoutFormat = new TextLayoutFormat();
-                       charAttr.fontFamily = "Adobe Song Std L";
-
-                       SelManager.applyLeafFormat(charAttr);
-                       SelManager.flushPendingOperations();
-
-                       //trace(begin + ", " + middle + ", " + end);
-               }
-
-               public function splitUTF32Test():void
-               {
-                       // remove all text
-                       SelManager.selectAll();
-                       SelManager.deleteNextCharacter();
-
-                       var y:String = String.fromCharCode(0x00028023);
-                       y = y + y + y;
-
-                       SelManager.insertText(y);
-                       SelManager.flushPendingOperations();
-
-                       var begin:int = 0;
-                       var end:int = SelManager.textFlow.textLength;
-                       var middle:int = ((end-1) - begin)/2;
-                       SelManager.selectRange(middle, middle);
-
-                       SelManager.splitParagraph();
-                       SelManager.flushPendingOperations();
-
-                       SelManager.selectAll();
-
-                       var charAttr:TextLayoutFormat = new TextLayoutFormat();
-                       charAttr.fontFamily = "Adobe Song Std L";
-
-                       SelManager.applyLeafFormat(charAttr);
-                       SelManager.flushPendingOperations();
-
-                       //trace(begin + ", " + middle + ", " + end);
-               }
-
-
-               // pick up the actual operation
-               private var flowOp:FlowOperation;
-
-               private function 
listenForOpBegin(opEvent:FlowOperationEvent):void
-               {
-                       flowOp = opEvent.operation;
-               }
-
-               /**
-                * Performs an operation, clear the selection manager and then 
make sure the operation doesn't undo
-                */
-               public function undoWithModelChangeTest():void
-               {
-                       var tf:TextFlow = SelManager.textFlow;
-                       var selManager:EditManager = SelManager;
-
-                       selManager.selectAll();
-
-                       var initLength:uint = SelManager.textFlow.textLength;
-
-
-                       flowOp = null;
-                       
tf.addEventListener(FlowOperationEvent.FLOW_OPERATION_BEGIN,listenForOpBegin,false,0,true);
-
-                       // now do an operation
-                       var ca:TextLayoutFormat = new TextLayoutFormat();
-                       ca.color = 0xff;
-                       selManager.applyFormatToElement(tf, ca);
-
-                       assertTrue("no begin operation event",flowOp != null);
-                       assertTrue("textFlow characterFormat.color should be 
0xff",tf.format && tf.format.color == 0xff);
-
-                       // clear the selection manager
-                       tf.interactionManager = null;
-                       // now I've got a hold of the operation.  do an out of 
bounds model modification and then attempt an undo
-                       tf.color = 0xff00;
-                       assertTrue("textFlow characterFormat.color should be 
0xff",tf.format.color == 0xff00);
-
-                       // now restore the interactionManager
-                       tf.interactionManager = selManager;
-                       // CONFIG::debug { 
trace("GeneralFunctionsTest.undoWithModelChangeTest: expect to see message 
regarding skipping undo due to mismatched generation numbers."); }
-                       // try to do an undo
-                       selManager.undo();
-
-                       // it should be skipped
-                       assertTrue("no begin operation event",flowOp != null);
-                       assertTrue("wrong begin operation event",flowOp is 
UndoOperation);
-                       assertTrue("textFlow characterFormat.color should be 
0xff00",tf.format && tf.format.color == 0xff00);
-
-                       selManager.selectRange(0,0);    // prevent assert in 
tearDown
-               }
-
-               private function Redo():void // KJT
-               {
-                       try {
-                               SelManager.redo();
-                       }
-                       catch(e:Error){
-                               fail("Redo operation failed.");
-                       }
-               }
-
-               private function dispatchEvent(event:Event):void
-               {
-                       // assume containers support dispatchEvent.  Otherwise 
we get an error
-                       TestFrame.container["dispatchEvent"](event);
-               }
-
-               public function doubleClickTest():void
-               {
-                       SelManager.selectRange( 68, 68 );
-                       var mEvent:MouseEvent = new MouseEvent( 
MouseEvent.DOUBLE_CLICK );
-                       TestFrame.container["dispatchEvent"](mEvent);
-
-                       assertTrue( "Double click failed to correctly select 
word",
-                                               SelManager.anchorPosition == 65 
&&
-                                               SelManager.activePosition == 72 
);
-
-                       SelManager.selectRange( 955, 955 );
-                       mEvent = new MouseEvent( MouseEvent.DOUBLE_CLICK );
-                       TestFrame.container["dispatchEvent"](mEvent);
-
-                       assertTrue( "Double click failed to correctly select 
word",
-                                               SelManager.anchorPosition == 
954 &&
-                                               SelManager.activePosition == 
957 );
-               }
-
-               public function doubleClickHyphenTest():void
-               {
-                       SelManager.selectRange( 24, 24 );
-                       var mEvent:MouseEvent = new MouseEvent( 
MouseEvent.DOUBLE_CLICK );
-                       TestFrame.container["dispatchEvent"](mEvent);
-
-                       assertTrue( "Double click failed on a hyphen",
-                                               SelManager.anchorPosition == 24 
&&
-                                               SelManager.activePosition == 25 
);
-
-                       SelManager.selectRange( 498, 498 );
-                       mEvent = new MouseEvent( MouseEvent.DOUBLE_CLICK );
-                       TestFrame.container["dispatchEvent"](mEvent);
-
-                       assertTrue( "Double click failed on a hyphenated word",
-                                               SelManager.anchorPosition == 
496 &&
-                                               SelManager.activePosition == 
502 );
-               }
-
-               public function doubleClickPunctuationTest():void
-               {
-                       SelManager.selectRange( 951, 951 );
-                       var mEvent:MouseEvent = new MouseEvent( 
MouseEvent.DOUBLE_CLICK );
-                       TestFrame.container["dispatchEvent"](mEvent);
-
-                       assertTrue( "Double click failed on a word next to 
punctuation",
-                                               SelManager.anchorPosition == 
945 &&
-                                               SelManager.activePosition == 
952 );
-
-                       SelManager.selectRange( 1964, 1964 );
-                       mEvent = new MouseEvent( MouseEvent.DOUBLE_CLICK );
-                       TestFrame.container["dispatchEvent"](mEvent);
-
-                       assertTrue( "Double click failed on punctuation",
-                                               SelManager.anchorPosition == 
1963 &&
-                                               SelManager.activePosition == 
1966 );
-               }
-
-               public function replaceChildrenFlowTest():void
-               {
-                       var caught:Boolean = false;
-
-                       try
-                       {
-                               SelManager.textFlow.replaceChildren( 0,0, new 
TextFlow() );
-                       }
-                       catch ( err:ArgumentError )
-                       {
-                               caught = true;
-                       }
-
-                       assertTrue( "TextFlow.replaceChildren with a TextFlow 
argument should throw an error", caught );
-               }
-               private function resolveInlines(ilg:InlineGraphicElement):Object
-               {
-                       return ilg.source == "placeholder" ? new Sprite() : 
ilg.source;
-               }
-
-               private var _ilgStatus:String;
-               private function 
graphicStatusChangeEvent(e:StatusChangeEvent):void
-               {
-                       _ilgStatus = e.status;
-               }
-
-               public function resolveInlinesTest():void
-               {
-                       var textFlow:TextFlow;
-                       const markup:String = "<flow:TextFlow 
xmlns:flow='http://ns.adobe.com/textLayout/2008'><flow:p><flow:img 
source='placeholder'/></flow:p></flow:TextFlow>";
-
-                       var config:Configuration = new Configuration();
-                       config.inlineGraphicResolverFunction = resolveInlines;
-                       textFlow = TextConverter.importToFlow(markup, 
TextConverter.TEXT_LAYOUT_FORMAT, config);
-
-                       
textFlow.addEventListener(StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE,graphicStatusChangeEvent);
-
-                       textFlow.flowComposer.addController(new 
ContainerController(new Sprite(), 400, 200));
-                       textFlow.flowComposer.updateAllControllers();
-
-                       assertTrue( "Inline Graphic resolution failed", 
_ilgStatus == InlineGraphicElementStatus.READY ); //
-
-               }
-
-               public function nestingTest():void
-               {
-                       var link1:LinkElement = new LinkElement();
-                       var tcy1:TCYElement = new TCYElement();
-                       var link2:LinkElement = new LinkElement();
-
-                       var exceptionThrown:Boolean = false;
-                       try
-                       {
-                               link1.addChild(link2);
-                       }
-                       catch (e:*)
-                       {
-                               exceptionThrown = true;
-                       }
-                       assertTrue("Should not be able to add a link child to a 
link", exceptionThrown);
-
-                       exceptionThrown = false;
-                       link1.addChild(tcy1);
-
-                       try
-                       {
-                               tcy1.addChild(link2);
-                       }
-                       catch (e:*)
-                       {
-                               exceptionThrown = true;
-                       }
-                       assertTrue("Should not be able to add a link child to a 
TCY if the latter is contained in a link", exceptionThrown);
-
-                       exceptionThrown = false;
-                       link1.removeChild (tcy1);
-                       tcy1.addChild(link2);
-
-                       try
-                       {
-                               link1.addChild(tcy1);
-                       }
-                       catch (e:*)
-                       {
-                               exceptionThrown = true;
-                       }
-                       assertTrue("Should not be able to add a TCY child to a 
link if the former contains a link", exceptionThrown);
-
-               }
-
-               private static const customResourceDict:Object = 
-               {
-                       invalidFlowElementConstruct_custom:     "Attempted 
construct of invalid FlowElement subclass",
-                       badMXMLChildrenArgument_custom: "Bad element of type 
{0} passed to mxmlChildren",
-                       malformedTag:   "Malformed tag </p/>",
-                       XMLParserFailure:       "TypeError: Error #1090: XML 
parser failure: element is malformed."
-               }
-               
-               tlf_internal static function 
customResourceStringFunction(resourceName:String, parameters:Array = 
null):String
-               {
-                       var value:String = 
String(customResourceDict[resourceName]);
-                       
-                       if (value == null)
-                       {
-                               value = 
String(customResourceDict["missingStringResource"]);
-                               parameters = [ resourceName ];
-                       }
-                       
-                       if (parameters)
-                               value = customSubstitute(value, parameters);
-                       
-                       return value;
-               }
-               
-               /** @private */
-               tlf_internal static function customSubstitute(str:String, ... 
rest):String
-               {
-                       if (str == null) 
-                               return '';
-                       
-                       // Replace all of the parameters in the msg string.
-                       var len:uint = rest.length;
-                       var args:Array;
-                       if (len == 1 && rest[0] is Array)
-                       {
-                               args = rest[0] as Array;
-                               len = args.length;
-                       }
-                       else
-                       {
-                               args = rest;
-                       }
-                       
-                       for (var i:int = 0; i < len; i++)
-                       {
-                               str = str.replace(new RegExp("\\{"+i+"\\}", 
"g"), args[i]);
-                       }
-                       
-                       return str;
-               }
-                       
-               /** Generate errors and make sure we get the right string */
-               public function errorThrowing():void
-               {
-                       var exceptionThrown:Boolean;
-                       
-                       //use defaultResourceStringFunction to check the error 
message
-                       // Invalid flowElement
-                       exceptionThrown = false;
-                       try
-                       {
-                               new FlowGroupElement();
-                       }
-                       catch (e:Error)
-                       {
-                               exceptionThrown = true;
-                               var invalidFlowElementConstruct_message:String 
= e.message;
-                               assertTrue("errorThrowing: Error thrown but 
message is incorrect",e.message == 
GlobalSettings.resourceStringFunction("invalidFlowElementConstruct"));
-                               
-                       }
-                       assertTrue("errorThrowing: Expected error on new 
FlowGroupElement did not occur", exceptionThrown);
-                       
-                       // invalid mxmlchildren assignment
-                       exceptionThrown = false;
-                       try
-                       {
-                               var s:Sprite = new Sprite();
-                               new DivElement().mxmlChildren = [ s ];
-                       }
-                       catch (e:Error)
-                       {
-                               exceptionThrown = true;
-                               var badMXMLChildrenArgument_message:String = 
e.message;
-                               assertTrue("errorThrowing: Error thrown but 
message is incorrect",e.message == 
GlobalSettings.resourceStringFunction("badMXMLChildrenArgument",[ 
getQualifiedClassName(s) ]));
-                       }
-                       assertTrue("errorThrowing: Expected error on bad 
MXMLChildren argument did not occur", exceptionThrown);
-                       
-                       //use customResourceStringFunction to check the error 
message
-                       try
-                       {
-                               GlobalSettings.resourceStringFunction= 
customResourceStringFunction;
-                               
-                               //check Invalid flowElement and invalid 
mxmlchildren assignment
-                               assertTrue("errorThrowing: Error thrown but 
message is incorrect", 
GlobalSettings.resourceStringFunction("invalidFlowElementConstruct_custom") == 
invalidFlowElementConstruct_message);
-                               assertTrue("errorThrowing: Error thrown but 
message is incorrect", 
GlobalSettings.resourceStringFunction("badMXMLChildrenArgument_custom",[ 
getQualifiedClassName(s) ]) == badMXMLChildrenArgument_message);
-                               
-                               //use custom resource string function to test 
HTML importer error
-                               exceptionThrown = false;
-                               var textImporter:ITextImporter = 
TextConverter.getImporter(TextConverter.TEXT_FIELD_HTML_FORMAT);
-                               var textFlow:TextFlow;
-                               
-                               var markup:String = '<p>Malformed tag 
next</p/>';
-                               textFlow = textImporter.importToFlow(markup);
-                               
-                               if (textImporter.errors)
-                               {
-                                       exceptionThrown = true;
-                                       assertTrue("errorThrowing: Error thrown 
but message is incorrect",textImporter.errors == 
GlobalSettings.resourceStringFunction("malformedTag"));
-                               }
-                               assertTrue("errorThrowing: Expected error on 
importer did not occur", exceptionThrown);
-                               
-                               //use custom resource string function to test 
Text importer error
-                               exceptionThrown = false;
-                               markup = "<TextFlow columnCount='inherit'" 
-                                       + "<span>Ethan 
Brand</span></a></p></TextFlow>";
-                               
-                       textImporter = 
TextConverter.getImporter(TextConverter.TEXT_LAYOUT_FORMAT);
-                               textFlow = textImporter.importToFlow(markup);
-                       
-                               if (textImporter.errors)
-                               {
-                                       exceptionThrown = true;
-                                       assertTrue("errorThrowing: Error thrown 
but message is incorrect",textImporter.errors == 
GlobalSettings.resourceStringFunction("XMLParserFailure"));
-                               }
-                               assertTrue("errorThrowing: Expected error on 
XML Parser Failure did not occur", exceptionThrown);
-                       }
-                       finally
-                       {
-                               GlobalSettings.resourceStringFunction = 
GlobalSettings.defaultResourceStringFunction;
-                       }
-               
-               }
-               
-               public static const childParentTable:Array = 
-               [
-                       [ "child\parent",                       TextFlow,       
DivElement, ParagraphElement, LinkElement, TCYElement, SpanElement, 
InlineGraphicElement, BreakElement, TabElement, ListElement, ListItemElement, 
SubParagraphGroupElement ],
-                       [ TextFlow,                                     "no",   
        "no",           "no",                           "no",           "no",   
        "no",                   "no",                           "no",           
        "no",           "no",           "no",                   "no" ],
-                       [ DivElement,                           "yes",          
"yes",          "no",                           "no",           "no",           
"no",                   "no",                           "no",                   
"no",           "yes",          "yes",                  "no" ],
-                       [ ParagraphElement,                     "yes",          
"yes",          "no",                           "no",           "no",           
"no",                   "no",                           "no",                   
"no",           "yes",          "yes",                  "no" ],
-                       [ LinkElement,                          "no",           
"no",           "yes",                          "no",           "yes",          
"no",                   "no",                           "no",                   
"no",           "no",           "no",                   "yes" ],
-                       [ TCYElement,                           "no",           
"no",           "yes",                          "yes",          "no",           
"no",                   "no",                           "no",                   
"no",           "no",           "no",                   "yes" ],
-                       [ SpanElement,                          "no",           
"no",           "yes",                          "yes",          "yes",          
"no",                   "no",                           "no",                   
"no",           "no",           "no",                   "yes" ],
-                       [ InlineGraphicElement,         "no",           "no",   
        "yes",                          "yes",          "yes",          "no",   
                "no",                           "no",                   "no",   
        "no",           "no",                   "yes" ],
-                       [ BreakElement,                         "no",           
"no",           "yes",                          "yes",          "yes",          
"no",                   "no",                           "no",                   
"no",           "no",           "no",                   "yes" ],
-                       [ TabElement,                           "no",           
"no",           "yes",                          "yes",          "yes",          
"no",                   "no",                           "no",                   
"no",           "no",           "no",                   "yes" ],
-                       [ ListElement,                          "yes",          
"yes",          "no",                           "no",           "no",           
"no",                   "no",                           "no",                   
"no",           "yes",          "yes",                  "no" ],
-                       [ ListItemElement,                      "no",           
"no",           "no",                           "no",           "no",           
"no",                   "no",                           "no",                   
"no",           "yes",          "no",                   "no" ],
-                       [ SubParagraphGroupElement,     "no",           "no",   
        "yes",                          "yes",          "yes",          "no",   
                "no",                           "no",                   "no",   
        "no",           "no",                   "yes" ]
-               ];
-               
-               /** Using above table for permitted child/parent relationships 
verify that canOwnFlowElement matches the table. */
-               public function AllNestingTest():void
-               {                       
-                       var parentRow:Array = childParentTable[0].slice(1);
-                       var childRow:Array;
-                       var childClassName:String;
-                       var childClass:Class;
-                       
-                       for each (childRow in childParentTable.slice(1))
-                       {
-                               childClassName = "flashx.textLayout.elements." 
+ childRow[0];
-                               childClass = childRow[0] as Class;
-                               var childElement:FlowElement = new childClass 
as FlowElement;
-                               assertTrue(childElement.defaultTypeName != 
null,"Bad defaultTypeName in " + childClassName);
-
-                               childRow = childRow.slice(1);
-                               for (var idx:int = 0; idx < childRow.length; 
idx++)
-                               {
-                                       var parentClass:Class = parentRow[idx] 
as Class
-                                       var parentElement:FlowElement = new 
parentClass as FlowElement;
-                                       
-                                       // 
trace(parentClass.toString(),childClass.toString(),childRow[idx]);
-                                       
-                                       if (parentElement is FlowGroupElement)
-                                       {
-                                               if 
(FlowGroupElement(parentElement).canOwnFlowElement(childElement))
-                                                       assertTrue("Bad 
canOwnFlowElement value for expected allowed "+parentClass.toString()+" 
"+childClass.toString(),childRow[idx] == "yes");
-                                               else
-                                                       assertTrue("Bad 
canOwnFlowElement value for expected not allowed "+parentClass.toString()+" 
"+childClass.toString(), childRow[idx] == "no");
-                                       }
-                                       else 
-                                               assertTrue("Bad 
canOwnFlowElement value for a non FlowGroupElement parent 
"+parentClass.toString()+" "+childClass.toString(),childRow[idx] == "no");
-                               }
-                       }
-                       
-                       // Check for indirect nesting of 
SubParagraphGroupElements
-                       var textFlow:TextFlow = new TextFlow();
-                       var paragraph:ParagraphElement = new ParagraphElement();
-                       textFlow.replaceChildren(0, 0, paragraph);
-                       var parentGroup:SubParagraphGroupElement = new 
SubParagraphGroupElement();
-                       paragraph.replaceChildren(0, 0, parentGroup);
-                       for each (childRow in childParentTable.slice(1))
-                       {
-                               childClassName = "flashx.textLayout.elements." 
+ childRow[0];
-                               childClass = childRow[0] as Class;
-                               var 
spgeChildElement:SubParagraphGroupElementBase = new childClass as 
SubParagraphGroupElementBase;
-                               if (spgeChildElement)
-                               {
-                                       var 
groupElement:SubParagraphGroupElement = new SubParagraphGroupElement();
-                                       groupElement.replaceChildren(0, 0, new 
SubParagraphGroupElement());
-
-                                       groupElement.replaceChildren(0, 0, 
spgeChildElement);
-                                       
-                                       assertTrue 
(parentGroup.canOwnFlowElement(groupElement), "Expected this nesting to work");
-                                       
-                                       if (!spgeChildElement.allowNesting)
-                                       {
-                                               var 
nestingParent:SubParagraphGroupElementBase = new childClass as 
SubParagraphGroupElementBase;
-                                               
parentGroup.replaceChildren(parentGroup.numChildren, parentGroup.numChildren, 
nestingParent);
-                                               var 
nestingGroup:SubParagraphGroupElement = new SubParagraphGroupElement();
-                                               
nestingParent.replaceChildren(nestingParent.numChildren, 
nestingParent.numChildren, nestingGroup);
-                                               assertTrue("Expected this 
nesting to fail because of nesting of Link or TCY", 
!nestingGroup.canOwnFlowElement(groupElement));
-                                       }
-                               }
-                       }
-               }
-       }
+            for (var i:int = 0; i < n; i++)
+            {
+                var event:TextEvent = new TextEvent(TextEvent.TEXT_INPUT, 
false, false, "a");
+                dispatchEvent(event);
+            }
+
+            SelManager.flushPendingOperations();
+
+            var endLength:uint = SelManager.textFlow.textLength;
+
+            SelManager.undo();
+
+            var undoLength:uint = SelManager.textFlow.textLength;
+
+            assertTrue("expected text length before undo to be " + n + " more. 
 Was actually " +
+                    (endLength - initLength) + " less.", endLength == 
initLength + n);
+            assertTrue("expected text length after undo to be identical to the 
start, but it was off by " +
+                    (undoLength - initLength), undoLength == initLength);
+            Redo();
+
+            var redoLength:uint = SelManager.textFlow.textLength;
+
+            assertTrue("expected redo length to equal undo length, but found " 
+
+                    redoLength + " and " + endLength, redoLength == endLength);
+        }
+
+        [Test]
+        /**
+         * Performs successive enters and one undo to see if all paragraph 
splits are
+         * undone, then performs a redo to see if they're all redone.
+         */
+        public function joinedSplitParagraphUndoTest():void
+        {
+            var n:int = 10;
+            SelManager.selectRange(10, 10);
+
+            var initLength:uint = SelManager.textFlow.textLength;
+
+            for (var i:int = 0; i < n; i++)
+            {
+                var event:KeyboardEvent = new 
KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 13);
+                dispatchEvent(event);
+            }
+
+            var endLength:uint = SelManager.textFlow.textLength;
+
+            SelManager.undo();
+
+            var undoLength:uint = SelManager.textFlow.textLength;
+
+            assertTrue("expected text length before undo to be " + n + " more. 
 Was actually " +
+                    (endLength - initLength) + " less.", endLength == 
initLength + n);
+            assertTrue("expected text length after undo to be identical to the 
start, but it was off by " +
+                    (undoLength - initLength), undoLength == initLength);
+
+            Redo();
+
+            var redoLength:uint = SelManager.textFlow.textLength;
+
+            assertTrue("expected redo length to equal undo length, but found " 
+
+                    redoLength + " and " + endLength, redoLength == endLength);
+        }
+
+        [Test]
+        /**
+         * Create a new undo manager with an undo limit of ten, then perform 
eleven
+         * undoable operations and see how many times it will let you undo.
+         */
+        public function undoLimitTest():void
+        {
+            var undo:UndoManager = new UndoManager();
+            var n:int = 10;
+            undo.undoAndRedoItemLimit = n;
+
+            var newSM:EditManager = new EditManager(undo);
+            SelManager = newSM;
+            TestFrame.rootElement.getTextFlow().interactionManager = newSM;
+
+            //SelManager.selectRange(n,n);
+
+            for (var i:int = 0; i < n + 1; i++)
+            {
+                SelManager.selectRange(n, n + i);
+                var event:KeyboardEvent = (i % 2 == 0) ?
+                        new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 
13) :
+                        new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 
8);
+                dispatchEvent(event);
+                SelManager.selectRange(-1, -1);
+            }
+
+            var u:int = 0;
+            while (undo.canUndo())
+            {
+                SelManager.undo();
+                u++;
+            }
+
+            assertTrue("expected only " + n + " undos but found " + u, u == n);
+        }
+
+        [Test]
+        public function undoRedoStackTest():void
+        {
+            var undo:UndoManager = new UndoManager();
+            var n:int = 10;
+            undo.undoAndRedoItemLimit = n;
+
+            var newSM:EditManager = new EditManager(undo);
+            SelManager = newSM;
+            TestFrame.rootElement.getTextFlow().interactionManager = newSM;
+
+            //do n operations
+            for (var i:int = 0; i < n + 1; i++)
+            {
+                SelManager.selectRange(n, n + i);
+                var event:KeyboardEvent = (i % 2 == 0) ?
+                        new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 
13) :
+                        new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 
8);
+                dispatchEvent(event);
+                SelManager.selectRange(-1, -1);
+            }
+            var testManager:TestEditManager = new TestEditManager(undo);
+            var stackItemNum:int = testManager.UndoRedoEntireStack(undo);
+
+            assertTrue("expected only " + n + " undos but found " + 
stackItemNum, stackItemNum == n);
+        }
+
+        [Test]
+        /**
+         * Select a section of text that spans paragraphs then delete it and 
see if the
+         * size of the flow goes down by the appropriate amount.
+         */
+        public function transParagraphDeleteTest():void
+        {
+            var startLength:int = TestFrame.rootElement.textLength;
+
+            var flow1:FlowElement;
+            var flow2:FlowElement;
+
+            var start:int = 0;
+            var finish:int = 0;
+
+            var origParas:int = TestFrame.rootElement.numChildren;
+
+            //Look for two back to back paragraphs.
+            for (var i:int = 0; i < TestFrame.rootElement.numChildren - 1; i++)
+            {
+                flow1 = TestFrame.rootElement.getChildAt(i);
+                flow2 = TestFrame.rootElement.getChildAt(i + 1);
+
+                if (flow1 is ParagraphElement && flow2 is ParagraphElement)
+                {
+                    finish = start + flow1.textLength + flow2.textLength / 2;
+                    start = start + flow1.textLength / 2;
+                    break;
+                } else
+                {
+                    start = start + flow1.textLength;
+                }
+            }
+
+            assertTrue("expected finish to be in the middle of the second 
para, but it's still 0", finish != 0);
+
+            var para1:ParagraphElement = flow1 as ParagraphElement;
+            var para2:ParagraphElement = flow2 as ParagraphElement;
+
+            var attrib1:ITextLayoutFormat = para1.computedFormat;
+            var pa:TextLayoutFormat = new TextLayoutFormat();
+            if (attrib1.textAlign == TextAlign.CENTER)
+                pa.textAlign = TextAlign.LEFT;
+            else
+                pa.textAlign = TextAlign.CENTER;
+
+
+            SelManager.selectRange(para2.getAbsoluteStart(), 
para2.getAbsoluteStart() + 1);
+
+            SelManager.applyParagraphFormat(pa);
+
+            var attrib2:ITextLayoutFormat = para2.computedFormat;
+            assertTrue("para1 and para2 paraAttrs must be different for this 
test to work!",
+                    !TextLayoutFormat.isEqual(attrib1, attrib2)
+            );
+
+            SelManager.selectRange(start, finish);
+            SelManager.deleteNextCharacter();
+            var finishLength:int = TestFrame.rootElement.textLength;
+
+            assertTrue("expected " + (finish - start) + " less characters but 
found " +
+                    (startLength - finishLength) + " less", startLength - 
finishLength == finish - start);
+
+            /*
+             * TODO: this tests current behavior. Proper behavior would be 
only one
+             * remaining paragraph.
+             */
+
+            assertTrue("number of paragraphs should have decreased!", 
origParas > TestFrame.rootElement.numChildren);
+
+            var finalPara:ParagraphElement = 
TestFrame.rootElement.getChildAt(i) as ParagraphElement;
+            var finalAttrs:ITextLayoutFormat = finalPara.computedFormat;
+
+            assertTrue("paragraph attributes changed and should be the same!", 
TextLayoutFormat.isEqual(attrib1, finalAttrs));
+        }
+
+        [Test]
+        /**
+         * Create an empty paragraph and select the 0 position in it.
+         * Then delete all the content on the flow and see if the position 
selected is 0.
+         */
+        public function emptyParagraphTest():void
+        {
+            SelManager.selectRange(0, 0);
+
+            var returnevent:KeyboardEvent =
+                    new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 13);
+            dispatchEvent(returnevent);
+
+            SelManager.selectRange(0, 0);
+            assertTrue("did not start with selection at 0,0", 
SelManager.anchorPosition == 0 && SelManager.activePosition == 0);
+            SelManager.selectAll();
+            SelManager.deleteNextCharacter();
+            assertTrue("did not end with selection at 0,0 after delete all", 
SelManager.anchorPosition == 0 && SelManager.activePosition == 0);
+        }
+
+        [Test]
+        public function splitUTF16Test():void
+        {
+            // remove all text
+            SelManager.selectAll();
+            SelManager.deleteNextCharacter();
+
+            var a:uint = 0xD866;
+            var b:uint = 0xDDC1;
+            var c:uint = 0xD869;
+            var d:uint = 0xDED6;
+            var e:uint = 0xD8BF;
+            var f:uint = 0xDFFD;
+
+            var y:String = String.fromCharCode(a, b, c, d, e, f);
+            SelManager.insertText(y);
+            SelManager.flushPendingOperations();
+
+            var begin:int = 0;
+            var end:int = SelManager.textFlow.textLength;
+            var middle:int = ((end - 1) - begin) / 2;
+            SelManager.selectRange(middle, middle);
+
+            var gotRangeError:Boolean = false;
+            try
+            {
+                SelManager.splitParagraph();
+                SelManager.flushPendingOperations();
+            }
+            catch (e:RangeError)
+            {
+                gotRangeError = true;
+            }
+            /* See bug #1798067 */
+            assertTrue("Spliting a surrogate pair did not throw an error", 
gotRangeError);
+
+            SelManager.selectAll();
+
+            var charAttr:TextLayoutFormat = new TextLayoutFormat();
+            charAttr.fontFamily = "Adobe Song Std L";
+
+            SelManager.applyLeafFormat(charAttr);
+            SelManager.flushPendingOperations();
+
+            //trace(begin + ", " + middle + ", " + end);
+        }
+
+        [Test]
+        public function splitUTF32Test():void
+        {
+            // remove all text
+            SelManager.selectAll();
+            SelManager.deleteNextCharacter();
+
+            var y:String = String.fromCharCode(0x00028023);
+            y = y + y + y;
+
+            SelManager.insertText(y);
+            SelManager.flushPendingOperations();
+
+            var begin:int = 0;
+            var end:int = SelManager.textFlow.textLength;
+            var middle:int = ((end - 1) - begin) / 2;
+            SelManager.selectRange(middle, middle);
+
+            SelManager.splitParagraph();
+            SelManager.flushPendingOperations();
+
+            SelManager.selectAll();
+
+            var charAttr:TextLayoutFormat = new TextLayoutFormat();
+            charAttr.fontFamily = "Adobe Song Std L";
+
+            SelManager.applyLeafFormat(charAttr);
+            SelManager.flushPendingOperations();
+
+            //trace(begin + ", " + middle + ", " + end);
+        }
+
+        [Test]
+        /**
+         * Performs an operation, clear the selection manager and then make 
sure the operation doesn't undo
+         */
+        public function undoWithModelChangeTest():void
+        {
+            var tf:TextFlow = SelManager.textFlow;
+            var selManager:EditManager = SelManager;
+
+            selManager.selectAll();
+
+            var initLength:uint = SelManager.textFlow.textLength;
+
+
+            flowOp = null;
+            tf.addEventListener(FlowOperationEvent.FLOW_OPERATION_BEGIN, 
listenForOpBegin, false, 0, true);
+
+            // now do an operation
+            var ca:TextLayoutFormat = new TextLayoutFormat();
+            ca.color = 0xff;
+            selManager.applyFormatToElement(tf, ca);
+
+            assertTrue("no begin operation event", flowOp != null);
+            assertTrue("textFlow characterFormat.color should be 0xff", 
tf.format && tf.format.color == 0xff);
+
+            // clear the selection manager
+            tf.interactionManager = null;
+            // now I've got a hold of the operation.  do an out of bounds 
model modification and then attempt an undo
+            tf.color = 0xff00;
+            assertTrue("textFlow characterFormat.color should be 0xff", 
tf.format.color == 0xff00);
+
+            // now restore the interactionManager
+            tf.interactionManager = selManager;
+            // CONFIG::debug { 
trace("GeneralFunctionsTest.undoWithModelChangeTest: expect to see message 
regarding skipping undo due to mismatched generation numbers."); }
+            // try to do an undo
+            selManager.undo();
+
+            // it should be skipped
+            assertTrue("no begin operation event", flowOp != null);
+            assertTrue("wrong begin operation event", flowOp is UndoOperation);
+            assertTrue("textFlow characterFormat.color should be 0xff00", 
tf.format && tf.format.color == 0xff00);
+
+            selManager.selectRange(0, 0);      // prevent assert in tearDown
+        }
+
+        [Test]
+        public function doubleClickTest():void
+        {
+            SelManager.selectRange(68, 68);
+            var mEvent:MouseEvent = new MouseEve

<TRUNCATED>

Reply via email to