diff --git a/automation_tests/src/AllTestsSuite.as b/automation_tests/src/AllTestsSuite.as
index 26e9d42..6464036 100644
--- a/automation_tests/src/AllTestsSuite.as
+++ b/automation_tests/src/AllTestsSuite.as
@@ -41,6 +41,7 @@
     import UnitTest.Tests.ImpliedParagraphTest;
     import UnitTest.Tests.ImportAPITest;
     import UnitTest.Tests.KeyboardGestureTest;
+    import UnitTest.Tests.LeadingTest;
     import UnitTest.Tests.LinkTest;
     import UnitTest.Tests.ListTest;
     import UnitTest.Tests.LocaleTests;
@@ -106,6 +107,7 @@
         public var selectionTest:SelectionTest;
         public var paragraphTest:ParagraphTest;
         public var measurementTest:MeasurementTest;
+        public var leadingTest:LeadingTest;
     }
 
 }
diff --git a/automation_tests/src/UnitTest/Tests/LeadingTest.as b/automation_tests/src/UnitTest/Tests/LeadingTest.as
index 5221386..9ec796a 100644
--- a/automation_tests/src/UnitTest/Tests/LeadingTest.as
+++ b/automation_tests/src/UnitTest/Tests/LeadingTest.as
@@ -18,1168 +18,1150 @@
 ////////////////////////////////////////////////////////////////////////////////
 package UnitTest.Tests
 {
-	import UnitTest.ExtendedClasses.TestDescriptor;
-	import UnitTest.ExtendedClasses.TestSuiteExtended;
-	import UnitTest.ExtendedClasses.VellumTestCase;
-	import UnitTest.Fixtures.TestConfig;
-	
-	import flash.display.Bitmap;
-	import flash.display.BitmapData;
-	import flash.display.DisplayObject;
-	import flash.display.DisplayObjectContainer;
-	import flash.display.IBitmapDrawable;
-	import flash.geom.Point;
-	import flash.text.engine.TextBaseline;
-	import flash.text.engine.TextBlock;
-	import flash.text.engine.TextLine;
-	import flash.text.engine.TextLineCreationResult;
-	import flash.utils.ByteArray;
-	
-	import flashx.textLayout.compose.IFlowComposer;
-	import flashx.textLayout.compose.TextFlowLine;
-	import flashx.textLayout.container.ContainerController;
-	import flashx.textLayout.conversion.ConversionType;
-	import flashx.textLayout.conversion.TextConverter;
-	import flashx.textLayout.elements.TextFlow;
-	import flashx.textLayout.formats.BaselineOffset;
-	import flashx.textLayout.formats.BlockProgression;
-	import flashx.textLayout.formats.JustificationRule;
-	import flashx.textLayout.formats.LeadingModel;
-	import flashx.textLayout.formats.TextLayoutFormat;
-	import flashx.textLayout.tlf_internal;
-	
-	import mx.core.UIComponent;
-	import mx.utils.LoaderUtil;
+    import UnitTest.ExtendedClasses.VellumTestCase;
+    import UnitTest.Fixtures.TestConfig;
+
+    import flash.display.BitmapData;
+    import flash.display.DisplayObjectContainer;
+
+    import flashx.textLayout.compose.IFlowComposer;
+    import flashx.textLayout.compose.TextFlowLine;
+    import flashx.textLayout.container.ContainerController;
+    import flashx.textLayout.elements.TextFlow;
+    import flashx.textLayout.formats.BlockProgression;
+    import flashx.textLayout.formats.JustificationRule;
+    import flashx.textLayout.formats.LeadingModel;
+    import flashx.textLayout.formats.TextLayoutFormat;
+    import flashx.textLayout.tlf_internal;
+
+    import mx.utils.LoaderUtil;
 
     import org.flexunit.asserts.assertTrue;
 
     use namespace tlf_internal;
 
-	public class LeadingTest extends VellumTestCase
-	{
-		public static var diffTolerance:Number = 0.001;
+    [TestCase(order=42)]
+    public class LeadingTest extends VellumTestCase
+    {
+        public static var diffTolerance:Number = 0.001;
 
-		public function LeadingTest(methodName:String, testID:String, testConfig:TestConfig, testXML:XML = null)
-		{
-			super(methodName, testID, testConfig);
+        public function LeadingTest()
+        {
+            super("", "LeadingTest", TestConfig.getInstance());
 
-			// Note: These must correspond to a Watson product area (case-sensitive)
-			metaData.productArea = "Text Composition";
-		}
+            metaData = {};
+            // Note: These must correspond to a Watson product area (case-sensitive)
+            metaData.productArea = "Text Composition";
+        }
 
-		public static function suite(testConfig:TestConfig, ts:TestSuiteExtended):void
-		{
-			ts.addTestDescriptor (new TestDescriptor (LeadingTest, "verifyRomanDefaultsTest", testConfig ) );
-			ts.addTestDescriptor (new TestDescriptor (LeadingTest, "verifyAsianDefaultsTest", testConfig ) );
-			ts.addTestDescriptor (new TestDescriptor (LeadingTest, "textFieldStyleLeadingTest", testConfig ) );
-			ts.addTestDescriptor (new TestDescriptor (LeadingTest, "ascentFromRomanTest", testConfig ) );
-			ts.addTestDescriptor (new TestDescriptor (LeadingTest, "descentFromRomanTest", testConfig ) );
-			ts.addTestDescriptor (new TestDescriptor (LeadingTest, "ideoTopFromIdeoCenterTest", testConfig ) );
-			ts.addTestDescriptor (new TestDescriptor (LeadingTest, "ideoBottomFromIdeoCenterTest", testConfig ) );
-			ts.addTestDescriptor (new TestDescriptor (LeadingTest, "eastAFirstBaselineOffsetTest", testConfig ) );
-			ts.addTestDescriptor (new TestDescriptor (LeadingTest, "spaceFirstBaselineOffsetTest", testConfig ) );
-			ts.addTestDescriptor (new TestDescriptor (LeadingTest, "topFBOColumnTest", testConfig ) );
-			ts.addTestDescriptor (new TestDescriptor (LeadingTest, "bottomFBOColumnTest", testConfig ) );
-			ts.addTestDescriptor (new TestDescriptor (LeadingTest, "ascentFBOColumnTest", testConfig ) );
-			ts.addTestDescriptor (new TestDescriptor (LeadingTest, "romanFBOColumnTest", testConfig ) );
-			ts.addTestDescriptor (new TestDescriptor (LeadingTest, "descentFBOColumnTest", testConfig ) );
-			ts.addTestDescriptor (new TestDescriptor (LeadingTest, "checkUpDownParagraphBoundryTest", testConfig) );
-			ts.addTestDescriptor (new TestDescriptor (LeadingTest, "checkDownUpParagraphBoundryTest", testConfig) );
-			ts.addTestDescriptor (new TestDescriptor (LeadingTest, "inlineGraphicWithFBOTest", testConfig) );
-		}
+        [Before]
+        override public function setUpTest():void
+        {
+            super.setUpTest();
+        }
 
-		public function verifyRomanDefaultsTest():void
-		{
-			var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonCharacterFormat());
-			cf.fontFamily = "Times New Roman";
+        [After]
+        override public function tearDownTest():void
+        {
+            super.tearDownTest();
+        }
 
-			var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.locale = "en";
-			pf.leadingModel = LeadingModel.AUTO;
+        [Test]
+        public function verifyRomanDefaultsTest():void
+        {
+            var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonCharacterFormat());
+            cf.fontFamily = "Times New Roman";
 
-			SelManager.selectAll();
-			SelManager.applyLeafFormat(cf);
-			SelManager.applyParagraphFormat(pf);
-			SelManager.flushPendingOperations();
+            var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.locale = "en";
+            pf.leadingModel = LeadingModel.AUTO;
 
-			var data1:BitmapData = getData();
+            SelManager.selectAll();
+            SelManager.applyLeafFormat(cf);
+            SelManager.applyParagraphFormat(pf);
+            SelManager.flushPendingOperations();
 
-			pf = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.locale = "en";
-			pf.leadingModel = LeadingModel.ROMAN_UP;
+            var data1:BitmapData = getData();
 
-			SelManager.applyParagraphFormat(pf);
-			SelManager.flushPendingOperations();
+            pf = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.locale = "en";
+            pf.leadingModel = LeadingModel.ROMAN_UP;
 
-			var data2:BitmapData = getData();
+            SelManager.applyParagraphFormat(pf);
+            SelManager.flushPendingOperations();
 
-			assertTrue("Changing to explicit default values changed image.",
-				compareData(data1,data2)
-			);
-		}
+            var data2:BitmapData = getData();
 
-		public function verifyAsianDefaultsTest():void
-		{
-			var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonCharacterFormat());
-			cf.fontFamily = "Times New Roman";
+            assertTrue("Changing to explicit default values changed image.",
+                    compareData(data1, data2)
+            );
+        }
 
-			var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.locale = "ja";
-			pf.leadingModel = LeadingModel.AUTO;
+        [Test]
+        public function verifyAsianDefaultsTest():void
+        {
+            var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonCharacterFormat());
+            cf.fontFamily = "Times New Roman";
 
-			SelManager.selectAll();
-			SelManager.applyLeafFormat(cf);
-			SelManager.applyParagraphFormat(pf);
-			SelManager.flushPendingOperations();
+            var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.locale = "ja";
+            pf.leadingModel = LeadingModel.AUTO;
 
-			var data1:BitmapData = getData();
+            SelManager.selectAll();
+            SelManager.applyLeafFormat(cf);
+            SelManager.applyParagraphFormat(pf);
+            SelManager.flushPendingOperations();
 
-			pf = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.locale = "ja";
-			pf.leadingModel = LeadingModel.IDEOGRAPHIC_TOP_DOWN;
+            var data1:BitmapData = getData();
 
-			SelManager.applyParagraphFormat(pf);
-			SelManager.flushPendingOperations();
+            pf = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.locale = "ja";
+            pf.leadingModel = LeadingModel.IDEOGRAPHIC_TOP_DOWN;
 
-			var data2:BitmapData = getData();
+            SelManager.applyParagraphFormat(pf);
+            SelManager.flushPendingOperations();
 
-			assertTrue("Changing to explicit default values changed image.",
-				compareData(data1,data2)
-			);
-		}
+            var data2:BitmapData = getData();
 
-		public function textFieldStyleLeadingTest():void
-		{
-			var textFlow:TextFlow = SelManager.textFlow;
+            assertTrue("Changing to explicit default values changed image.",
+                    compareData(data1, data2)
+            );
+        }
 
-			textFlow.paddingTop = 0;
-			textFlow.paddingBottom = 0;
-			textFlow.paddingLeft = 0;
-			textFlow.paddingRight = 0;
+        [Test]
+        public function textFieldStyleLeadingTest():void
+        {
+            var textFlow:TextFlow = SelManager.textFlow;
 
-			var cf:TextLayoutFormat = new TextLayoutFormat();
-			cf.paddingTop = cf.paddingBottom = cf.paddingLeft = cf.paddingRight = 0;
-			cf.columnCount = 1;
+            textFlow.paddingTop = 0;
+            textFlow.paddingBottom = 0;
+            textFlow.paddingLeft = 0;
+            textFlow.paddingRight = 0;
 
-			var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.leadingModel = LeadingModel.ASCENT_DESCENT_UP;
-			pf.paragraphSpaceBefore = pf.paragraphSpaceAfter = 0; pf.paragraphStartIndent = 0; pf.paragraphEndIndent = 0;
+            var cf:TextLayoutFormat = new TextLayoutFormat();
+            cf.paddingTop = cf.paddingBottom = cf.paddingLeft = cf.paddingRight = 0;
+            cf.columnCount = 1;
 
-			var lf:TextLayoutFormat = new TextLayoutFormat();
-			lf.lineHeight = 0;
+            var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.leadingModel = LeadingModel.ASCENT_DESCENT_UP;
+            pf.paragraphSpaceBefore = pf.paragraphSpaceAfter = 0;
+            pf.paragraphStartIndent = 0;
+            pf.paragraphEndIndent = 0;
 
-			SelManager.selectAll();
-			SelManager.applyFormat(lf, pf, cf);
-			SelManager.flushPendingOperations();
+            var lf:TextLayoutFormat = new TextLayoutFormat();
+            lf.lineHeight = 0;
 
-			var composer:IFlowComposer =  SelManager.textFlow.flowComposer;
-			composer.composeToPosition(); // ensure everything is composed regardless of what's visible
+            SelManager.selectAll();
+            SelManager.applyFormat(lf, pf, cf);
+            SelManager.flushPendingOperations();
 
-			var cumulativeTextHeight:Number = 0;
-			for (var i:int=0; i<composer.numLines; i++)
-			{
-				var line:TextFlowLine = composer.getLineAt(i);
-				cumulativeTextHeight += line.textHeight;
-			}
+            var composer:IFlowComposer = SelManager.textFlow.flowComposer;
+            composer.composeToPosition(); // ensure everything is composed regardless of what's visible
 
-			var cumulativeContentHeight:Number = 0;
-			for (i=0; i<composer.numControllers; i++)
-			{
-				var controller:ContainerController = composer.getControllerAt(i);
-				cumulativeContentHeight += textFlow.computedFormat.blockProgression == BlockProgression.TB ? controller.contentHeight : controller.contentWidth;
-			}
+            var cumulativeTextHeight:Number = 0;
+            for (var i:int = 0; i < composer.numLines; i++)
+            {
+                var line:TextFlowLine = composer.getLineAt(i);
+                cumulativeTextHeight += line.textHeight;
+            }
 
-			assertTrue("Lines set solid by using lineHeight=0 and leadingModel=ascentDescentUp. Yet, cumulative content height does not equal cumulative text height.",
-				cumulativeTextHeight == cumulativeContentHeight);
-		}
+            var cumulativeContentHeight:Number = 0;
+            for (i = 0; i < composer.numControllers; i++)
+            {
+                var controller:ContainerController = composer.getControllerAt(i);
+                cumulativeContentHeight += textFlow.computedFormat.blockProgression == BlockProgression.TB ? controller.contentHeight : controller.contentWidth;
+            }
 
-		public function ascentFromRomanTest():void
-		{
-			SelManager.selectRange(SelManager.absoluteStart,SelManager.absoluteEnd);
+            assertTrue("Lines set solid by using lineHeight=0 and leadingModel=ascentDescentUp. Yet, cumulative content height does not equal cumulative text height.",
+                    cumulativeTextHeight == cumulativeContentHeight);
+        }
 
-			var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
-			cf.paddingTop = 0;
-			cf.paddingRight = 0;
-			/*cf.firstBaselineOffset = 0;
-			cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.ASCENT;
-			(firstBaselineOffsetBasis no longer supported; using following equivlent)*/
-			cf.firstBaselineOffset = "auto";
+        [Test]
+        public function ascentFromRomanTest():void
+        {
+            SelManager.selectRange(SelManager.absoluteStart, SelManager.absoluteEnd);
 
-			SelManager.applyContainerFormat(cf);
-			SelManager.applyFormatToElement(SelManager.textFlow,cf);
+            var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
+            cf.paddingTop = 0;
+            cf.paddingRight = 0;
+            /*cf.firstBaselineOffset = 0;
+             cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.ASCENT;
+             (firstBaselineOffsetBasis no longer supported; using following equivlent)*/
+            cf.firstBaselineOffset = "auto";
 
-			var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.justificationRule = JustificationRule.SPACE;
-			pf.leadingModel = LeadingModel.ROMAN_UP;
+            SelManager.applyContainerFormat(cf);
+            SelManager.applyFormatToElement(SelManager.textFlow, cf);
 
-			SelManager.applyParagraphFormat(pf);
-			SelManager.textFlow.flowComposer.updateAllControllers();
+            var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.justificationRule = JustificationRule.SPACE;
+            pf.leadingModel = LeadingModel.ROMAN_UP;
 
-			var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            SelManager.applyParagraphFormat(pf);
+            SelManager.textFlow.flowComposer.updateAllControllers();
 
-			SelManager.selectRange(firstLine.textLength,firstLine.textLength);
-			SelManager.splitParagraph();
+            var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
 
-			firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
-			var nextLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(1);
+            SelManager.selectRange(firstLine.textLength, firstLine.textLength);
+            SelManager.splitParagraph();
 
-			assertTrue("There is only one line in the paragraph!", nextLine != null);
+            firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            var nextLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(1);
 
-			var flStats:Array = new Array(
-				firstLine.ascent,
-				firstLine.height,
-				firstLine.descent,
-				firstLine.x,
-				firstLine.y
-			);
-			var slStats:Array = new Array(
-				nextLine.ascent,
-				nextLine.height,
-				nextLine.descent,
-				nextLine.x,
-				nextLine.y
-			);
-			assertTrue("FBO and/or padding not correctly set!",
-				SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
-					flStats[4] == 0 :
-					flStats[3] == -flStats[0]
-			);
-			assertTrue("First and second lines do not share leading values!",
-				flStats[0] == slStats[0] && flStats[2] == slStats[2]
-			);
-		}
+            assertTrue("There is only one line in the paragraph!", nextLine != null);
 
-		public function descentFromRomanTest():void
-		{
-			SelManager.selectRange(SelManager.absoluteStart,SelManager.absoluteEnd);
+            var flStats:Array = [
+                firstLine.ascent,
+                firstLine.height,
+                firstLine.descent,
+                firstLine.x,
+                firstLine.y];
 
-			var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
-			cf.paddingTop = 0;
-			cf.paddingRight = 0;
-			cf.firstBaselineOffset = 0;
-			/*cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.DESCENT;
-			(firstBaselineOffsetBasis no longer supported; using following equivlent)*/
-			cf.locale = "ja";
+            var slStats:Array = [
+                nextLine.ascent,
+                nextLine.height,
+                nextLine.descent,
+                nextLine.x,
+                nextLine.y];
 
-			SelManager.applyContainerFormat(cf);
-			SelManager.applyFormatToElement(SelManager.textFlow,cf);
+            assertTrue("FBO and/or padding not correctly set!",
+                    SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
+                    flStats[4] == 0 :
+                    flStats[3] == -flStats[0]
+            );
+            assertTrue("First and second lines do not share leading values!",
+                    flStats[0] == slStats[0] && flStats[2] == slStats[2]
+            );
+        }
 
-			var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.justificationRule = JustificationRule.SPACE;
-			pf.leadingModel = LeadingModel.ROMAN_UP;
+        [Test]
+        public function descentFromRomanTest():void
+        {
+            SelManager.selectRange(SelManager.absoluteStart, SelManager.absoluteEnd);
 
-			SelManager.applyParagraphFormat(pf);
-			SelManager.textFlow.flowComposer.updateAllControllers();
+            var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
+            cf.paddingTop = 0;
+            cf.paddingRight = 0;
+            cf.firstBaselineOffset = 0;
+            /*cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.DESCENT;
+             (firstBaselineOffsetBasis no longer supported; using following equivlent)*/
+            cf.locale = "ja";
 
-			var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            SelManager.applyContainerFormat(cf);
+            SelManager.applyFormatToElement(SelManager.textFlow, cf);
 
-			SelManager.selectRange(firstLine.textLength,firstLine.textLength);
-			SelManager.splitParagraph();
+            var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.justificationRule = JustificationRule.SPACE;
+            pf.leadingModel = LeadingModel.ROMAN_UP;
 
-			firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
-			var nextLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(1);
+            SelManager.applyParagraphFormat(pf);
+            SelManager.textFlow.flowComposer.updateAllControllers();
 
-			assertTrue("There is only one line in the paragraph!", nextLine != null);
+            var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
 
-			var flStats:Array = new Array(
-				firstLine.ascent,
-				firstLine.height,
-				firstLine.descent,
-				firstLine.x,
-				firstLine.y
-			);
-			var slStats:Array = new Array(
-				nextLine.ascent,
-				nextLine.height,
-				nextLine.descent,
-				nextLine.x,
-				nextLine.y
-			);
-			assertTrue("FBO and/or padding not correctly set!",
-				SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
-					flStats[4] == -(flStats[0] + flStats[2]) :
-					flStats[3] == flStats[2]
-			);
-			assertTrue("First and second lines do not share leading values!",
-				flStats[0] == slStats[0] && flStats[2] == slStats[2]
-			);
-		}
+            SelManager.selectRange(firstLine.textLength, firstLine.textLength);
+            SelManager.splitParagraph();
 
-		public function ideoTopFromIdeoCenterTest():void
-		{
-			SelManager.selectRange(SelManager.absoluteStart,SelManager.absoluteEnd);
+            firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            var nextLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(1);
 
-			var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
-			cf.paddingTop = 0;
-			cf.paddingRight = 0;
-			/*cf.firstBaselineOffset = 0;
-			cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.IDEOGRAPHIC_TOP;
-			(firstBaselineOffsetBasis no longer supported; using following equivlent)*/
-			cf.firstBaselineOffset = "auto";
+            assertTrue("There is only one line in the paragraph!", nextLine != null);
 
-			SelManager.applyContainerFormat(cf);
-			SelManager.applyFormatToElement(SelManager.textFlow,cf);
+            var flStats:Array = [
+                firstLine.ascent,
+                firstLine.height,
+                firstLine.descent,
+                firstLine.x,
+                firstLine.y
+            ];
+            var slStats:Array = [
+                nextLine.ascent,
+                nextLine.height,
+                nextLine.descent,
+                nextLine.x,
+                nextLine.y
+            ];
+            assertTrue("FBO and/or padding not correctly set!",
+                    SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
+                    flStats[4] == -(flStats[0] + flStats[2]) :
+                    flStats[3] == flStats[2]
+            );
+            assertTrue("First and second lines do not share leading values!",
+                    flStats[0] == slStats[0] && flStats[2] == slStats[2]
+            );
+        }
 
-			var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.justificationRule = JustificationRule.EAST_ASIAN;
-			pf.leadingModel = LeadingModel.IDEOGRAPHIC_CENTER_DOWN;
+        [Test]
+        public function ideoTopFromIdeoCenterTest():void
+        {
+            SelManager.selectRange(SelManager.absoluteStart, SelManager.absoluteEnd);
 
-			SelManager.applyParagraphFormat(pf);
-			SelManager.textFlow.flowComposer.updateAllControllers();
+            var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
+            cf.paddingTop = 0;
+            cf.paddingRight = 0;
+            /*cf.firstBaselineOffset = 0;
+             cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.IDEOGRAPHIC_TOP;
+             (firstBaselineOffsetBasis no longer supported; using following equivlent)*/
+            cf.firstBaselineOffset = "auto";
 
-			var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            SelManager.applyContainerFormat(cf);
+            SelManager.applyFormatToElement(SelManager.textFlow, cf);
 
-			SelManager.selectRange(firstLine.textLength,firstLine.textLength);
-			SelManager.splitParagraph();
-			
-			var startIndex:int = SelManager.absoluteStart;
-			var endIndex:int = SelManager.absoluteEnd;
-			
-			SelManager.undo();
-			SelManager.redo();
-			
-			SelManager.selectRange(startIndex, endIndex);
+            var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.justificationRule = JustificationRule.EAST_ASIAN;
+            pf.leadingModel = LeadingModel.IDEOGRAPHIC_CENTER_DOWN;
 
-			firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
-			var nextLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(1);
+            SelManager.applyParagraphFormat(pf);
+            SelManager.textFlow.flowComposer.updateAllControllers();
 
-			assertTrue("There is only one line in the paragraph!", nextLine != null);
+            var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
 
-			var flStats:Array = new Array(
-				firstLine.ascent,
-				firstLine.height,
-				firstLine.descent,
-				firstLine.x,
-				firstLine.y
-			);
-			var slStats:Array = new Array(
-				nextLine.ascent,
-				nextLine.height,
-				nextLine.descent,
-				nextLine.x,
-				nextLine.y
-			);
-			assertTrue("FBO and/or padding not correctly set!",
-				SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
-					flStats[4] == 0 :
-					flStats[3] == -flStats[2]
-			);
-			assertTrue("First and second lines do not share leading values!",
-				flStats[0] == slStats[0] && flStats[2] == slStats[2]
-			);
+            SelManager.selectRange(firstLine.textLength, firstLine.textLength);
+            SelManager.splitParagraph();
 
-			pf = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.justificationRule = JustificationRule.EAST_ASIAN;
-			pf.leadingModel = LeadingModel.IDEOGRAPHIC_TOP_DOWN;
+            var startIndex:int = SelManager.absoluteStart;
+            var endIndex:int = SelManager.absoluteEnd;
 
-			SelManager.applyParagraphFormat(pf);
-			SelManager.textFlow.flowComposer.updateAllControllers();
+            SelManager.undo();
+            SelManager.redo();
 
-			firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
-			nextLine = SelManager.textFlow.flowComposer.getLineAt(1);
+            SelManager.selectRange(startIndex, endIndex);
 
-			assertTrue("There is only one line in the paragraph!", nextLine != null);
+            firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            var nextLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(1);
 
-			flStats = new Array(
-				firstLine.ascent,
-				firstLine.height,
-				firstLine.descent,
-				firstLine.x,
-				firstLine.y
-			);
-			slStats = new Array(
-				nextLine.ascent,
-				nextLine.height,
-				nextLine.descent,
-				nextLine.x,
-				nextLine.y
-			);
+            assertTrue("There is only one line in the paragraph!", nextLine != null);
 
-			assertTrue("FBO and/or padding not correctly set!",
-				SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
-					flStats[4] == 0 :
-					flStats[3] == -flStats[2]
-			);
-			assertTrue("Second line does not have the correct leading!",
-				slStats[0] == flStats[0] - flStats[2] &&
-				slStats[2] == flStats[0] + flStats[2]
-			);
-		}
+            var flStats:Array = [
+                firstLine.ascent,
+                firstLine.height,
+                firstLine.descent,
+                firstLine.x,
+                firstLine.y
+            ];
+            var slStats:Array = [
+                nextLine.ascent,
+                nextLine.height,
+                nextLine.descent,
+                nextLine.x,
+                nextLine.y
+            ];
+            assertTrue("FBO and/or padding not correctly set!",
+                    SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
+                    flStats[4] == 0 :
+                    flStats[3] == -flStats[2]
+            );
+            assertTrue("First and second lines do not share leading values!",
+                    flStats[0] == slStats[0] && flStats[2] == slStats[2]
+            );
 
-		public function ideoBottomFromIdeoCenterTest():void
-		{
-			SelManager.selectRange(SelManager.absoluteStart,SelManager.absoluteEnd);
+            pf = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.justificationRule = JustificationRule.EAST_ASIAN;
+            pf.leadingModel = LeadingModel.IDEOGRAPHIC_TOP_DOWN;
 
-			var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
-			cf.paddingTop = 0;
-			cf.paddingRight = 0;
-			/*cf.firstBaselineOffset = 0;
-			cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.IDEOGRAPHIC_TOP;
-			(firstBaselineOffsetBasis no longer supported; using following equivlent)*/
-			cf.firstBaselineOffset = "auto";
+            SelManager.applyParagraphFormat(pf);
+            SelManager.textFlow.flowComposer.updateAllControllers();
 
-			SelManager.applyContainerFormat(cf);
-			SelManager.applyFormatToElement(SelManager.textFlow,cf);
+            firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            nextLine = SelManager.textFlow.flowComposer.getLineAt(1);
 
-			var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.justificationRule = JustificationRule.EAST_ASIAN;
-			pf.leadingModel = LeadingModel.IDEOGRAPHIC_CENTER_DOWN;
+            assertTrue("There is only one line in the paragraph!", nextLine != null);
 
-			SelManager.applyParagraphFormat(pf);
-			SelManager.textFlow.flowComposer.updateAllControllers();
+            flStats = [
+                firstLine.ascent,
+                firstLine.height,
+                firstLine.descent,
+                firstLine.x,
+                firstLine.y
+            ];
+            slStats = [
+                nextLine.ascent,
+                nextLine.height,
+                nextLine.descent,
+                nextLine.x,
+                nextLine.y
+            ];
 
-			var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            assertTrue("FBO and/or padding not correctly set!",
+                    SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
+                    flStats[4] == 0 :
+                    flStats[3] == -flStats[2]
+            );
+            assertTrue("Second line does not have the correct leading!",
+                    slStats[0] == flStats[0] - flStats[2] &&
+                    slStats[2] == flStats[0] + flStats[2]
+            );
+        }
 
-			SelManager.selectRange(firstLine.textLength,firstLine.textLength);
-			SelManager.splitParagraph();
+        [Test]
+        public function ideoBottomFromIdeoCenterTest():void
+        {
+            SelManager.selectRange(SelManager.absoluteStart, SelManager.absoluteEnd);
 
-			firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
-			var nextLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(1);
+            var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
+            cf.paddingTop = 0;
+            cf.paddingRight = 0;
+            /*cf.firstBaselineOffset = 0;
+             cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.IDEOGRAPHIC_TOP;
+             (firstBaselineOffsetBasis no longer supported; using following equivlent)*/
+            cf.firstBaselineOffset = "auto";
 
-			assertTrue("There is only one line in the paragraph!", nextLine != null);
+            SelManager.applyContainerFormat(cf);
+            SelManager.applyFormatToElement(SelManager.textFlow, cf);
 
-			var flStats:Array = new Array(
-				firstLine.ascent,
-				firstLine.height,
-				firstLine.descent,
-				firstLine.x,
-				firstLine.y
-			);
-			var slStats:Array = new Array(
-				nextLine.ascent,
-				nextLine.height,
-				nextLine.descent,
-				nextLine.x,
-				nextLine.y
-			);
-			assertTrue("FBO and/or padding not correctly set!",
-				SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
-					flStats[4] == 0 :
-					flStats[3] == -(flStats[2])
-			);
-			assertTrue("First and second lines do not share leading values!",
-				flStats[0] == slStats[0] && flStats[2] == slStats[2]
-			);
-		}
+            var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.justificationRule = JustificationRule.EAST_ASIAN;
+            pf.leadingModel = LeadingModel.IDEOGRAPHIC_CENTER_DOWN;
 
-		public function eastAFirstBaselineOffsetTest():void
-		{
-			SelManager.selectRange(SelManager.absoluteStart,SelManager.absoluteEnd);
+            SelManager.applyParagraphFormat(pf);
+            SelManager.textFlow.flowComposer.updateAllControllers();
 
-			var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
-			cf.paddingTop = 0;
-			cf.paddingRight = 0;
-			/*cf.firstBaselineOffset = 0;
-			cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.IDEOGRAPHIC_TOP;
-			(firstBaselineOffsetBasis no longer supported; using following equivlent)*/
-			cf.firstBaselineOffset = "auto";
+            var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
 
-			SelManager.applyContainerFormat(cf);
-			SelManager.applyFormatToElement(SelManager.textFlow,cf);
+            SelManager.selectRange(firstLine.textLength, firstLine.textLength);
+            SelManager.splitParagraph();
 
-			var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.justificationRule = JustificationRule.EAST_ASIAN;
-			pf.leadingModel = LeadingModel.IDEOGRAPHIC_CENTER_DOWN;
+            firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            var nextLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(1);
 
-			SelManager.applyParagraphFormat(pf);
-			SelManager.textFlow.flowComposer.updateAllControllers();
+            assertTrue("There is only one line in the paragraph!", nextLine != null);
 
-			var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            var flStats:Array = [
+                firstLine.ascent,
+                firstLine.height,
+                firstLine.descent,
+                firstLine.x,
+                firstLine.y
+            ];
+            var slStats:Array = [
+                nextLine.ascent,
+                nextLine.height,
+                nextLine.descent,
+                nextLine.x,
+                nextLine.y
+            ];
+            assertTrue("FBO and/or padding not correctly set!",
+                    SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
+                    flStats[4] == 0 :
+                    flStats[3] == -(flStats[2])
+            );
+            assertTrue("First and second lines do not share leading values!",
+                    flStats[0] == slStats[0] && flStats[2] == slStats[2]
+            );
+        }
 
-			SelManager.selectRange(firstLine.textLength,SelManager.absoluteEnd);
-			SelManager.deleteText();
+        [Test]
+        public function eastAFirstBaselineOffsetTest():void
+        {
+            SelManager.selectRange(SelManager.absoluteStart, SelManager.absoluteEnd);
 
-			firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
+            cf.paddingTop = 0;
+            cf.paddingRight = 0;
+            /*cf.firstBaselineOffset = 0;
+             cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.IDEOGRAPHIC_TOP;
+             (firstBaselineOffsetBasis no longer supported; using following equivlent)*/
+            cf.firstBaselineOffset = "auto";
 
-			var flStats:Array = new Array(
-				firstLine.ascent,
-				firstLine.height,
-				firstLine.descent,
-				firstLine.x,
-				firstLine.y
-			);
+            SelManager.applyContainerFormat(cf);
+            SelManager.applyFormatToElement(SelManager.textFlow, cf);
 
-			assertTrue("Height not equal to ascent!",flStats[0] == flStats[1]);
-			assertTrue("Position not equal to height minus ascent!",
-				SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
-					flStats[4] == flStats[1] - flStats[0] :
-					flStats[3] == -(flStats[1])
-			);
+            var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.justificationRule = JustificationRule.EAST_ASIAN;
+            pf.leadingModel = LeadingModel.IDEOGRAPHIC_CENTER_DOWN;
 
-			cf = new TextLayoutFormat(SelManager.getCommonContainerFormat());
-			cf.paddingTop = 0;
-			cf.paddingRight = 0;
-			/*cf.firstBaselineOffset = 0;
-			cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.IDEOGRAPHIC_CENTER;
-			(firstBaselineOffsetBasis no longer supported; using following equivlent)*/
-			cf.firstBaselineOffset = firstLine.textHeight/2;
-			cf.locale = "ja";
+            SelManager.applyParagraphFormat(pf);
+            SelManager.textFlow.flowComposer.updateAllControllers();
 
-			SelManager.applyContainerFormat(cf);
-			SelManager.textFlow.flowComposer.updateAllControllers();
+            var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
 
-			firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            SelManager.selectRange(firstLine.textLength, SelManager.absoluteEnd);
+            SelManager.deleteText();
 
-			flStats = new Array(
-				firstLine.ascent,
-				firstLine.height,
-				firstLine.descent,
-				firstLine.x,
-				firstLine.y
-			);
+            firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
 
-			assertTrue("Height not equal to zero!",flStats[1] == 0);
-			assertTrue("Position not equal to height minus ascent!",
-				SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
-					flStats[4] == flStats[1] - flStats[0] :
-					flStats[3] == -(flStats[1])
-			);
+            var flStats:Array = [
+                firstLine.ascent,
+                firstLine.height,
+                firstLine.descent,
+                firstLine.x,
+                firstLine.y
+            ];
 
-			cf = new TextLayoutFormat(SelManager.getCommonContainerFormat());
-			cf.paddingTop = 0;
-			cf.paddingRight = 0;
-			cf.firstBaselineOffset = 0;
-			/*cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.IDEOGRAPHIC_BOTTOM;
-			(firstBaselineOffsetBasis no longer supported; using following equivlent)*/
-			cf.locale = "ja";
+            assertTrue("Height not equal to ascent!", flStats[0] == flStats[1]);
+            assertTrue("Position not equal to height minus ascent!",
+                    SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
+                    flStats[4] == flStats[1] - flStats[0] :
+                    flStats[3] == -(flStats[1])
+            );
 
-			SelManager.applyContainerFormat(cf);
-			SelManager.textFlow.flowComposer.updateAllControllers();
+            cf = new TextLayoutFormat(SelManager.getCommonContainerFormat());
+            cf.paddingTop = 0;
+            cf.paddingRight = 0;
+            /*cf.firstBaselineOffset = 0;
+             cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.IDEOGRAPHIC_CENTER;
+             (firstBaselineOffsetBasis no longer supported; using following equivlent)*/
+            cf.firstBaselineOffset = firstLine.textHeight / 2;
+            cf.locale = "ja";
 
-			firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            SelManager.applyContainerFormat(cf);
+            SelManager.textFlow.flowComposer.updateAllControllers();
 
-			flStats = new Array(
-				firstLine.ascent,
-				firstLine.height,
-				firstLine.descent,
-				firstLine.x,
-				firstLine.y
-			);
+            firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
 
-			assertTrue("Height not equal to negative descent!",flStats[1] == -(flStats[2]));
-			assertTrue("Position not equal to height minus ascent!",
-				SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
-					flStats[4] == flStats[1] - flStats[0] :
-					flStats[3] == -(flStats[1])
-			);
-		}
+            flStats = [
+                firstLine.ascent,
+                firstLine.height,
+                firstLine.descent,
+                firstLine.x,
+                firstLine.y
+            ];
 
-		public function spaceFirstBaselineOffsetTest():void
-		{
-			SelManager.selectRange(SelManager.absoluteStart,SelManager.absoluteEnd);
+            assertTrue("Height not equal to zero!", flStats[1] == 0);
+            assertTrue("Position not equal to height minus ascent!",
+                    SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
+                    flStats[4] == flStats[1] - flStats[0] :
+                    flStats[3] == -(flStats[1])
+            );
 
-			var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
-			cf.paddingTop = 0;
-			cf.paddingRight = 0;
-			/*cf.firstBaselineOffset = 0;
-			cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.ASCENT;
-			(firstBaselineOffsetBasis no longer supported; using following equivlent)*/
-			cf.firstBaselineOffset = "auto";
+            cf = new TextLayoutFormat(SelManager.getCommonContainerFormat());
+            cf.paddingTop = 0;
+            cf.paddingRight = 0;
+            cf.firstBaselineOffset = 0;
+            /*cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.IDEOGRAPHIC_BOTTOM;
+             (firstBaselineOffsetBasis no longer supported; using following equivlent)*/
+            cf.locale = "ja";
 
-			SelManager.applyContainerFormat(cf);
-			SelManager.applyFormatToElement(SelManager.textFlow,cf);
+            SelManager.applyContainerFormat(cf);
+            SelManager.textFlow.flowComposer.updateAllControllers();
 
-			var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.justificationRule = JustificationRule.SPACE;
-			pf.leadingModel = LeadingModel.ROMAN_UP;
+            firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
 
-			SelManager.applyParagraphFormat(pf);
-			SelManager.textFlow.flowComposer.updateAllControllers();
+            flStats = [
+                firstLine.ascent,
+                firstLine.height,
+                firstLine.descent,
+                firstLine.x,
+                firstLine.y
+            ];
 
-			var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            assertTrue("Height not equal to negative descent!", flStats[1] == -(flStats[2]));
+            assertTrue("Position not equal to height minus ascent!",
+                    SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
+                    flStats[4] == flStats[1] - flStats[0] :
+                    flStats[3] == -(flStats[1])
+            );
+        }
 
-			SelManager.selectRange(firstLine.textLength,SelManager.absoluteEnd);
-			SelManager.deleteText();
+        [Test]
+        public function spaceFirstBaselineOffsetTest():void
+        {
+            SelManager.selectRange(SelManager.absoluteStart, SelManager.absoluteEnd);
 
-			firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
+            cf.paddingTop = 0;
+            cf.paddingRight = 0;
+            /*cf.firstBaselineOffset = 0;
+             cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.ASCENT;
+             (firstBaselineOffsetBasis no longer supported; using following equivlent)*/
+            cf.firstBaselineOffset = "auto";
 
-			var flStats:Array = new Array(
-				firstLine.ascent,
-				firstLine.height,
-				firstLine.descent,
-				firstLine.x,
-				firstLine.y
-			);
+            SelManager.applyContainerFormat(cf);
+            SelManager.applyFormatToElement(SelManager.textFlow, cf);
 
-			assertTrue("Height not equal to ascent!",flStats[0] == flStats[1]);
-			assertTrue("Position not equal to height minus ascent!",
-				SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
-					flStats[4] == flStats[1] - flStats[0] :
-					flStats[3] == -(flStats[1])
-			);
+            var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.justificationRule = JustificationRule.SPACE;
+            pf.leadingModel = LeadingModel.ROMAN_UP;
 
-			cf = new TextLayoutFormat(SelManager.getCommonContainerFormat());
-			cf.paddingTop = 0;
-			cf.paddingRight = 0;
-			cf.firstBaselineOffset = 0;
-			/*cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.ROMAN;
-			(firstBaselineOffsetBasis no longer supported; using following equivlent)*/
-			cf.locale = "en"; // not really needed since this is the default
+            SelManager.applyParagraphFormat(pf);
+            SelManager.textFlow.flowComposer.updateAllControllers();
 
-			SelManager.applyContainerFormat(cf);
-			SelManager.textFlow.flowComposer.updateAllControllers();
+            var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
 
-			firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            SelManager.selectRange(firstLine.textLength, SelManager.absoluteEnd);
+            SelManager.deleteText();
 
-			flStats = new Array(
-				firstLine.ascent,
-				firstLine.height,
-				firstLine.descent,
-				firstLine.x,
-				firstLine.y
-			);
+            firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
+
+            var flStats:Array = [
+                firstLine.ascent,
+                firstLine.height,
+                firstLine.descent,
+                firstLine.x,
+                firstLine.y
+            ];
+
+            assertTrue("Height not equal to ascent!", flStats[0] == flStats[1]);
+            assertTrue("Position not equal to height minus ascent!",
+                    SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
+                    flStats[4] == flStats[1] - flStats[0] :
+                    flStats[3] == -(flStats[1])
+            );
+
+            cf = new TextLayoutFormat(SelManager.getCommonContainerFormat());
+            cf.paddingTop = 0;
+            cf.paddingRight = 0;
+            cf.firstBaselineOffset = 0;
+            /*cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.ROMAN;
+             (firstBaselineOffsetBasis no longer supported; using following equivlent)*/
+            cf.locale = "en"; // not really needed since this is the default
+
+            SelManager.applyContainerFormat(cf);
+            SelManager.textFlow.flowComposer.updateAllControllers();
+
+            firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
+
+            flStats = [
+                firstLine.ascent,
+                firstLine.height,
+                firstLine.descent,
+                firstLine.x,
+                firstLine.y
+            ];
 
-			assertTrue("Height not equal to zero!",flStats[1] == 0);
-			assertTrue("Position not equal to height minus ascent!",
-				SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
-					flStats[4] == flStats[1] - flStats[0] :
-					flStats[3] == -(flStats[1])
-			);
+            assertTrue("Height not equal to zero!", flStats[1] == 0);
+            assertTrue("Position not equal to height minus ascent!",
+                    SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
+                    flStats[4] == flStats[1] - flStats[0] :
+                    flStats[3] == -(flStats[1])
+            );
 
-			cf = new TextLayoutFormat(SelManager.getCommonContainerFormat());
-			cf.paddingTop = 0;
-			cf.paddingRight = 0;
-			cf.firstBaselineOffset = 0;
-			/*cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.DESCENT;
-			(firstBaselineOffsetBasis no longer supported; using following equivlent)*/
-			cf.locale = "ja";
+            cf = new TextLayoutFormat(SelManager.getCommonContainerFormat());
+            cf.paddingTop = 0;
+            cf.paddingRight = 0;
+            cf.firstBaselineOffset = 0;
+            /*cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.DESCENT;
+             (firstBaselineOffsetBasis no longer supported; using following equivlent)*/
+            cf.locale = "ja";
 
-			SelManager.applyContainerFormat(cf);
-			SelManager.textFlow.flowComposer.updateAllControllers();
+            SelManager.applyContainerFormat(cf);
+            SelManager.textFlow.flowComposer.updateAllControllers();
 
-			firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
 
-			flStats = new Array(
-				firstLine.ascent,
-				firstLine.height,
-				firstLine.descent,
-				firstLine.x,
-				firstLine.y
-			);
+            flStats = [
+                firstLine.ascent,
+                firstLine.height,
+                firstLine.descent,
+                firstLine.x,
+                firstLine.y
+            ];
 
-			assertTrue("Height not equal to negative descent!",flStats[1] == -(flStats[2]));
-			assertTrue("Position not equal to height minus ascent!",
-				SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
-					flStats[4] == flStats[1] - flStats[0] :
-					flStats[3] == -(flStats[1])
-			);
-		}
+            assertTrue("Height not equal to negative descent!", flStats[1] == -(flStats[2]));
+            assertTrue("Position not equal to height minus ascent!",
+                    SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
+                    flStats[4] == flStats[1] - flStats[0] :
+                    flStats[3] == -(flStats[1])
+            );
+        }
 
-		public function topFBOColumnTest():void
-		{
-			var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
-			cf.paddingTop = 0;
-			cf.paddingRight = 0;
-			cf.columnCount = 2;
-			/*cf.firstBaselineOffset = 0;
-			cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.IDEOGRAPHIC_TOP;
-			(firstBaselineOffsetBasis no longer supported; using following equivlent)*/
-			cf.firstBaselineOffset = "auto";
+        [Test]
+        public function topFBOColumnTest():void
+        {
+            var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
+            cf.paddingTop = 0;
+            cf.paddingRight = 0;
+            cf.columnCount = 2;
+            /*cf.firstBaselineOffset = 0;
+             cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.IDEOGRAPHIC_TOP;
+             (firstBaselineOffsetBasis no longer supported; using following equivlent)*/
+            cf.firstBaselineOffset = "auto";
 
-			SelManager.applyContainerFormat(cf);
-			SelManager.applyFormatToElement(SelManager.textFlow,cf);
+            SelManager.applyContainerFormat(cf);
+            SelManager.applyFormatToElement(SelManager.textFlow, cf);
 
-			var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.justificationRule = JustificationRule.EAST_ASIAN;
-			pf.leadingModel = LeadingModel.AUTO;
+            var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.justificationRule = JustificationRule.EAST_ASIAN;
+            pf.leadingModel = LeadingModel.AUTO;
 
-			SelManager.selectAll();
-			SelManager.applyParagraphFormat(pf);
-			SelManager.textFlow.flowComposer.updateAllControllers();
+            SelManager.selectAll();
+            SelManager.applyParagraphFormat(pf);
+            SelManager.textFlow.flowComposer.updateAllControllers();
 
-			var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
-			var nextLine:TextFlowLine;
+            var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            var nextLine:TextFlowLine;
 
-			for(var i:int = 0; i < SelManager.textFlow.flowComposer.numLines; i++){
-				nextLine = SelManager.textFlow.flowComposer.getLineAt(i);
+            for (var i:int = 0; i < SelManager.textFlow.flowComposer.numLines; i++)
+            {
+                nextLine = SelManager.textFlow.flowComposer.getLineAt(i);
 
-				if(nextLine.columnIndex == 1){
-					break;
-				}else{
-					nextLine = null;
-				}
-			}
+                if (nextLine.columnIndex == 1)
+                {
+                    break;
+                } else
+                {
+                    nextLine = null;
+                }
+            }
 
-			assertTrue("Could not find a line in the second column!", nextLine != null);
+            assertTrue("Could not find a line in the second column!", nextLine != null);
 
-			var f:Array = new Array(
-				firstLine.ascent,
-				firstLine.height,
-				firstLine.descent,
-				firstLine.x,
-				firstLine.y
-			);
-			var n:Array = new Array(
-				nextLine.ascent,
-				nextLine.height,
-				nextLine.descent,
-				nextLine.x,
-				nextLine.y
-			);
+            var f:Array = [
+                firstLine.ascent,
+                firstLine.height,
+                firstLine.descent,
+                firstLine.x,
+                firstLine.y
+            ];
+            var n:Array = [
+                nextLine.ascent,
+                nextLine.height,
+                nextLine.descent,
+                nextLine.x,
+                nextLine.y
+            ];
 
-			assertTrue("Ascent of second column line not equal to first!", f[0]==n[0]);
-			assertTrue("Height of second column line not equal to first!", f[1]==n[1]);
-			assertTrue("Descent of second column line not equal to first!", f[2]==n[2]);
-			assertTrue("Position of second column line not equal to first!",
-				SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
-					f[4]==n[4] :
-					f[3]==n[3]
-			);
-		}
+            assertTrue("Ascent of second column line not equal to first!", f[0] == n[0]);
+            assertTrue("Height of second column line not equal to first!", f[1] == n[1]);
+            assertTrue("Descent of second column line not equal to first!", f[2] == n[2]);
+            assertTrue("Position of second column line not equal to first!",
+                    SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
+                    f[4] == n[4] :
+                    f[3] == n[3]
+            );
+        }
 
-		public function bottomFBOColumnTest():void
-		{
-			var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
-			cf.paddingTop = 0;
-			cf.paddingRight = 0;
-			cf.columnCount = 2;
-			cf.firstBaselineOffset = 0;
-			/*cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.IDEOGRAPHIC_BOTTOM;
-			(firstBaselineOffsetBasis no longer supported; using following equivlent)*/
-			cf.locale = "ja";
+        [Test]
+        public function bottomFBOColumnTest():void
+        {
+            var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
+            cf.paddingTop = 0;
+            cf.paddingRight = 0;
+            cf.columnCount = 2;
+            cf.firstBaselineOffset = 0;
+            /*cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.IDEOGRAPHIC_BOTTOM;
+             (firstBaselineOffsetBasis no longer supported; using following equivlent)*/
+            cf.locale = "ja";
 
-			SelManager.applyContainerFormat(cf);
+            SelManager.applyContainerFormat(cf);
 
-			var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.justificationRule = JustificationRule.EAST_ASIAN;
-			pf.leadingModel = LeadingModel.AUTO;
+            var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.justificationRule = JustificationRule.EAST_ASIAN;
+            pf.leadingModel = LeadingModel.AUTO;
 
-			SelManager.selectAll();
-			SelManager.applyParagraphFormat(pf);
-			SelManager.textFlow.flowComposer.updateAllControllers();
+            SelManager.selectAll();
+            SelManager.applyParagraphFormat(pf);
+            SelManager.textFlow.flowComposer.updateAllControllers();
 
-			var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
-			var nextLine:TextFlowLine;
+            var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            var nextLine:TextFlowLine;
 
-			for(var i:int = 0; i < SelManager.textFlow.flowComposer.numLines; i++){
-				nextLine = SelManager.textFlow.flowComposer.getLineAt(i);
+            for (var i:int = 0; i < SelManager.textFlow.flowComposer.numLines; i++)
+            {
+                nextLine = SelManager.textFlow.flowComposer.getLineAt(i);
 
-				if(nextLine.columnIndex == 1){
-					break;
-				}else{
-					nextLine = null;
-				}
-			}
+                if (nextLine.columnIndex == 1)
+                {
+                    break;
+                } else
+                {
+                    nextLine = null;
+                }
+            }
 
-			assertTrue("Could not find a line in the second column!", nextLine != null);
+            assertTrue("Could not find a line in the second column!", nextLine != null);
 
-			var f:Array = new Array(
-				firstLine.ascent,
-				firstLine.height,
-				firstLine.descent,
-				firstLine.x,
-				firstLine.y
-			);
-			var n:Array = new Array(
-				nextLine.ascent,
-				nextLine.height,
-				nextLine.descent,
-				nextLine.x,
-				nextLine.y
-			);
+            var f:Array = [
+                firstLine.ascent,
+                firstLine.height,
+                firstLine.descent,
+                firstLine.x,
+                firstLine.y
+            ];
+            var n:Array = [
+                nextLine.ascent,
+                nextLine.height,
+                nextLine.descent,
+                nextLine.x,
+                nextLine.y
+            ];
 
-			assertTrue("Ascent of second column line not equal to first!", f[0]==n[0]);
-			assertTrue("Height of second column line not equal to first!", f[1]==n[1]);
-			assertTrue("Descent of second column line not equal to first!", f[2]==n[2]);
-			assertTrue("Position of second column line not equal to first!",
-				SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
-					f[4]==n[4] :
-					f[3]==n[3]
-			);
-		}
+            assertTrue("Ascent of second column line not equal to first!", f[0] == n[0]);
+            assertTrue("Height of second column line not equal to first!", f[1] == n[1]);
+            assertTrue("Descent of second column line not equal to first!", f[2] == n[2]);
+            assertTrue("Position of second column line not equal to first!",
+                    SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
+                    f[4] == n[4] :
+                    f[3] == n[3]
+            );
+        }
 
-		public function ascentFBOColumnTest():void
-		{
-			var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
-			cf.paddingTop = 0;
-			cf.paddingRight = 0;
-			cf.columnCount = 2;
-			/*cf.firstBaselineOffset = 0;
-			cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.ASCENT;
-			(firstBaselineOffsetBasis no longer supported; using following equivlent)*/
-			cf.firstBaselineOffset = "auto";
+        [Test]
+        public function ascentFBOColumnTest():void
+        {
+            var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
+            cf.paddingTop = 0;
+            cf.paddingRight = 0;
+            cf.columnCount = 2;
+            /*cf.firstBaselineOffset = 0;
+             cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.ASCENT;
+             (firstBaselineOffsetBasis no longer supported; using following equivlent)*/
+            cf.firstBaselineOffset = "auto";
 
-			SelManager.applyContainerFormat(cf);
+            SelManager.applyContainerFormat(cf);
 
-			var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.justificationRule = JustificationRule.SPACE;
-			pf.leadingModel = LeadingModel.AUTO;
+            var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.justificationRule = JustificationRule.SPACE;
+            pf.leadingModel = LeadingModel.AUTO;
 
-			SelManager.selectAll();
-			SelManager.applyParagraphFormat(pf);
-			SelManager.textFlow.flowComposer.updateAllControllers();
+            SelManager.selectAll();
+            SelManager.applyParagraphFormat(pf);
+            SelManager.textFlow.flowComposer.updateAllControllers();
 
-			var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
-			var nextLine:TextFlowLine;
+            var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            var nextLine:TextFlowLine;
 
-			for(var i:int = 0; i < SelManager.textFlow.flowComposer.numLines; i++){
-				nextLine = SelManager.textFlow.flowComposer.getLineAt(i);
+            for (var i:int = 0; i < SelManager.textFlow.flowComposer.numLines; i++)
+            {
+                nextLine = SelManager.textFlow.flowComposer.getLineAt(i);
 
-				if(nextLine.columnIndex == 1){
-					break;
-				}else{
-					nextLine = null;
-				}
-			}
+                if (nextLine.columnIndex == 1)
+                {
+                    break;
+                } else
+                {
+                    nextLine = null;
+                }
+            }
 
-			assertTrue("Could not find a line in the second column!", nextLine != null);
+            assertTrue("Could not find a line in the second column!", nextLine != null);
 
-			var f:Array = new Array(
-				firstLine.ascent,
-				firstLine.height,
-				firstLine.descent,
-				firstLine.x,
-				firstLine.y
-			);
-			var n:Array = new Array(
-				nextLine.ascent,
-				nextLine.height,
-				nextLine.descent,
-				nextLine.x,
-				nextLine.y
-			);
+            var f:Array = [
+                firstLine.ascent,
+                firstLine.height,
+                firstLine.descent,
+                firstLine.x,
+                firstLine.y
+            ];
+            var n:Array = [
+                nextLine.ascent,
+                nextLine.height,
+                nextLine.descent,
+                nextLine.x,
+                nextLine.y
+            ];
 
-			assertTrue("Ascent of second column line not equal to first!", f[0]==n[0]);
-			assertTrue("Height of second column line not equal to first!", f[1]==n[1]);
-			assertTrue("Descent of second column line not equal to first!", f[2]==n[2]);
-			assertTrue("Position of second column line not equal to first!",
-				SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
-					f[4]==n[4] :
-					f[3]==n[3]
-			);
-		}
+            assertTrue("Ascent of second column line not equal to first!", f[0] == n[0]);
+            assertTrue("Height of second column line not equal to first!", f[1] == n[1]);
+            assertTrue("Descent of second column line not equal to first!", f[2] == n[2]);
+            assertTrue("Position of second column line not equal to first!",
+                    SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
+                    f[4] == n[4] :
+                    f[3] == n[3]
+            );
+        }
 
-		public function romanFBOColumnTest():void
-		{
-			var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
-			cf.paddingTop = 0;
-			cf.paddingRight = 0;
-			cf.columnCount = 2;
-			cf.firstBaselineOffset = 0;
-			/*cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.ROMAN;
-			(firstBaselineOffsetBasis no longer supported; using following equivlent)*/
-			cf.locale = "en"; // not really needed since this is the default
+        [Test]
+        public function romanFBOColumnTest():void
+        {
+            var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
+            cf.paddingTop = 0;
+            cf.paddingRight = 0;
+            cf.columnCount = 2;
+            cf.firstBaselineOffset = 0;
+            /*cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.ROMAN;
+             (firstBaselineOffsetBasis no longer supported; using following equivlent)*/
+            cf.locale = "en"; // not really needed since this is the default
 
-			SelManager.applyContainerFormat(cf);
+            SelManager.applyContainerFormat(cf);
 
-			var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.justificationRule = JustificationRule.SPACE;
-			pf.leadingModel = LeadingModel.AUTO;
+            var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.justificationRule = JustificationRule.SPACE;
+            pf.leadingModel = LeadingModel.AUTO;
 
-			SelManager.selectAll();
-			SelManager.applyParagraphFormat(pf);
-			SelManager.textFlow.flowComposer.updateAllControllers();
+            SelManager.selectAll();
+            SelManager.applyParagraphFormat(pf);
+            SelManager.textFlow.flowComposer.updateAllControllers();
 
-			var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
-			var nextLine:TextFlowLine;
+            var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            var nextLine:TextFlowLine;
 
-			for(var i:int = 0; i < SelManager.textFlow.flowComposer.numLines; i++){
-				nextLine = SelManager.textFlow.flowComposer.getLineAt(i);
+            for (var i:int = 0; i < SelManager.textFlow.flowComposer.numLines; i++)
+            {
+                nextLine = SelManager.textFlow.flowComposer.getLineAt(i);
 
-				if(nextLine.columnIndex == 1){
-					break;
-				}else{
-					nextLine = null;
-				}
-			}
+                if (nextLine.columnIndex == 1)
+                {
+                    break;
+                } else
+                {
+                    nextLine = null;
+                }
+            }
 
-			assertTrue("Could not find a line in the second column!", nextLine != null);
+            assertTrue("Could not find a line in the second column!", nextLine != null);
 
-			var f:Array = new Array(
-				firstLine.ascent,
-				firstLine.height,
-				firstLine.descent,
-				firstLine.x,
-				firstLine.y
-			);
-			var n:Array = new Array(
-				nextLine.ascent,
-				nextLine.height,
-				nextLine.descent,
-				nextLine.x,
-				nextLine.y
-			);
+            var f:Array = [
+                firstLine.ascent,
+                firstLine.height,
+                firstLine.descent,
+                firstLine.x,
+                firstLine.y
+            ];
+            var n:Array = [
+                nextLine.ascent,
+                nextLine.height,
+                nextLine.descent,
+                nextLine.x,
+                nextLine.y
+            ];
 
-			assertTrue("Ascent of second column line not equal to first!", f[0]==n[0]);
-			assertTrue("Height of second column line not equal to first!", f[1]==n[1]);
-			assertTrue("Descent of second column line not equal to first!", f[2]==n[2]);
-			assertTrue("Position of second column line not equal to first!",
-				SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
-					f[4]==n[4] :
-					f[3]==n[3]
-			);
-		}
+            assertTrue("Ascent of second column line not equal to first!", f[0] == n[0]);
+            assertTrue("Height of second column line not equal to first!", f[1] == n[1]);
+            assertTrue("Descent of second column line not equal to first!", f[2] == n[2]);
+            assertTrue("Position of second column line not equal to first!",
+                    SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
+                    f[4] == n[4] :
+                    f[3] == n[3]
+            );
+        }
 
-		public function descentFBOColumnTest():void
-		{
-			var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
-			cf.paddingTop = 0;
-			cf.paddingRight = 0;
-			cf.columnCount = 2;
-			cf.firstBaselineOffset = 0;
-			/*cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.DESCENT;
-			(firstBaselineOffsetBasis no longer supported; using following equivlent)*/
-			cf.locale = "ja";
+        [Test]
+        public function descentFBOColumnTest():void
+        {
+            var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
+            cf.paddingTop = 0;
+            cf.paddingRight = 0;
+            cf.columnCount = 2;
+            cf.firstBaselineOffset = 0;
+            /*cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.DESCENT;
+             (firstBaselineOffsetBasis no longer supported; using following equivlent)*/
+            cf.locale = "ja";
 
-			SelManager.applyContainerFormat(cf);
+            SelManager.applyContainerFormat(cf);
 
-			var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.justificationRule = JustificationRule.SPACE;
-			pf.leadingModel = LeadingModel.AUTO;
+            var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.justificationRule = JustificationRule.SPACE;
+            pf.leadingModel = LeadingModel.AUTO;
 
-			SelManager.selectAll();
-			SelManager.applyParagraphFormat(pf);
-			SelManager.textFlow.flowComposer.updateAllControllers();
+            SelManager.selectAll();
+            SelManager.applyParagraphFormat(pf);
+            SelManager.textFlow.flowComposer.updateAllControllers();
 
-			var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
-			var nextLine:TextFlowLine;
+            var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            var nextLine:TextFlowLine;
 
-			for(var i:int = 0; i < SelManager.textFlow.flowComposer.numLines; i++){
-				nextLine = SelManager.textFlow.flowComposer.getLineAt(i);
+            for (var i:int = 0; i < SelManager.textFlow.flowComposer.numLines; i++)
+            {
+                nextLine = SelManager.textFlow.flowComposer.getLineAt(i);
 
-				if(nextLine.columnIndex == 1){
-					break;
-				}else{
-					nextLine = null;
-				}
-			}
+                if (nextLine.columnIndex == 1)
+                {
+                    break;
+                } else
+                {
+                    nextLine = null;
+                }
+            }
 
-			assertTrue("Could not find a line in the second column!", nextLine != null);
+            assertTrue("Could not find a line in the second column!", nextLine != null);
 
-			var f:Array = new Array(
-				firstLine.ascent,
-				firstLine.height,
-				firstLine.descent,
-				firstLine.x,
-				firstLine.y
-			);
-			var n:Array = new Array(
-				nextLine.ascent,
-				nextLine.height,
-				nextLine.descent,
-				nextLine.x,
-				nextLine.y
-			);
+            var f:Array = [
+                firstLine.ascent,
+                firstLine.height,
+                firstLine.descent,
+                firstLine.x,
+                firstLine.y
+            ];
+            var n:Array = [
+                nextLine.ascent,
+                nextLine.height,
+                nextLine.descent,
+                nextLine.x,
+                nextLine.y
+            ];
 
-			assertTrue("Ascent of second column line not equal to first!", f[0]==n[0]);
-			assertTrue("Height of second column line not equal to first!", f[1]==n[1]);
-			assertTrue("Descent of second column line not equal to first!", f[2]==n[2]);
-			assertTrue("Position of second column line not equal to first!",
-				SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
-					f[4]==n[4] :
-					f[3]==n[3]
-			);
-		}
+            assertTrue("Ascent of second column line not equal to first!", f[0] == n[0]);
+            assertTrue("Height of second column line not equal to first!", f[1] == n[1]);
+            assertTrue("Descent of second column line not equal to first!", f[2] == n[2]);
+            assertTrue("Position of second column line not equal to first!",
+                    SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
+                    f[4] == n[4] :
+                    f[3] == n[3]
+            );
+        }
 
-		public function checkUpDownParagraphBoundryTest():void
-		{
-			var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
-			cf.paddingTop = 0;
-			cf.paddingRight = 0;
-			/*cf.firstBaselineOffset = 0;
-			cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.ASCENT;
-			(firstBaselineOffsetBasis no longer supported; using following equivlent)*/
-			cf.firstBaselineOffset = "auto";
+        [Test]
+        public function checkUpDownParagraphBoundryTest():void
+        {
+            var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
+            cf.paddingTop = 0;
+            cf.paddingRight = 0;
+            /*cf.firstBaselineOffset = 0;
+             cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.ASCENT;
+             (firstBaselineOffsetBasis no longer supported; using following equivlent)*/
+            cf.firstBaselineOffset = "auto";
 
-			SelManager.applyFormatToElement(SelManager.textFlow,cf);
-			SelManager.applyContainerFormat(cf);
+            SelManager.applyFormatToElement(SelManager.textFlow, cf);
+            SelManager.applyContainerFormat(cf);
 
-			var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.justificationRule = JustificationRule.SPACE;
-			pf.leadingModel = LeadingModel.IDEOGRAPHIC_TOP_UP;
+            var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.justificationRule = JustificationRule.SPACE;
+            pf.leadingModel = LeadingModel.IDEOGRAPHIC_TOP_UP;
 
-			SelManager.selectAll();
-			SelManager.applyParagraphFormat(pf);
-			SelManager.textFlow.flowComposer.updateAllControllers();
+            SelManager.selectAll();
+            SelManager.applyParagraphFormat(pf);
+            SelManager.textFlow.flowComposer.updateAllControllers();
 
-			var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
 
-			SelManager.selectRange(firstLine.textLength,firstLine.textLength);
-			SelManager.splitParagraph();
+            SelManager.selectRange(firstLine.textLength, firstLine.textLength);
+            SelManager.splitParagraph();
 
-			firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
-			var nextLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(1);
+            firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            var nextLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(1);
 
-			assertTrue("Seperated lines are still in the same paragraph!",
-				firstLine.paragraph != nextLine.paragraph
-			);
+            assertTrue("Seperated lines are still in the same paragraph!",
+                    firstLine.paragraph != nextLine.paragraph
+            );
 
-			pf = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.justificationRule = JustificationRule.SPACE;
-			pf.leadingModel = LeadingModel.IDEOGRAPHIC_TOP_DOWN;
+            pf = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.justificationRule = JustificationRule.SPACE;
+            pf.leadingModel = LeadingModel.IDEOGRAPHIC_TOP_DOWN;
 
-			SelManager.selectRange(
-				nextLine.absoluteStart,
-				(nextLine.absoluteStart + nextLine.textLength)
-			);
-			SelManager.applyParagraphFormat(pf);
-			SelManager.textFlow.flowComposer.updateAllControllers();
+            SelManager.selectRange(
+                    nextLine.absoluteStart,
+                    (nextLine.absoluteStart + nextLine.textLength)
+            );
+            SelManager.applyParagraphFormat(pf);
+            SelManager.textFlow.flowComposer.updateAllControllers();
 
-			firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
-			nextLine = SelManager.textFlow.flowComposer.getLineAt(1);
+            nextLine = SelManager.textFlow.flowComposer.getLineAt(1);
 
-			var f:Array = new Array(
-				firstLine.ascent,
-				firstLine.height,
-				firstLine.descent,
-				firstLine.x,
-				firstLine.y
-			);
-			var n:Array = new Array(
-				nextLine.ascent,
-				nextLine.height,
-				nextLine.descent,
-				nextLine.x,
-				nextLine.y
-			);
-			var size:int = SelManager.getCommonCharacterFormat().fontSize as int;
-			assertTrue("Leading is incorrectly applied",
-				SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
-				nextLine.y == nextLine.height + size + 1 :
-				nextLine.x == -(nextLine.height + size + 1)
-			);
-		}
+            var size:int = SelManager.getCommonCharacterFormat().fontSize as int;
+            assertTrue("Leading is incorrectly applied",
+                    SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
+                    nextLine.y == nextLine.height + size + 1 :
+                    nextLine.x == -(nextLine.height + size + 1)
+            );
+        }
 
-		public function checkDownUpParagraphBoundryTest():void
-		{
-			var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
-			cf.paddingTop = 0;
-			cf.paddingRight = 0;
-			/*cf.firstBaselineOffset = 0;
-			cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.ASCENT;
-			(firstBaselineOffsetBasis no longer supported; using following equivlent)*/
-			cf.firstBaselineOffset = "auto";
+        [Test]
+        public function checkDownUpParagraphBoundryTest():void
+        {
+            var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
+            cf.paddingTop = 0;
+            cf.paddingRight = 0;
+            /*cf.firstBaselineOffset = 0;
+             cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.ASCENT;
+             (firstBaselineOffsetBasis no longer supported; using following equivlent)*/
+            cf.firstBaselineOffset = "auto";
 
-			SelManager.applyFormatToElement(SelManager.textFlow,cf);
-			SelManager.applyContainerFormat(cf);
+            SelManager.applyFormatToElement(SelManager.textFlow, cf);
+            SelManager.applyContainerFormat(cf);
 
-			var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.justificationRule = JustificationRule.SPACE;
-			pf.leadingModel = LeadingModel.IDEOGRAPHIC_TOP_DOWN;
+            var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.justificationRule = JustificationRule.SPACE;
+            pf.leadingModel = LeadingModel.IDEOGRAPHIC_TOP_DOWN;
 
-			SelManager.selectAll();
-			SelManager.applyParagraphFormat(pf);
-			SelManager.textFlow.flowComposer.updateAllControllers();
+            SelManager.selectAll();
+            SelManager.applyParagraphFormat(pf);
+            SelManager.textFlow.flowComposer.updateAllControllers();
 
-			var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
 
-			SelManager.selectRange(firstLine.textLength,firstLine.textLength);
-			SelManager.splitParagraph();
+            SelManager.selectRange(firstLine.textLength, firstLine.textLength);
+            SelManager.splitParagraph();
 
-			firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
-			var nextLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(1);
+            firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            var nextLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(1);
 
-			assertTrue("Seperated lines are still in the same paragraph!",
-				firstLine.paragraph != nextLine.paragraph
-			);
+            assertTrue("Seperated lines are still in the same paragraph!",
+                    firstLine.paragraph != nextLine.paragraph
+            );
 
-			pf = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.justificationRule = JustificationRule.SPACE;
-			pf.leadingModel = LeadingModel.IDEOGRAPHIC_TOP_UP;
+            pf = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.justificationRule = JustificationRule.SPACE;
+            pf.leadingModel = LeadingModel.IDEOGRAPHIC_TOP_UP;
 
-			SelManager.selectRange(
-				nextLine.absoluteStart,
-				(nextLine.absoluteStart + nextLine.textLength)
-			);
-			SelManager.applyParagraphFormat(pf);
-			SelManager.textFlow.flowComposer.updateAllControllers();
+            SelManager.selectRange(
+                    nextLine.absoluteStart,
+                    (nextLine.absoluteStart + nextLine.textLength)
+            );
+            SelManager.applyParagraphFormat(pf);
+            SelManager.textFlow.flowComposer.updateAllControllers();
 
-			firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
-			nextLine = SelManager.textFlow.flowComposer.getLineAt(1);
+            firstLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            nextLine = SelManager.textFlow.flowComposer.getLineAt(1);
 
-			var f:Array = new Array(
-				firstLine.ascent,
-				firstLine.height,
-				firstLine.descent,
-				firstLine.x,
-				firstLine.y
-			);
-			var n:Array = new Array(
-				nextLine.ascent,
-				nextLine.height,
-				nextLine.descent,
-				nextLine.x,
-				nextLine.y
-			);
-			var size:int = SelManager.getCommonCharacterFormat().fontSize as int;
-			assertTrue("Leading is incorrectly applied",
-				SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
-				nextLine.y == nextLine.height + size + 1 :
-				nextLine.x == -(nextLine.height + size + 1)
-			);
-		}
+            var size:int = SelManager.getCommonCharacterFormat().fontSize as int;
+            assertTrue("Leading is incorrectly applied",
+                    SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB ?
+                    nextLine.y == nextLine.height + size + 1 :
+                    nextLine.x == -(nextLine.height + size + 1)
+            );
+        }
 
-		public function inlineGraphicWithFBOTest():void
-		{
-			var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
-			cf.paddingTop = 0;
-			cf.paddingRight = 0;
-			/*cf.firstBaselineOffset = 0;
-			cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.ASCENT;
-			(firstBaselineOffsetBasis no longer supported; using following equivlent)*/
-			cf.firstBaselineOffset = "auto";
+        [Test]
+        public function inlineGraphicWithFBOTest():void
+        {
+            var cf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonContainerFormat());
+            cf.paddingTop = 0;
+            cf.paddingRight = 0;
+            /*cf.firstBaselineOffset = 0;
+             cf.firstBaselineOffsetBasis = flash.text.engine.TextBaseline.ASCENT;
+             (firstBaselineOffsetBasis no longer supported; using following equivlent)*/
+            cf.firstBaselineOffset = "auto";
 
-			SelManager.applyContainerFormat(cf);
+            SelManager.applyContainerFormat(cf);
 
-			var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
-			pf.justificationRule = JustificationRule.SPACE;
-			pf.leadingModel = LeadingModel.ROMAN_UP;
+            var pf:TextLayoutFormat = new TextLayoutFormat(SelManager.getCommonParagraphFormat());
+            pf.justificationRule = JustificationRule.SPACE;
+            pf.leadingModel = LeadingModel.ROMAN_UP;
 
-			SelManager.selectAll();
-			SelManager.applyParagraphFormat(pf);
+            SelManager.selectAll();
+            SelManager.applyParagraphFormat(pf);
 
-			SelManager.selectRange(3,4);
-			SelManager.insertInlineGraphic(LoaderUtil.createAbsoluteURL(baseURL,"../../test/testFiles/assets/smiling.png"),30,30);
-			SelManager.textFlow.flowComposer.updateAllControllers();
+            SelManager.selectRange(3, 4);
+            SelManager.insertInlineGraphic(LoaderUtil.createAbsoluteURL(baseURL, "../../test/testFiles/assets/smiling.png"), 30, 30);
+            SelManager.textFlow.flowComposer.updateAllControllers();
 
-			var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
+            var firstLine:TextFlowLine = SelManager.textFlow.flowComposer.getLineAt(0);
 
-			var flStats:Array = new Array(
-				firstLine.ascent,
-				firstLine.height,
-				firstLine.descent,
-				firstLine.x,
-				firstLine.y
-			);
+            var flStats:Array = [
+                firstLine.ascent,
+                firstLine.height,
+                firstLine.descent,
+                firstLine.x,
+                firstLine.y
+            ];
 
-			assertTrue("Line height is not the height of the inline graphic!",flStats[1] == 30);
-		}
+            assertTrue("Line height is not the height of the inline graphic!", flStats[1] == 30);
+        }
 
-		private function getData():BitmapData
-		{
-			var doc:DisplayObjectContainer =
-				testApp.getTextFlow().flowComposer.getControllerAt(0).container;
+        private function getData():BitmapData
+        {
+            var doc:DisplayObjectContainer = testApp.getTextFlow().flowComposer.getControllerAt(0).container;
 
-			var data:BitmapData = new BitmapData(doc.width,doc.height);
-			data.draw(doc);
+            var data:BitmapData = new BitmapData(doc.width, doc.height);
+            data.draw(doc);
 
-			return data;
-		}
+            return data;
+        }
 
-		private function compareData(data1:BitmapData, data2:BitmapData):Boolean
-		{
-			var vect1:Vector.<uint> = data1.getVector(data1.rect);
-			var vect2:Vector.<uint> = data2.getVector(data2.rect);
+        private function compareData(data1:BitmapData, data2:BitmapData):Boolean
+        {
+            var vect1:Vector.<uint> = data1.getVector(data1.rect);
+            var vect2:Vector.<uint> = data2.getVector(data2.rect);
 
-			var one:uint = 0;
-			var two:uint = 0;
-			var count:int = 0;
+            var one:uint = 0;
+            var two:uint = 0;
+            var count:int = 0;
 
-			var marked:Boolean = false;
-			for(var i:int = 0; i < vect1.length; i++){
-				one = vect1.pop();
-				two = vect2.pop();
+            for (var i:int = 0; i < vect1.length; i++)
+            {
+                one = vect1.pop();
+                two = vect2.pop();
 
-				/* TODO: Change this back to not include block progression.*/
-				if( one != two &&
-					SelManager.textFlow.computedFormat.blockProgression !=
-						BlockProgression.RL)
-				{
-					count++;
-				}
-			}
+                /* TODO: Change this back to not include block progression.*/
+                if (one != two &&
+                        SelManager.textFlow.computedFormat.blockProgression !=
+                        BlockProgression.RL)
+                {
+                    count++;
+                }
+            }
 
-			return (((count/(vect1.length/4))*100) < diffTolerance);
-		}
-	}
+            return (((count / (vect1.length / 4)) * 100) < diffTolerance);
+        }
+    }
 }
diff --git a/test/testCases/MeasurementTest.xml b/test/testCases/MeasurementTest.xml
index 9d5eae7..63952c4 100644
--- a/test/testCases/MeasurementTest.xml
+++ b/test/testCases/MeasurementTest.xml
@@ -30,7 +30,7 @@
 	<TestData name="fileName">listMarkerAlignmentZeroPad.xml</TestData>
 	<TestData name="testFile">listMarkerAlignmentZeroPad.xml</TestData>
 </TestCase>
-<TestCase functionName="listNegativeMarkersMeasure">
+<TestCase functionName="listNegativeMarkers">
 	<TestData name="flash">false</TestData>
 	<TestData name="measure">true</TestData>
 	<TestData name="fileName">listMarkerAlignmentZeroPad.xml</TestData>
