diff --git a/automation_tests/src/AllTestsSuite.as b/automation_tests/src/AllTestsSuite.as
index cf1c29e..708c768 100644
--- a/automation_tests/src/AllTestsSuite.as
+++ b/automation_tests/src/AllTestsSuite.as
@@ -43,6 +43,7 @@
     import UnitTest.Tests.KeyboardGestureTest;
     import UnitTest.Tests.OperationTest;
     import UnitTest.Tests.ScrollingTest;
+    import UnitTest.Tests.SpacingTest;
     import UnitTest.Tests.TabTest;
     import UnitTest.Tests.TextFlowEditTest;
     import UnitTest.Tests.UndoRedoTest;
@@ -80,6 +81,7 @@
         public var impliedParagraphTest:ImpliedParagraphTest;
         public var importApiTest:ImportAPITest;
         public var keyboardGestureTest:KeyboardGestureTest;
+        public var spacingTest:SpacingTest;
     }
 
 }
diff --git a/automation_tests/src/UnitTest/Helpers/SingleContainer.as b/automation_tests/src/UnitTest/Helpers/SingleContainer.as
new file mode 100644
index 0000000..db4b50f
--- /dev/null
+++ b/automation_tests/src/UnitTest/Helpers/SingleContainer.as
@@ -0,0 +1,211 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package UnitTest.Helpers
+{
+    import flash.display.Sprite;
+    import flash.events.Event;
+    import flash.events.MouseEvent;
+    import flash.system.System;
+    import flash.text.TextField;
+    import flash.text.TextFormat;
+
+    import flashx.textLayout.container.ContainerController;
+    import flashx.textLayout.edit.EditManager;
+    import flashx.textLayout.elements.DivElement;
+    import flashx.textLayout.elements.InlineGraphicElement;
+    import flashx.textLayout.elements.ParagraphElement;
+    import flashx.textLayout.elements.SpanElement;
+    import flashx.textLayout.elements.TextFlow;
+    import flashx.textLayout.tlf_internal;
+    import flashx.undo.UndoManager;
+
+    use namespace tlf_internal;
+
+    [SWF(width="500", height="700", backgroundColor="#FFFFFF")]
+
+    public class SingleContainer extends Sprite
+    {
+
+        protected var tf:TextFlow;
+        protected var em:EditManager;
+        protected var um:UndoManager
+        protected var _bg:Sprite;
+        protected var _spr:Sprite;
+        protected var _cc:ContainerController;
+        protected var _btn:Sprite;
+        protected var _playing:Boolean = false;
+        protected var _count:int = 0;
+
+        protected var _graph:Sprite;
+        protected var _print_out:TextField;
+        protected var _last_time:Date = new Date();
+        protected var _last_five:Array = [];
+
+        public function SingleContainer()
+        {
+
+            //			stage.scaleMode = StageScaleMode.NO_SCALE;
+            //			stage.align = StageAlign.TOP_LEFT;
+
+            var cw:Number = 200; // the container width
+            var ch:Number = 600;  // the container height
+
+            _bg = new Sprite();
+            _bg.graphics.lineStyle(.25, 0);
+            _bg.graphics.drawRect(0, 0, cw, ch);
+            addChild(_bg);
+
+            _spr = new Sprite();
+            addChild(_spr);
+
+            _graph = new Sprite();
+            _graph.x = cw + 10;
+            _graph.y = 250;
+            addChild(_graph);
+
+            _print_out = new TextField();
+            var fmt:TextFormat = _print_out.defaultTextFormat;
+            fmt.font = "_sans";
+            _print_out.wordWrap = true;
+            _print_out.multiline = true;
+            //			_print_out.width = stage.stageWidth - (10 + _graph.x);
+            _print_out.x = _graph.x;
+            _print_out.y = _graph.y + 10;
+            addChild(_print_out);
+
+            //define TextFlow and manager objects
+            tf = new TextFlow();
+            um = new UndoManager();
+            em = new EditManager(um);
+            tf.interactionManager = em;
+
+            //compose TextFlow to display
+            _cc = new ContainerController(_spr, cw, ch);
+            //_cc.verticalAlign = VerticalAlign.BOTTOM;
+            //_cc.verticalScrollPolicy = ScrollPolicy.ON;
+            tf.flowComposer.addController(_cc);
+            tf.flowComposer.updateAllControllers();
+
+            //make a button to add Inline Graphic elements
+            _btn = new Sprite();
+            _btn.graphics.beginFill(0xFF0000, 1);
+            _btn.graphics.drawRect(0, 0, 120, 30);
+            addChild(_btn);
+            _btn.addEventListener(MouseEvent.CLICK, btnClicked);
+            _btn.y = 600;
+
+            addMessage("1");
+            addMessage("2");
+            addMessage("3", true);
+
+        }
+
+        public function addMessage(msg:String, add_image:Boolean = false):void
+        {
+            //define elements to contain text
+            var d:DivElement = new DivElement();
+            var p:ParagraphElement = new ParagraphElement();
+            var s:SpanElement = new SpanElement();
+            s.text = msg;
+            //add these elements to the TextFlow
+            p.addChild(s);
+            d.addChild(p);
+            if (add_image)
+            {
+                var sp:Sprite = new Sprite();
+                sp.graphics.beginFill(0xFFCC00);
+                sp.graphics.drawRect(0, 0, 100, 20);
+                var i:InlineGraphicElement = new InlineGraphicElement();
+                i.source = sp;
+                i.width = 100;
+                i.height = 20;
+                p.addChild(i);
+            }
+            tf.addChild(d);
+            tf.flowComposer.updateAllControllers();
+            _cc.verticalScrollPosition = _cc.getContentBounds().height;
+            tf.flowComposer.updateAllControllers();
+        }
+
+        protected function btnClicked(e:MouseEvent):void
+        {
+            _playing = !_playing;
+            removeEventListener(Event.ENTER_FRAME, onEnterFrame);
+            if (_playing)
+            {
+                addEventListener(Event.ENTER_FRAME, onEnterFrame);
+            }
+        }
+
+        protected function onEnterFrame(e:Event):void
+        {
+            _count++;
+
+            if (_count > 100)
+            {
+                tf.removeChildAt(0);
+            }
+
+            addMessage("Message Number: " + _count + " " + randomString());
+            printOut()
+        }
+
+        protected function printOut():void
+        {
+            var now:Date = new Date();
+            var tm:Number = (now.getTime() - _last_time.getTime());
+            _last_five.push(tm);
+            if (_last_five.length > 10) _last_five.shift();
+            var avg_tm:Number = 0;
+            for (var i:int = 0; i < _last_five.length; i++) avg_tm += _last_five[i];
+            avg_tm = Math.round(avg_tm / _last_five.length);
+            var elapsed_str:String = "message: \t\t\t" + _count
+                    + "\ntime: \t\t\t\t" + tm + "ms"
+                    + "\navg of last 10:\t\t" + avg_tm + "ms";
+            //trace(elapsed_str );
+            _print_out.text = elapsed_str;
+            _last_time = now;
+            drawGraph(tm);
+        }
+
+        protected function drawGraph(tm:Number):void
+        {
+            if (_count % 5 == 0)
+            {
+                _graph.graphics.beginFill(0x0);
+                _graph.graphics.drawRect(_count / 10, -Math.round(tm / 10), 1, 1);
+                _graph.graphics.beginFill(0xFF0000);
+                _graph.graphics.drawRect(_count / 10, -Math.round(System.totalMemory / 1000000), 1, 1);
+            }
+        }
+
+        protected function randomString():String
+        {
+            var chars:String = "abcdefghijklmnopqrstuvwzyz                    ";
+            var chars_len:Number = chars.length;
+            var random_str:String = "";
+            var num_chars:Number = Math.round(Math.random() * 100);
+            for (var i:int = 0; i < num_chars; i++)
+            {
+                random_str = random_str + chars.charAt(Math.round(Math.random() * chars_len));
+            }
+            return random_str;
+        }
+    }
+}
\ No newline at end of file
diff --git a/automation_tests/src/UnitTest/Tests/ScrollingTest.as b/automation_tests/src/UnitTest/Tests/ScrollingTest.as
index 6ca0e41..e530c07 100644
--- a/automation_tests/src/UnitTest/Tests/ScrollingTest.as
+++ b/automation_tests/src/UnitTest/Tests/ScrollingTest.as
@@ -32,6 +32,7 @@
     import UnitTest.ExtendedClasses.VellumTestCase;
     import UnitTest.Fixtures.TestCaseVo;
     import UnitTest.Fixtures.TestConfig;
+    import UnitTest.Helpers.SingleContainer;
 
     import flash.display.Shape;
     import flash.display.Sprite;
@@ -558,7 +559,7 @@
             }
         }
 
-        private var singleCT:SingleContainerTest = new SingleContainerTest();
+        private var singleCT:SingleContainer = new SingleContainer();
 
         /**
          * mjzhang : Watson#2819924 Error #1009 in flashx.textLayout.container::ContainerController::updateGraphics()
diff --git a/automation_tests/src/UnitTest/Tests/SimpleTest.as b/automation_tests/src/UnitTest/Tests/SimpleTest.as
deleted file mode 100644
index da26661..0000000
--- a/automation_tests/src/UnitTest/Tests/SimpleTest.as
+++ /dev/null
@@ -1,48 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-//  Licensed to the Apache Software Foundation (ASF) under one or more
-//  contributor license agreements.  See the NOTICE file distributed with
-//  this work for additional information regarding copyright ownership.
-//  The ASF licenses this file to You under the Apache License, Version 2.0
-//  (the "License"); you may not use this file except in compliance with
-//  the License.  You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-//
-////////////////////////////////////////////////////////////////////////////////
-package UnitTest.Tests
-{
-
-    import org.flexunit.asserts.assertTrue;
-
-    public class SimpleTest
-    {
-        public function SimpleTest()
-        {
-        }
-
-        [Before]
-        public function setUp() : void
-        {
-            var ddd:Object = null;
-        }
-
-        [After]
-        public function tearDown():void
-        {
-            var ddd:Object = null;
-        }
-
-        [Test]
-        public function myTest():void
-        {
-            assertTrue(true);
-        }
-    }
-}
diff --git a/automation_tests/src/UnitTest/Tests/SingleContainerTest.as b/automation_tests/src/UnitTest/Tests/SingleContainerTest.as
deleted file mode 100644
index d575685..0000000
--- a/automation_tests/src/UnitTest/Tests/SingleContainerTest.as
+++ /dev/null
@@ -1,206 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-//  Licensed to the Apache Software Foundation (ASF) under one or more
-//  contributor license agreements.  See the NOTICE file distributed with
-//  this work for additional information regarding copyright ownership.
-//  The ASF licenses this file to You under the Apache License, Version 2.0
-//  (the "License"); you may not use this file except in compliance with
-//  the License.  You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-//
-////////////////////////////////////////////////////////////////////////////////
-package UnitTest.Tests
-{
-	import flash.display.Sprite;
-	import flash.display.StageAlign;
-	import flash.display.StageScaleMode;
-	import flash.events.Event;
-	import flash.events.MouseEvent;
-	import flash.system.System;
-	import flash.text.TextField;
-	import flash.text.TextFormat;
-	
-	import flashx.textLayout.container.ContainerController;
-	import flashx.textLayout.container.ScrollPolicy;
-	import flashx.textLayout.edit.EditManager;
-	import flashx.textLayout.elements.DivElement;
-	import flashx.textLayout.elements.InlineGraphicElement;
-	import flashx.textLayout.elements.ParagraphElement;
-	import flashx.textLayout.elements.SpanElement;
-	import flashx.textLayout.elements.TextFlow;
-	import flashx.textLayout.formats.TextLayoutFormat;
-	import flashx.textLayout.formats.VerticalAlign;
-	import flashx.textLayout.tlf_internal;
-	import flashx.undo.UndoManager;
-	
-	use namespace tlf_internal;
-	
-	[SWF (width="500", height="700", backgroundColor="#FFFFFF")]
-	
-	public class SingleContainerTest extends Sprite
-	{
-		
-		protected var tf:TextFlow;
-		protected var em:EditManager;
-		protected var um:flashx.undo.UndoManager
-		protected var _bg:Sprite;
-		protected var _spr:Sprite;
-		protected var _cc:ContainerController
-		protected var _init_fmt:TextLayoutFormat;
-		protected var _btn:Sprite;
-		protected var _playing:Boolean = false;
-		protected var _count:int = 0;
-		
-		protected var _graph:Sprite;
-		protected var _print_out:TextField;
-		protected var _last_time:Date = new Date();
-		protected var _last_five:Array = [];
-		
-		public function SingleContainerTest()
-		{
-			
-//			stage.scaleMode = StageScaleMode.NO_SCALE;
-//			stage.align = StageAlign.TOP_LEFT;
-			
-			var cw:Number = 200; // the container width
-			var ch:Number = 600;  // the container height
-			
-			_bg = new Sprite();
-			_bg.graphics.lineStyle(.25, 0);
-			_bg.graphics.drawRect(0,0,cw,ch);
-			addChild(_bg);
-			
-			_spr = new Sprite();
-			addChild(_spr);
-			
-			_graph = new Sprite();
-			_graph.x = cw + 10;
-			_graph.y = 250;
-			addChild(_graph);
-			
-			_print_out = new TextField();
-			var fmt:TextFormat = _print_out.defaultTextFormat;
-			fmt.font = "_sans";
-			_print_out.wordWrap = true;
-			_print_out.multiline = true;
-//			_print_out.width = stage.stageWidth - (10 + _graph.x);
-			_print_out.x = _graph.x;
-			_print_out.y = _graph.y + 10;
-			addChild(_print_out);
-			
-			//define TextFlow and manager objects
-			tf = new TextFlow();
-			um = new UndoManager();
-			em = new EditManager(um);
-			tf.interactionManager = em;  
-			
-			//compose TextFlow to display
-			_cc = new ContainerController(_spr,cw,ch);
-			//_cc.verticalAlign = VerticalAlign.BOTTOM;
-			//_cc.verticalScrollPolicy = ScrollPolicy.ON;
-			tf.flowComposer.addController(_cc);
-			tf.flowComposer.updateAllControllers();
-			
-			//make a button to add Inline Graphic elements
-			_btn = new Sprite();
-			_btn.graphics.beginFill(0xFF0000,1);
-			_btn.graphics.drawRect(0,0,120,30);
-			addChild(_btn);
-			_btn.addEventListener(MouseEvent.CLICK, btnClicked);
-			_btn.y = 600;
-			
-			addMessage("1");
-			addMessage("2");
-			addMessage("3", true);
-			
-		}
-		
-		public function addMessage(msg:String, add_image:Boolean = false):void {
-			//define elements to contain text
-			var d:DivElement = new DivElement();
-			var p:ParagraphElement = new ParagraphElement();
-			var s:SpanElement = new SpanElement();
-			s.text = msg;
-			//add these elements to the TextFlow
-			p.addChild(s);
-			d.addChild(p);
-			if(add_image){
-				var sp:Sprite = new Sprite();
-				sp.graphics.beginFill(0xFFCC00);
-				sp.graphics.drawRect(0,0,100,20);
-				var i:InlineGraphicElement = new InlineGraphicElement();
-				i.source = sp;
-				i.width = 100;
-				i.height = 20;
-				p.addChild(i);
-			}
-			tf.addChild(d);
-			tf.flowComposer.updateAllControllers();
-			_cc.verticalScrollPosition = _cc.getContentBounds().height;
-			tf.flowComposer.updateAllControllers();
-		}
-		
-		protected function btnClicked(e:MouseEvent):void {
-			_playing = !_playing;
-			removeEventListener(Event.ENTER_FRAME, onEnterFrame);
-			if(_playing){
-				addEventListener(Event.ENTER_FRAME, onEnterFrame);
-			}
-		}
-		
-		protected function onEnterFrame(e:Event):void {
-			_count++;
-			
-			if(_count > 100){
-				tf.removeChildAt(0);
-			}
-			
-			addMessage("Message Number: " + _count + " " + randomString());
-			printOut()
-		}
-		
-		protected function printOut():void {
-			var now:Date = new Date();
-			var tm:Number = (now.getTime() - _last_time.getTime());
-			_last_five.push(tm);
-			if(_last_five.length > 10) _last_five.shift();
-			var avg_tm:Number = 0;
-			for(var i:int = 0; i < _last_five.length; i++) avg_tm += _last_five[i];
-			avg_tm = Math.round(avg_tm/_last_five.length);
-			var elapsed_str:String = "message: \t\t\t"+_count
-				+ "\ntime: \t\t\t\t" + tm + "ms"
-				+ "\navg of last 10:\t\t" + avg_tm +"ms";
-			//trace(elapsed_str );
-			_print_out.text = elapsed_str;
-			_last_time = now;
-			drawGraph(tm);
-		}
-		
-		protected function drawGraph(tm:Number):void {
-			if(_count % 5 == 0){
-				_graph.graphics.beginFill(0x0);
-				_graph.graphics.drawRect(_count/10,-Math.round(tm/10),1,1);
-				_graph.graphics.beginFill(0xFF0000);
-				_graph.graphics.drawRect(_count/10,-Math.round(System.totalMemory/1000000),1,1);
-			}
-		}
-		
-		protected function randomString():String {
-			var chars:String = "abcdefghijklmnopqrstuvwzyz                    ";
-			var chars_len:Number = chars.length;
-			var random_str:String = "";
-			var num_chars:Number = Math.round(Math.random() * 100);
-			for (var i:int =0; i < num_chars; i++){
-				random_str = random_str + chars.charAt(Math.round(Math.random() * chars_len));
-			}
-			return random_str;
-		}
-	}
-}
\ No newline at end of file
diff --git a/automation_tests/src/UnitTest/Tests/SpacingTest.as b/automation_tests/src/UnitTest/Tests/SpacingTest.as
index a689a28..fcd4438 100644
--- a/automation_tests/src/UnitTest/Tests/SpacingTest.as
+++ b/automation_tests/src/UnitTest/Tests/SpacingTest.as
@@ -18,138 +18,136 @@
 ////////////////////////////////////////////////////////////////////////////////
 package UnitTest.Tests
 {
-	import UnitTest.ExtendedClasses.TestDescriptor;
-	import UnitTest.ExtendedClasses.TestSuiteExtended;
-	import UnitTest.ExtendedClasses.VellumTestCase;
-	import UnitTest.Fixtures.TestConfig;
+    import UnitTest.ExtendedClasses.VellumTestCase;
+    import UnitTest.Fixtures.TestConfig;
 
-	import flash.events.Event;
-	import flash.geom.Point;
-	import flash.geom.Rectangle;
-
-	import flashx.textLayout.compose.StandardFlowComposer;
-	import flashx.textLayout.compose.TextFlowLine;
-	import flashx.textLayout.formats.BlockProgression;
-	import flashx.textLayout.formats.Direction;
-	import flashx.textLayout.formats.ITextLayoutFormat;
-	import flashx.textLayout.formats.TextLayoutFormat;
-	import flashx.textLayout.tlf_internal;
+    import flashx.textLayout.compose.StandardFlowComposer;
+    import flashx.textLayout.compose.TextFlowLine;
+    import flashx.textLayout.formats.BlockProgression;
+    import flashx.textLayout.formats.Direction;
+    import flashx.textLayout.formats.TextLayoutFormat;
+    import flashx.textLayout.tlf_internal;
 
     import org.flexunit.asserts.assertTrue;
-
     import org.flexunit.asserts.fail;
 
     use namespace tlf_internal;
 
-	public class SpacingTest extends VellumTestCase
-	{
-		private var firstLine:TextFlowLine;
-		private var secondLine:TextFlowLine;
+    [TestCase(order=29)]
+    public class SpacingTest extends VellumTestCase
+    {
+        private var firstLine:TextFlowLine;
+        private var secondLine:TextFlowLine;
 
-		public function SpacingTest(methodName:String, testID:String, testConfig:TestConfig, testCaseXML:XML=null)
-		{
-			super(methodName, testID, testConfig, testCaseXML);
+        public function SpacingTest()
+        {
+            super("", "SpacingTest", 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(SpacingTest, "spaceLeadingMarginTest", testConfig));
-		}
+        [Before]
+        public override function setUpTest():void
+        {
+            super.setUpTest();
 
-		public override function setUpTest():void
-		{
-			super.setUpTest();
+            var ca:TextLayoutFormat = new TextLayoutFormat(TestFrame.format);
+            ca.columnCount = 1;
+            TestFrame.format = ca;
 
-			var ca:TextLayoutFormat = new TextLayoutFormat(TestFrame.format);
-			ca.columnCount = 1;
-			TestFrame.format = ca;
+            TestFrame.textFlow.flowComposer.updateAllControllers();
+        }
 
-			TestFrame.textFlow.flowComposer.updateAllControllers();
-		}
+        [After]
+        override public function tearDownTest():void
+        {
+            super.tearDownTest();
+        }
 
-		//Paragraph.
-		public function spaceLeadingMarginTest():void
-		{
-			var lines:Array = StandardFlowComposer(SelManager.textFlow.flowComposer).lines;
-			firstLine = lines[0] as TextFlowLine;
+        [Test]
+        public function spaceLeadingMarginTest():void
+        {
+            var lines:Array = StandardFlowComposer(SelManager.textFlow.flowComposer).lines;
+            firstLine = lines[0] as TextFlowLine;
 
-			for each (var sl:TextFlowLine in lines){
-				if(sl.paragraph != firstLine.paragraph &&
-						sl.location == firstLine.location
-				){
-					secondLine = sl;
-					break;
-				}
-			}
+            for each (var sl:TextFlowLine in lines)
+            {
+                if (sl.paragraph != firstLine.paragraph &&
+                        sl.location == firstLine.location
+                )
+                {
+                    secondLine = sl;
+                    break;
+                }
+            }
 
-			SelManager.selectRange(firstLine.absoluteStart,firstLine.textLength - 2);
-			var pa:TextLayoutFormat = new TextLayoutFormat();
+            SelManager.selectRange(firstLine.absoluteStart, firstLine.textLength - 2);
+            var pa:TextLayoutFormat = new TextLayoutFormat();
 
-			if (this.writingDirection[0] == BlockProgression.TB)
-			{
-				if (this.writingDirection[1] == Direction.LTR)
-				{
-					assertTrue(firstLine.x == secondLine.x);
-					pa.paragraphStartIndent = 100;
-				}
-				else if (this.writingDirection[1] == Direction.RTL)
-				{
-					// these should be close
-					var l1End:Number = firstLine.x+firstLine.getTextLine().width;
-					var l2End:Number = secondLine.x+secondLine.getTextLine().width;
-					var isNearlyEqual:Boolean = Math.abs(l1End-l2End)< 0.1;
-					assertTrue(isNearlyEqual);
-					pa.paragraphEndIndent = 100;
-				}
-				else
-					fail("Unknown direction " + this.writingDirection[1]);
-			}
-			else if (this.writingDirection[0] == BlockProgression.RL)
-			{
-				assertTrue(firstLine.y == secondLine.y);
-				pa.paragraphStartIndent = 100;
-			}
-			else
-				fail("Unknown blockProgression " + this.writingDirection[0]);
+            if (this.writingDirection[0] == BlockProgression.TB)
+            {
+                if (this.writingDirection[1] == Direction.LTR)
+                {
+                    assertTrue(firstLine.x == secondLine.x);
+                    pa.paragraphStartIndent = 100;
+                }
+                else if (this.writingDirection[1] == Direction.RTL)
+                {
+                    // these should be close
+                    var l1End:Number = firstLine.x + firstLine.getTextLine().width;
+                    var l2End:Number = secondLine.x + secondLine.getTextLine().width;
+                    var isNearlyEqual:Boolean = Math.abs(l1End - l2End) < 0.1;
+                    assertTrue(isNearlyEqual);
+                    pa.paragraphEndIndent = 100;
+                }
+                else
+                    fail("Unknown direction " + this.writingDirection[1]);
+            }
+            else if (this.writingDirection[0] == BlockProgression.RL)
+            {
+                assertTrue(firstLine.y == secondLine.y);
+                pa.paragraphStartIndent = 100;
+            }
+            else
+                fail("Unknown blockProgression " + this.writingDirection[0]);
 
-			SelManager.applyParagraphFormat(pa);
-			SelManager.flushPendingOperations();
+            SelManager.applyParagraphFormat(pa);
+            SelManager.flushPendingOperations();
 
-			firstLine = lines[0];
-			testLines();
-		}
+            firstLine = lines[0];
+            testLines();
+        }
 
-		private function testLines():void
-		{
-			if (this.writingDirection[0] == BlockProgression.TB)
-			{
-				if (this.writingDirection[1] == Direction.LTR)
-				{
-					assertTrue("First = " + firstLine.x + ", Second = " + secondLine.x,
-						firstLine.x == secondLine.x + 100
-					);
-				}
-				else if (this.writingDirection[1] == Direction.RTL)
-				{
-					assertTrue("First = " + firstLine.targetWidth +
-							", Second = " + secondLine.targetWidth,
-						firstLine.targetWidth == secondLine.targetWidth - 100
-					);
-				}
-				else
-					fail("Unknown direction " + this.writingDirection[1]);
-			}
-			else if (this.writingDirection[0] == BlockProgression.RL)
-			{
-				assertTrue("First = " + firstLine.y + ", Second = " + secondLine.y,
-					firstLine.y == secondLine.y + 100
-				);
-			}
-			else
-				fail("Unknown blockProgression " + this.writingDirection[0]);
-		}
-	}
+        private function testLines():void
+        {
+            if (this.writingDirection[0] == BlockProgression.TB)
+            {
+                if (this.writingDirection[1] == Direction.LTR)
+                {
+                    assertTrue("First = " + firstLine.x + ", Second = " + secondLine.x,
+                            firstLine.x == secondLine.x + 100
+                    );
+                }
+                else if (this.writingDirection[1] == Direction.RTL)
+                {
+                    assertTrue("First = " + firstLine.targetWidth +
+                            ", Second = " + secondLine.targetWidth,
+                            firstLine.targetWidth == secondLine.targetWidth - 100
+                    );
+                }
+                else
+                    fail("Unknown direction " + this.writingDirection[1]);
+            }
+            else if (this.writingDirection[0] == BlockProgression.RL)
+            {
+                assertTrue("First = " + firstLine.y + ", Second = " + secondLine.y,
+                        firstLine.y == secondLine.y + 100
+                );
+            }
+            else
+                fail("Unknown blockProgression " + this.writingDirection[0]);
+        }
+    }
 }
