diff --git a/automation_tests/src/AllTestsSuite.as b/automation_tests/src/AllTestsSuite.as
index fe02fe5..1669dcf 100644
--- a/automation_tests/src/AllTestsSuite.as
+++ b/automation_tests/src/AllTestsSuite.as
@@ -49,6 +49,7 @@
     import UnitTest.Tests.SpacingTest;
     import UnitTest.Tests.TabTest;
     import UnitTest.Tests.TextFlowEditTest;
+    import UnitTest.Tests.TextLineFilterTest;
     import UnitTest.Tests.UndoRedoTest;
     import UnitTest.Tests.VerticalScrollingTest;
     import UnitTest.Tests.WritingModeTest;
@@ -90,6 +91,7 @@
         public var listTest:ListTest;
         public var linkTest:LinkTest;
         public var localeTest:LocaleTests;
+        public var textLineFilterTest:TextLineFilterTest;
     }
 
 }
diff --git a/automation_tests/src/UnitTest/Tests/TextLineFilterTest.as b/automation_tests/src/UnitTest/Tests/TextLineFilterTest.as
index 4c9f0f5..c36f924 100644
--- a/automation_tests/src/UnitTest/Tests/TextLineFilterTest.as
+++ b/automation_tests/src/UnitTest/Tests/TextLineFilterTest.as
@@ -26,142 +26,557 @@
 
 package UnitTest.Tests
 {
-	import UnitTest.ExtendedClasses.TestSuiteExtended;
-	import UnitTest.ExtendedClasses.VellumTestCase;
-	import UnitTest.Fixtures.TestConfig;
-	import UnitTest.Validation.MD5;
-	
-	import flash.display.Bitmap;
-	import flash.display.BitmapData;
-	import flash.display.DisplayObject;
-	import flash.display.IBitmapDrawable;
-	import flash.display.Sprite;
-	import flash.events.*;
-	import flash.filters.BitmapFilter;
-	import flash.filters.BitmapFilterQuality;
-	import flash.filters.BlurFilter;
-	import flash.geom.Rectangle;
-	import flash.system.*;
-	import flash.text.engine.*;
-	import flash.utils.ByteArray;
-	
-	import flashx.textLayout.*;
-	import flashx.textLayout.compose.StandardFlowComposer;
-	import flashx.textLayout.compose.TextLineRecycler;
-	import flashx.textLayout.container.ContainerController;
-	import flashx.textLayout.container.ScrollPolicy;
-	import flashx.textLayout.container.TextContainerManager;
-	import flashx.textLayout.conversion.TextConverter;
-	import flashx.textLayout.edit.EditManager;
-	import flashx.textLayout.edit.IEditManager;
-	import flashx.textLayout.edit.ISelectionManager;
-	import flashx.textLayout.edit.SelectionManager;
-	import flashx.textLayout.elements.*;
-	import flashx.textLayout.events.StatusChangeEvent;
-	import flashx.textLayout.events.UpdateCompleteEvent;
-	import flashx.textLayout.factory.StringTextLineFactory;
-	import flashx.textLayout.factory.TextFlowTextLineFactory;
-	import flashx.textLayout.formats.TextLayoutFormat;
-	
-	import mx.containers.Canvas;
-	import mx.core.ByteArrayAsset;
-	import mx.utils.LoaderUtil;
+    import UnitTest.ExtendedClasses.TestSuiteExtended;
+    import UnitTest.ExtendedClasses.VellumTestCase;
+    import UnitTest.Fixtures.TestConfig;
+    import UnitTest.Validation.MD5;
+
+    import flash.display.Bitmap;
+    import flash.display.BitmapData;
+    import flash.display.DisplayObject;
+    import flash.display.IBitmapDrawable;
+    import flash.display.Sprite;
+    import flash.geom.Rectangle;
+    import flash.system.*;
+    import flash.text.engine.*;
+    import flash.utils.ByteArray;
+
+    import flashx.textLayout.*;
+    import flashx.textLayout.compose.StandardFlowComposer;
+    import flashx.textLayout.compose.TextLineRecycler;
+    import flashx.textLayout.container.ContainerController;
+    import flashx.textLayout.container.ScrollPolicy;
+    import flashx.textLayout.container.TextContainerManager;
+    import flashx.textLayout.conversion.TextConverter;
+    import flashx.textLayout.edit.EditManager;
+    import flashx.textLayout.edit.ISelectionManager;
+    import flashx.textLayout.edit.SelectionManager;
+    import flashx.textLayout.elements.*;
+    import flashx.textLayout.factory.StringTextLineFactory;
+    import flashx.textLayout.factory.TextFlowTextLineFactory;
+    import flashx.textLayout.formats.TextLayoutFormat;
+
+    import mx.containers.Canvas;
+    import mx.core.ByteArrayAsset;
 
     import org.flexunit.asserts.assertTrue;
     import org.flexunit.asserts.fail;
 
     use namespace tlf_internal;
 
-	public class TextLineFilterTest extends VellumTestCase
-	{
-		private var displayobject:DisplayObject;
-		private var TestCanvas:Canvas = null;
-		private var ItemsToRemove:Array;
-		private var text:String = 'There are many such lime-kilns in that tract of country. ';
-		private var headingFlow:TextFlow;
+    [TestCase(order=34)]
+    public class TextLineFilterTest extends VellumTestCase
+    {
+        private var TestCanvas:Canvas = null;
+        private var itemsToRemove:Array;
         private var bodyFlow:TextFlow;
-        private var headController:CustomContainerController;
         private var bodyController:CustomContainerController;
+        private var bodyContainer:Sprite;
 
         private const bodyMarkup:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' fontSize='18' " +
                 "textIndent='10' paragraphSpaceBefore='6' paddingTop='8' paddingBottom='8' paddingLeft='8' paddingRight='8'>" +
-            "<flow:p paragraphSpaceBefore='inherit' >" +
+                "<flow:p paragraphSpaceBefore='inherit' >" +
                 "<flow:span>There are many </flow:span>" +
                 "<flow:span fontStyle='italic'>such</flow:span>" +
                 "<flow:span> lime-kilns in that tract of country, for the purpose of burning the white" +
-                    " marble which composes a large part of the substance of the hills. Some of them, built " +
-                    "years ago, and long deserted, with weeds growing in the vacant round of the interior, " +
-                    "which is open to the sky, and grass and wild-flowers rooting themselves into the chinks " +
-                    "of the stones, look already like relics of antiquity, and may yet be overspread with the" +
-                    " lichens of centuries to come. Others, where the lime-burner still feeds his daily and " +
-                    "nightlong fire, afford points of interest to the wanderer among the hills, who seats " +
-                    "himself on a log of wood or a fragment of marble, to hold a chat with the solitary man. " +
-                    "It is a lonesome, and, when the character is inclined to thought, may be an intensely " +
-                    "thoughtful occupation; as it proved in the case of Ethan Brand, who had mused to such " +
-                    "strange purpose, in days gone by, while the fire in this very kiln was burning.</flow:span>" +
-            "</flow:p>" +
-            "<flow:p paragraphSpaceBefore='inherit'>" +
+                " marble which composes a large part of the substance of the hills. Some of them, built " +
+                "years ago, and long deserted, with weeds growing in the vacant round of the interior, " +
+                "which is open to the sky, and grass and wild-flowers rooting themselves into the chinks " +
+                "of the stones, look already like relics of antiquity, and may yet be overspread with the" +
+                " lichens of centuries to come. Others, where the lime-burner still feeds his daily and " +
+                "nightlong fire, afford points of interest to the wanderer among the hills, who seats " +
+                "himself on a log of wood or a fragment of marble, to hold a chat with the solitary man. " +
+                "It is a lonesome, and, when the character is inclined to thought, may be an intensely " +
+                "thoughtful occupation; as it proved in the case of Ethan Brand, who had mused to such " +
+                "strange purpose, in days gone by, while the fire in this very kiln was burning.</flow:span>" +
+                "</flow:p>" +
+                "<flow:p paragraphSpaceBefore='inherit'>" +
                 "<flow:span>" +
-                    "The man who now watched the fire was of a different order, and troubled himself with no " +
-                    "thoughts save the very few that were requisite to his business. At frequent intervals, " +
-                    "he flung back the clashing weight of the iron door, and, turning his face from the " +
-                    "insufferable glare, thrust in huge logs of oak, or stirred the immense brands with a " +
-                    "long pole. Within the furnace were seen the curling and riotous flames, and the burning " +
-                    "marble, almost molten with the intensity of heat; while without, the reflection of the " +
-                    "fire quivered on the dark intricacy of the surrounding forest, and showed in the " +
-                    "foreground a bright and ruddy little picture of the hut, the spring beside its door, the " +
-                    "athletic and coal-begrimed figure of the lime-burner, and the halffrightened child, " +
-                    "shrinking into the protection of his father's shadow. And when again the iron door was " +
-                    "closed, then reappeared the tender light of the half-full moon, which vainly strove to " +
-                    "trace out the indistinct shapes of the neighboring mountains; and, in the upper sky, " +
-                    "there was a flitting congregation of clouds, still faintly tinged with the rosy sunset, " +
-                    "though thus far down into the valley the sunshine had vanished long and long ago.</flow:span>" +
-            "</flow:p>" +
-        "</flow:TextFlow>";
+                "The man who now watched the fire was of a different order, and troubled himself with no " +
+                "thoughts save the very few that were requisite to his business. At frequent intervals, " +
+                "he flung back the clashing weight of the iron door, and, turning his face from the " +
+                "insufferable glare, thrust in huge logs of oak, or stirred the immense brands with a " +
+                "long pole. Within the furnace were seen the curling and riotous flames, and the burning " +
+                "marble, almost molten with the intensity of heat; while without, the reflection of the " +
+                "fire quivered on the dark intricacy of the surrounding forest, and showed in the " +
+                "foreground a bright and ruddy little picture of the hut, the spring beside its door, the " +
+                "athletic and coal-begrimed figure of the lime-burner, and the halffrightened child, " +
+                "shrinking into the protection of his father's shadow. And when again the iron door was " +
+                "closed, then reappeared the tender light of the half-full moon, which vainly strove to " +
+                "trace out the indistinct shapes of the neighboring mountains; and, in the upper sky, " +
+                "there was a flitting congregation of clouds, still faintly tinged with the rosy sunset, " +
+                "though thus far down into the valley the sunshine had vanished long and long ago.</flow:span>" +
+                "</flow:p>" +
+                "</flow:TextFlow>";
 
-		// embed alice - this simplifies things - don't need to trust the swf and pass the xml around with it
-		[Embed(source="../../../../test/testFiles/markup/tlf/alice.xml",mimeType="application/octet-stream")]
-		private var AliceClass : Class;
+        /**
+         * embed alice - this simplifies things - don't need to trust the swf and pass the xml around with it
+         */
+        [Embed(source="../../../../test/testFiles/markup/tlf/alice.xml", mimeType="application/octet-stream")]
+        private var AliceClass:Class;
 
-		public function TextLineFilterTest(methodName:String, testID:String, testConfig:TestConfig, testCaseXML:XML=null)
-		{
-			ItemsToRemove = new Array();
-			super(methodName, testID, testConfig, testCaseXML);
-			//reset containerType and ID
-			containerType = "custom";
+        public function TextLineFilterTest()
+        {
+            itemsToRemove = [];
+            super("", "TextLineFilterTest", TestConfig.getInstance());
+            //reset containerType and ID
+            containerType = "custom";
 
-			// Note: These must correspond to a Watson product area (case-sensitive)
-			metaData.productArea = "Text Container";
-		}
+            metaData = {};
+            // Note: These must correspond to a Watson product area (case-sensitive)
+            metaData.productArea = "Text Container";
+        }
 
-		public static function suiteFromXML(testListXML:XML, testConfig:TestConfig, ts:TestSuiteExtended):void
- 		{
- 			var testCaseClass:Class = TextLineFilterTest;
- 			VellumTestCase.suiteFromXML(testCaseClass, testListXML, testConfig, ts);
- 		}
+        public static function suiteFromXML(testListXML:XML, testConfig:TestConfig, ts:TestSuiteExtended):void
+        {
+            var testCaseClass:Class = TextLineFilterTest;
+            VellumTestCase.suiteFromXML(testCaseClass, testListXML, testConfig, ts);
+        }
 
-		override public function setUpTest() : void
-		{
-			cleanUpTestApp();
-			TestDisplayObject = testApp.getDisplayObject();
-			if (TestDisplayObject)
-			{
-				TestCanvas = Canvas(TestDisplayObject);
-			}
-			else
-			{
-				fail("Did not get a blank canvas to work with");
-			}
+        [Before]
+        override public function setUpTest():void
+        {
+            cleanUpTestApp();
+            TestDisplayObject = testApp.getDisplayObject();
+            if (TestDisplayObject)
+            {
+                TestCanvas = Canvas(TestDisplayObject);
+            }
+            else
+            {
+                fail("Did not get a blank canvas to work with");
+            }
 
-		}
-		private var bodyContainer:Sprite;
-		public function initApp():void
-		{
-			// create body text flow, import body text, and assign flow composer
+        }
+
+        [After]
+        override public function tearDownTest():void
+        {
+            super.tearDownTest();
+        }
+
+        /**
+         * Apply a filter to the text lines and the selection
+         */
+        [Test]
+        public function textlineAndSelectionFilterTest():void
+        {
+            initApp();
+            bodyFlow.interactionManager = new SelectionManager();
+            var selectManager:ISelectionManager = bodyFlow.interactionManager;
+            selectManager.selectRange(0, 107);
+            selectManager.refreshSelection();
+
+            // add controller, add container to stage, and display body text
+            bodyFlow.flowComposer.addController(bodyController);
+            bodyFlow.flowComposer.updateAllControllers();
+
+
+            TestCanvas.rawChildren.addChild(DisplayObject(bodyContainer));
+            itemsToRemove.push(bodyContainer);
+            System.gc();	//mark
+            System.gc();	//sweep
+
+        }
+
+        /**
+         * Apply a filter to the text lines, but not the selection
+         */
+        [Test]
+        public function textlinesFilterTest():void
+        {
+            initApp();
+            bodyFlow.interactionManager = new SelectionManager();
+            var selectManager:ISelectionManager = bodyFlow.interactionManager;
+
+
+            // add controller, add container to stage, and display body text
+            bodyFlow.flowComposer.addController(bodyController);
+            bodyFlow.flowComposer.updateAllControllers();
+
+
+            TestCanvas.rawChildren.addChild(DisplayObject(bodyContainer));
+            itemsToRemove.push(bodyContainer);
+            System.gc();	//mark
+            System.gc();	//sweep
+        }
+
+        /**
+         * Apply a filter to the selection, but not the textline
+         */
+        [Test]
+        public function selectionFilterTest():void
+        {
+            initApp();
+            bodyFlow.interactionManager = new SelectionManager();
+            var selectManager:ISelectionManager = bodyFlow.interactionManager;
+            selectManager.selectRange(1000, 2000);
+            selectManager.refreshSelection();
+
+            // add controller, add container to stage, and display body text
+            bodyFlow.flowComposer.addController(bodyController);
+            bodyFlow.flowComposer.updateAllControllers();
+
+            TestCanvas.rawChildren.addChild(DisplayObject(bodyContainer));
+            itemsToRemove.push(bodyContainer);
+            System.gc();	//mark
+            System.gc();	//sweep
+        }
+
+        private var recycledTextLine:TextLine;
+        private var composedTextLine:TextLine;
+        private var _lines:Array;
+        private var textLine_invalid:TextLine;
+
+        private static function createInvalidTextLine():TextLine
+        {
+            var elementFormat:ElementFormat = new ElementFormat();
+            var textElement:TextElement = new TextElement("aaa", elementFormat);
+            var textBlock:TextBlock = new TextBlock(textElement);
+            var textLine:TextLine = textBlock.createTextLine();
+            textLine.validity = TextLineValidity.INVALID;
+            return textLine;
+        }
+
+        [Test]
+        public function recycleLineByFlowComposer():void
+        {
+            //create an invald TextLine to recycle
+            textLine_invalid = createInvalidTextLine();
+            //recycle the invalid TextLine
+            TextLineRecycler.emptyReusableLineCache();
+            TextLineRecycler.addLineForReuse(textLine_invalid);
+            recycledTextLine = textLine_invalid;
+
+            //create a TextFlow
+            var textFlow:TextFlow = new TextFlow();
+            textFlow.mxmlChildren = ["Hello, World"];
+            var textContainer:Sprite = new Sprite();
+            var textController:ContainerController = new CustomContainerController(textContainer, 800, 1000);
+            textFlow.flowComposer.addController(textController);
+
+            //compose a single line which should be from recycler
+            textFlow.flowComposer.updateAllControllers();
+            TestCanvas.rawChildren.addChild(DisplayObject(textContainer));
+
+            //check if the composed line is same as the recycled one
+            composedTextLine = textFlow.flowComposer.getLineAt(0).getTextLine();
+            assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine);
+        }
+
+        [Test]
+        public function recycleLineByFlowFactory():void
+        {
+            _lines = [];
+
+            //create an invald TextLine to recycle
+            textLine_invalid = createInvalidTextLine();
+
+            //recycle the invalid TextLine
+            TextLineRecycler.emptyReusableLineCache();
+            TextLineRecycler.addLineForReuse(textLine_invalid);
+            recycledTextLine = textLine_invalid;
+
+            var factory:TextFlowTextLineFactory = new TextFlowTextLineFactory();
+            factory.compositionBounds = new Rectangle(100, 100, 200, 130);
+            var flow:TextFlow = new TextFlow();
+            var span:SpanElement = new SpanElement();
+            span.text = "Hello World.";
+            var para:ParagraphElement = new ParagraphElement();
+            para.addChild(span);
+            flow.addChild(para);
+
+            //compose a single line which should be from recycler
+            factory.createTextLines(useTextLines, flow);
+
+            //check if the composed line is same as the recycled one
+            composedTextLine = _lines[0];
+            assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine);
+        }
+
+        [Test]
+        public function recycleLineByStringFactory():void
+        {
+            _lines = [];
+
+            //create an invald TextLine to recycle
+            textLine_invalid = createInvalidTextLine();
+
+            //recycle the invalid TextLine
+            TextLineRecycler.emptyReusableLineCache();
+            TextLineRecycler.addLineForReuse(textLine_invalid);
+            recycledTextLine = textLine_invalid;
+
+            var factory:StringTextLineFactory = new StringTextLineFactory();
+            factory.compositionBounds = new Rectangle(100, 100, 200, 130);
+            factory.text = "Hello World";
+
+            //compose a single line which should be from recycler
+            factory.createTextLines(useTextLines);
+
+            //check if the composed line is same as the recycled one
+            composedTextLine = _lines[0];
+            assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine);
+        }
+
+        [Test]
+        public function stringFactoryBackgroundColor():void
+        {
+            _lines = [];
+
+            var factory:StringTextLineFactory = new StringTextLineFactory();
+            factory.compositionBounds = new Rectangle(100, 100, 200, 130);
+            factory.text = "Hello World";
+
+            factory.textFlowFormat = TextLayoutFormat.createTextLayoutFormat({
+                blockProgression: writingDirection[0],
+                direction: writingDirection[1]
+            });
+            factory.spanFormat = TextLayoutFormat.createTextLayoutFormat({backgroundColor: 0xffff4F, fontSize: 48});
+            factory.createTextLines(useTextLines);
+        }
+
+        private function useTextLines(tl:DisplayObject):void
+        {
+            _lines.push(tl);
+            TestCanvas.rawChildren.addChild(tl);
+        }
+
+        [Test]
+        public function recycleLineByCustomLineCreatorTextFlow():void
+        {
+            //create an invald TextLine to recycle
+            textLine_invalid = createInvalidTextLine();
+
+            //recycle the invalid TextLine
+            TextLineRecycler.emptyReusableLineCache();
+            TextLineRecycler.addLineForReuse(textLine_invalid);
+            recycledTextLine = textLine_invalid;
+
+            //Create a TextFlow
+            var textFlow:TextFlow = new TextFlow();
+            textFlow.mxmlChildren = ["Hello, World"];
+            var textContainer:Sprite = new Sprite();
+            var textController:ContainerController = new CustomContainerController(textContainer, 800, 1000);
+            textFlow.flowComposer.addController(textController);
+
+            //monitor if the TextLine created from recycler
+            var myswfContext:MySwfContext = new MySwfContext();
+            textFlow.flowComposer.swfContext = myswfContext;
+            textFlow.flowComposer.updateAllControllers();
+
+            //check if composed line is same as recycled line and if createTextLine gets the recycled line
+            composedTextLine = textFlow.flowComposer.getLineAt(0).getTextLine();
+            assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine
+            && myswfContext.numRecycledLines == 1);
+
+            //monitor if the TextLine created from new
+            textFlow.mxmlChildren = ["Again, Hello, World "];
+            textFlow.flowComposer.swfContext = myswfContext;
+            textFlow.flowComposer.updateAllControllers();
+            assertTrue("The composed line is not newly created", myswfContext.numLinesCreated == 1);
+
+            TestCanvas.rawChildren.addChild(DisplayObject(textContainer));
+        }
+
+        [Test]
+        public function recycleLineByTCM():void
+        {
+            //create an invald TextLine to recycle
+            textLine_invalid = createInvalidTextLine();
+            //recycle the invalid TextLine
+            TextLineRecycler.emptyReusableLineCache();
+            TextLineRecycler.addLineForReuse(textLine_invalid);
+            recycledTextLine = textLine_invalid;
+
+            //create a TextFlow by TCM using the recycled line
+            var sprite:Sprite = new Sprite();
+            sprite.x = 50;
+            sprite.y = 50;
+            var tcm:TextContainerManager = new TextContainerManager(sprite);
+            tcm.setText("Hello World");
+            tcm.updateContainer();
+            var editManager:EditManager = EditManager(tcm.beginInteraction());
+            editManager.selectRange(0, 0);
+            var textFlow:TextFlow = tcm.getTextFlow();
+
+            //check if the composed line is same as the recycled one
+            composedTextLine = textFlow.flowComposer.getLineAt(0).getTextLine();
+            assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine);
+            TestCanvas.rawChildren.addChild(DisplayObject(sprite));
+            TestCanvas.rawChildren.addChild(sprite);
+        }
+
+        [Test]
+        public function recycleLineByCustomLineCreatorFlowFactory():void
+        {
+            _lines = [];
+
+            //create an invald TextLine to recycle
+            textLine_invalid = createInvalidTextLine();
+
+            //recycle the invalid TextLine
+            TextLineRecycler.emptyReusableLineCache();
+            TextLineRecycler.addLineForReuse(textLine_invalid);
+            recycledTextLine = textLine_invalid;
+
+            var factory:TextFlowTextLineFactory = new TextFlowTextLineFactory();
+            factory.compositionBounds = new Rectangle(100, 100, 200, 130);
+
+            //Create a TextFlow
+            var flow:TextFlow = new TextFlow();
+            flow.mxmlChildren = ["Hello, World"];
+
+            //create custom TextLine creator
+            var myswfContext:MySwfContext = new MySwfContext();
+            flow.flowComposer.swfContext = myswfContext;
+            factory.swfContext = flow.flowComposer.swfContext;
+
+            //compose a single line which should be from recycler using FlowFactory
+            factory.createTextLines(useTextLines, flow);
+
+            //check if the composed line is same as the recycled one
+            composedTextLine = _lines[0];
+            assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine
+            && myswfContext.numRecycledLines == 1);
+
+            //monitor if the TextLine created from new
+            flow.mxmlChildren = ["Again, Hello, World "];
+            factory.compositionBounds = new Rectangle(100, 200, 200, 130);
+            factory.createTextLines(useTextLines, flow);
+            assertTrue("The composed line is not newly created", myswfContext.numLinesCreated == 1);
+        }
+
+        [Test]
+        public function recycleLineByCustomLineCreatorStringFactory():void
+        {
+            _lines = [];
+
+            //create an invald TextLine to recycle
+            textLine_invalid = createInvalidTextLine();
+
+            //recycle the invalid TextLine
+            TextLineRecycler.emptyReusableLineCache();
+            TextLineRecycler.addLineForReuse(textLine_invalid);
+            recycledTextLine = textLine_invalid;
+
+            var factory:StringTextLineFactory = new StringTextLineFactory();
+            factory.compositionBounds = new Rectangle(100, 100, 200, 130);
+            factory.text = "Hello World";
+
+            //create custom TextLine creator
+            var myswfContext:MySwfContext = new MySwfContext();
+            factory.swfContext = myswfContext;
+
+            //compose a single line which should be from recycler using FlowFactory
+            factory.createTextLines(useTextLines);
+
+            //check if the composed line is same as the recycled one
+            composedTextLine = _lines[0];
+            assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine
+            && myswfContext.numRecycledLines == 1);
+
+            //monitor if the TextLine created from new
+            factory.text = "Again, Hello World";
+            factory.compositionBounds = new Rectangle(100, 200, 200, 130);
+            factory.createTextLines(useTextLines);
+            assertTrue("The composed line is not newly created", myswfContext.numLinesCreated == 1);
+        }
+
+        [Test]
+        public function recycleLineByCustomLineCreatorTCM():void
+        {
+            _lines = [];
+
+            //create an invald TextLine to recycle
+            textLine_invalid = createInvalidTextLine();
+
+            //recycle the invalid TextLine
+            TextLineRecycler.emptyReusableLineCache();
+            TextLineRecycler.addLineForReuse(textLine_invalid);
+            recycledTextLine = textLine_invalid;
+
+            //create a TextFlow by TCM using the recycled line
+            var sprite:Sprite = new Sprite();
+            sprite.x = 50;
+            sprite.y = 50;
+            var tcm:TextContainerManager = new TextContainerManager(sprite);
+            tcm.setText("Hello World");
+            tcm.updateContainer();
+            var editManager:EditManager = EditManager(tcm.beginInteraction());
+            editManager.selectRange(0, 0);
+            var textFlow:TextFlow = tcm.getTextFlow();
+
+            //check if the composed line is same as the recycled one
+            composedTextLine = textFlow.flowComposer.getLineAt(0).getTextLine();
+            assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine);
+            TestCanvas.rawChildren.addChild(sprite);
+        }
+
+        [Test]
+        public function recycleLineInSuite():void
+        {
+            var alice:ByteArrayAsset = new AliceClass();
+            var aliceData:String = alice.readMultiByte(alice.length, "utf-8");
+            var textFlow:TextFlow = TextConverter.importToFlow(aliceData, TextConverter.TEXT_LAYOUT_FORMAT);
+
+            TextLineRecycler.emptyReusableLineCache();
+            TextLineRecycler.textLineRecyclerEnabled = false;
+            var s:Sprite = new Sprite();
+            s.x = 50;
+            s.y = 50;
+            var tcm:TextContainerManager = new TextContainerManager(s);
+            tcm.compositionWidth = 500;
+            tcm.compositionHeight = NaN;
+            tcm.setTextFlow(textFlow);
+            tcm.updateContainer();
+
+            var displayobject:DisplayObject = testApp.getDisplayObject();
+            var bits:BitmapData = new BitmapData(displayobject.width, displayobject.height);
+            bits.draw(TestDisplayObject as IBitmapDrawable);
+            bitmapSnapshot = new Bitmap(bits);
+            bits = null;
+            var pixels:ByteArray = bitmapSnapshot.bitmapData.getPixels(bitmapSnapshot.bitmapData.rect);
+            pixels.compress();
+            pixels.position = 0;
+            var checksumRecyclingOff:String = MD5.hashBinary(pixels);
+
+            //create a bunch(100) of invald TextLines to recycle
+            TextLineRecycler.emptyReusableLineCache();
+            TextLineRecycler.textLineRecyclerEnabled = true;
+            var i:int = 0;
+            while (i <= 100)
+            {
+                var textLine_invalid:TextLine = createInvalidTextLine();
+                TextLineRecycler.addLineForReuse(textLine_invalid);
+                i++;
+            }
+
+            //recompose the text flow with the recycled lines
+            tcm.updateContainer();
+
+            //get checksum for recycling on
+            var bits_2:BitmapData = new BitmapData(displayobject.width, displayobject.height);
+            bits_2.draw(TestDisplayObject as IBitmapDrawable);
+            bitmapSnapshot = new Bitmap(bits_2);
+            bits_2 = null;
+            pixels = bitmapSnapshot.bitmapData.getPixels(bitmapSnapshot.bitmapData.rect);
+            pixels.compress();
+            pixels.position = 0;
+            var checksumRecyclingOn:String = MD5.hashBinary(pixels);
+
+            //check if there is any rendering difference
+            assertTrue("the rendering changed between recycle on and off.", checksumRecyclingOn == checksumRecyclingOff);
+            TestCanvas.rawChildren.addChild(DisplayObject(s));
+        }
+
+        private function initApp():void
+        {
+            // create body text flow, import body text, and assign flow composer
             bodyFlow = new TextFlow();
             bodyFlow = TextConverter.importToFlow(bodyMarkup, TextConverter.TEXT_LAYOUT_FORMAT);
             bodyFlow.flowComposer = new StandardFlowComposer();
-			bodyContainer = new Sprite();
+            bodyContainer = new Sprite();
             bodyController = new CustomContainerController(bodyContainer, 800, 1000);
             bodyController.updateCompositionShapes();
             //bodyController.addTextLine(tl1, 0);
@@ -174,583 +589,123 @@
             bodyController.format = bodyContainerFormat;
             // enable scrolling
             bodyController.verticalScrollPolicy = ScrollPolicy.AUTO;
-		}
-
- 		/**
-		 * Apply a filter to the text lines and the selection
-		 */
-		public function textlineAndSelectionFilterTest():void
-		{
-			initApp();
-            bodyFlow.interactionManager = new SelectionManager();
-            var selectManager:ISelectionManager = bodyFlow.interactionManager;
-            selectManager.selectRange(0, 107);
-            selectManager.refreshSelection();
-
-            // add controller, add container to stage, and display body text
-            bodyFlow.flowComposer.addController(bodyController);
-            bodyFlow.flowComposer.updateAllControllers();
-
-
-
-			TestCanvas.rawChildren.addChild(DisplayObject(bodyContainer));
-			ItemsToRemove.push(bodyContainer);
-			System.gc();	//mark
-			System.gc();	//sweep
-
-		}
-
-		public function getBitmapFilter():BitmapFilter {
-            var blurX:Number = 3;
-            var blurY:Number = 3;
-            return new BlurFilter(blurX, blurY, BitmapFilterQuality.HIGH);
         }
-
- 		/**
-		 * Apply a filter to the text lines, but not the selection
-		 */
-
-		public function textlinesFilterTest():void
-		{
-			initApp();
-            bodyFlow.interactionManager = new SelectionManager();
-            var selectManager:ISelectionManager = bodyFlow.interactionManager;
-
-
-            // add controller, add container to stage, and display body text
-            bodyFlow.flowComposer.addController(bodyController);
-            bodyFlow.flowComposer.updateAllControllers();
-
-
-
-			TestCanvas.rawChildren.addChild(DisplayObject(bodyContainer));
-			ItemsToRemove.push(bodyContainer);
-			System.gc();	//mark
-			System.gc();	//sweep
-		}
-
-		/**
-		 * Apply a filter to the selection, but not the textline
-		 */
-		public function selectionFilterTest():void
-		{
-			initApp();
-            bodyFlow.interactionManager = new SelectionManager();
-            var selectManager:ISelectionManager = bodyFlow.interactionManager;
-            selectManager.selectRange(1000, 2000);
-            selectManager.refreshSelection();
-
-            // add controller, add container to stage, and display body text
-            bodyFlow.flowComposer.addController(bodyController);
-            bodyFlow.flowComposer.updateAllControllers();
-
-			TestCanvas.rawChildren.addChild(DisplayObject(bodyContainer));
-			ItemsToRemove.push(bodyContainer);
-			System.gc();	//mark
-			System.gc();	//sweep
-		}
-
-		private var recycledTextLine:TextLine;
-		private var composedTextLine:TextLine;
-		private var _lines:Array;
-		private var textLine_invalid:TextLine;
-
-		private static function createInvalidTextLine():TextLine
-		{
-			var elementFormat:ElementFormat = new ElementFormat();
-			var textElement:TextElement = new TextElement("aaa", elementFormat)
-			var textBlock:TextBlock = new TextBlock(textElement);
-			var textLine:TextLine = textBlock.createTextLine();
-			textLine.validity = TextLineValidity.INVALID;
-			return textLine;
-		}
-
-		public function recycleLineByFlowComposer():void
-		{
-			//create an invald TextLine to recycle
-			textLine_invalid = createInvalidTextLine();
-			//recycle the invalid TextLine
-			TextLineRecycler.emptyReusableLineCache();
-			TextLineRecycler.addLineForReuse(textLine_invalid);
-			recycledTextLine = textLine_invalid;
-
-			//create a TextFlow
-			var textFlow:TextFlow = new TextFlow();
-			textFlow.mxmlChildren = [ "Hello, World" ];
-			var textContainer:Sprite = new Sprite();
-			var textController:ContainerController = new CustomContainerController(textContainer, 800, 1000);
-			textFlow.flowComposer.addController(textController);
-
-			//compose a single line which should be from recycler
-			textFlow.flowComposer.updateAllControllers();
-			TestCanvas.rawChildren.addChild(DisplayObject(textContainer));
-
-			//check if the composed line is same as the recycled one
-			composedTextLine = textFlow.flowComposer.getLineAt(0).getTextLine();
-			assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine);
-		}
-
-		public function recycleLineByFlowFactory():void
-		{
-			_lines = new Array();
-
-			//create an invald TextLine to recycle
-			textLine_invalid = createInvalidTextLine();
-
-			//recycle the invalid TextLine
-			TextLineRecycler.emptyReusableLineCache();
-			TextLineRecycler.addLineForReuse(textLine_invalid);
-			recycledTextLine = textLine_invalid;
-
-			var factory:TextFlowTextLineFactory = new TextFlowTextLineFactory();
-			factory.compositionBounds = new Rectangle( 100, 100, 200, 130 );
-			var flow:TextFlow = new TextFlow();
-			var span:SpanElement = new SpanElement();
-			span.text = "Hello World.";
-			var para:ParagraphElement = new ParagraphElement();
-			para.addChild( span );
-			flow.addChild( para );
-
-			//compose a single line which should be from recycler
-			factory.createTextLines(useTextLines, flow );
-
-			//check if the composed line is same as the recycled one
-			composedTextLine = _lines[0];
-			assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine);
-		}
-
-		public function recycleLineByStringFactory():void
-		{
-			_lines = new Array();
-
-			//create an invald TextLine to recycle
-			textLine_invalid = createInvalidTextLine();
-
-			//recycle the invalid TextLine
-			TextLineRecycler.emptyReusableLineCache();
-			TextLineRecycler.addLineForReuse(textLine_invalid);
-			recycledTextLine = textLine_invalid;
-
-			var factory:StringTextLineFactory = new StringTextLineFactory();
-			factory.compositionBounds = new Rectangle( 100, 100, 200, 130 );
-			factory.text = "Hello World";
-
-			//compose a single line which should be from recycler
-			factory.createTextLines(useTextLines);
-
-			//check if the composed line is same as the recycled one
-			composedTextLine = _lines[0];
-			assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine);
-		}
-		
-		public function stringFactoryBackgroundColor():void
-		{
-			_lines = new Array();
-			
-			var factory:StringTextLineFactory = new StringTextLineFactory();
-			factory.compositionBounds = new Rectangle( 100, 100, 200, 130 );
-			factory.text = "Hello World";
-			
-			factory.textFlowFormat = TextLayoutFormat.createTextLayoutFormat({blockProgression:writingDirection[0],direction:writingDirection[1]});
-			factory.spanFormat = TextLayoutFormat.createTextLayoutFormat({backgroundColor:0xffff4F,fontSize:48});
-			factory.createTextLines(useTextLines);
-		}
-
-		private function useTextLines( tl:DisplayObject ):void
-		{
-			_lines.push(tl);
-			TestCanvas.rawChildren.addChild( tl );
-		}
-
-		public function recycleLineByCustomLineCreatorTextFlow():void
-		{
-			//create an invald TextLine to recycle
-			textLine_invalid = createInvalidTextLine();
-
-			//recycle the invalid TextLine
-			TextLineRecycler.emptyReusableLineCache();
-			TextLineRecycler.addLineForReuse(textLine_invalid);
-			recycledTextLine = textLine_invalid;
-
-			//Create a TextFlow
-			var textFlow:TextFlow = new TextFlow();
-			textFlow.mxmlChildren = [ "Hello, World" ];
-			var textContainer:Sprite = new Sprite();
-			var textController:ContainerController = new CustomContainerController(textContainer, 800, 1000);
-			textFlow.flowComposer.addController(textController);
-
-			//monitor if the TextLine created from recycler
-			var myswfContext:MySwfContext = new MySwfContext()
-			textFlow.flowComposer.swfContext = myswfContext;
-			textFlow.flowComposer.updateAllControllers();
-
-			//check if composed line is same as recycled line and if createTextLine gets the recycled line
-			composedTextLine = textFlow.flowComposer.getLineAt(0).getTextLine();
-			assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine
-				&& myswfContext.numRecycledLines == 1);
-
-			//monitor if the TextLine created from new
-			textFlow.mxmlChildren = [ "Again, Hello, World " ];
-			textFlow.flowComposer.swfContext = myswfContext;
-			textFlow.flowComposer.updateAllControllers();
-			assertTrue("The composed line is not newly created", myswfContext.numLinesCreated == 1);
-
-			TestCanvas.rawChildren.addChild(DisplayObject(textContainer));
-		}
-
-		public function recycleLineByTCM():void
-		{
-			//create an invald TextLine to recycle
-			textLine_invalid = createInvalidTextLine();
-			//recycle the invalid TextLine
-			TextLineRecycler.emptyReusableLineCache();
-			TextLineRecycler.addLineForReuse(textLine_invalid);
-			recycledTextLine = textLine_invalid;
-
-			//create a TextFlow by TCM using the recycled line
-			var sprite:Sprite = new Sprite();
-			sprite.x = 50; sprite.y = 50;
-			var tcm:TextContainerManager = new TextContainerManager(sprite);
-			tcm.setText("Hello World");
-			tcm.updateContainer();
-			var editManager:EditManager = EditManager(tcm.beginInteraction())
-			editManager.selectRange(0, 0);
-			var textFlow:TextFlow = tcm.getTextFlow();
-
-			//check if the composed line is same as the recycled one
-			composedTextLine = textFlow.flowComposer.getLineAt(0).getTextLine();
-			assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine);
-			TestCanvas.rawChildren.addChild(DisplayObject(sprite));
-			TestCanvas.rawChildren.addChild(sprite);
-		}
-
-		public function recycleLineByCustomLineCreatorFlowFactory():void
-		{
-			_lines = new Array();
-
-			//create an invald TextLine to recycle
-			textLine_invalid = createInvalidTextLine();
-
-			//recycle the invalid TextLine
-			TextLineRecycler.emptyReusableLineCache();
-			TextLineRecycler.addLineForReuse(textLine_invalid);
-			recycledTextLine = textLine_invalid;
-
-			var factory:TextFlowTextLineFactory = new TextFlowTextLineFactory();
-			factory.compositionBounds = new Rectangle( 100, 100, 200, 130 );
-
-			//Create a TextFlow
-			var flow:TextFlow = new TextFlow();
-			flow.mxmlChildren = [ "Hello, World" ];
-
-			//create custom TextLine creator
-			var myswfContext:MySwfContext = new MySwfContext()
-			flow.flowComposer.swfContext = myswfContext;
-			factory.swfContext = flow.flowComposer.swfContext;
-
-			//compose a single line which should be from recycler using FlowFactory
-			factory.createTextLines(useTextLines, flow );
-
-			//check if the composed line is same as the recycled one
-			composedTextLine = _lines[0];
-			assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine
-			&& myswfContext.numRecycledLines == 1);
-
-			//monitor if the TextLine created from new
-			flow.mxmlChildren = [ "Again, Hello, World " ];
-			factory.compositionBounds = new Rectangle( 100, 200, 200, 130 );
-			factory.createTextLines(useTextLines, flow );
-			assertTrue("The composed line is not newly created", myswfContext.numLinesCreated == 1);
-		}
-
-		public function recycleLineByCustomLineCreatorStringFactory():void
-		{
-			_lines = new Array();
-
-			//create an invald TextLine to recycle
-			textLine_invalid = createInvalidTextLine();
-
-			//recycle the invalid TextLine
-			TextLineRecycler.emptyReusableLineCache();
-			TextLineRecycler.addLineForReuse(textLine_invalid);
-			recycledTextLine = textLine_invalid;
-
-			var factory:StringTextLineFactory = new StringTextLineFactory();
-			factory.compositionBounds = new Rectangle( 100, 100, 200, 130 );
-			factory.text = "Hello World";
-
-			//create custom TextLine creator
-			var myswfContext:MySwfContext = new MySwfContext()
-			factory.swfContext = myswfContext;
-
-			//compose a single line which should be from recycler using FlowFactory
-			factory.createTextLines(useTextLines);
-
-			//check if the composed line is same as the recycled one
-			composedTextLine = _lines[0];
-			assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine
-			&& myswfContext.numRecycledLines == 1);
-
-			//monitor if the TextLine created from new
-			factory.text = "Again, Hello World";
-			factory.compositionBounds = new Rectangle( 100, 200, 200, 130 );
-			factory.createTextLines(useTextLines);
-			assertTrue("The composed line is not newly created", myswfContext.numLinesCreated == 1);
-		}
-
-		public function recycleLineByCustomLineCreatorTCM():void
-		{
-			_lines = new Array();
-
-			//create an invald TextLine to recycle
-			textLine_invalid = createInvalidTextLine();
-
-			//recycle the invalid TextLine
-			TextLineRecycler.emptyReusableLineCache();
-			TextLineRecycler.addLineForReuse(textLine_invalid);
-			recycledTextLine = textLine_invalid;
-
-			//create a TextFlow by TCM using the recycled line
-			var sprite:Sprite = new Sprite();
-			sprite.x = 50; sprite.y = 50;
-			var tcm:TextContainerManager = new TextContainerManager(sprite);
-			tcm.setText("Hello World");
-			tcm.updateContainer();
-			var editManager:EditManager = EditManager(tcm.beginInteraction());
-			editManager.selectRange(0, 0);
-			var textFlow:TextFlow = tcm.getTextFlow();
-
-			//check if the composed line is same as the recycled one
-			composedTextLine = textFlow.flowComposer.getLineAt(0).getTextLine();
-			assertTrue("The composed line is not same as recycled line.", recycledTextLine === composedTextLine);
-			TestCanvas.rawChildren.addChild(sprite);
-		}
-
-		public function recycleLineInSuite():void
-		{
-			var alice:ByteArrayAsset = new AliceClass();
-			var aliceData:String = alice.readMultiByte(alice.length,"utf-8");
-			var textFlow:TextFlow = TextConverter.importToFlow(aliceData, TextConverter.TEXT_LAYOUT_FORMAT);
-
-			TextLineRecycler.emptyReusableLineCache();
-			TextLineRecycler.textLineRecyclerEnabled = false;
-			var s:Sprite = new Sprite();
-			s.x = 50; s.y = 50;
-			var tcm:TextContainerManager = new TextContainerManager(s);
-			tcm.compositionWidth = 500;
-			tcm.compositionHeight = NaN;
-			tcm.setTextFlow(textFlow);
-			tcm.updateContainer();
-
-			displayobject = testApp.getDisplayObject();
-			var bits:BitmapData = new BitmapData(displayobject.width, displayobject.height);
-			bits.draw(TestDisplayObject as IBitmapDrawable);
-			bitmapSnapshot = new Bitmap(bits);
-			bits = null;
-			var pixels:ByteArray = bitmapSnapshot.bitmapData.getPixels(bitmapSnapshot.bitmapData.rect);
-			pixels.compress();
-			pixels.position = 0;
-			var checksumRecyclingOff:String = MD5.hashBinary(pixels);
-
-			//create a bunch(100) of invald TextLines to recycle
-			TextLineRecycler.emptyReusableLineCache();
-			TextLineRecycler.textLineRecyclerEnabled = true;
-			var i:int = 0;
-			while (i<=100)
-			{
-				var textLine_invalid:TextLine = createInvalidTextLine();
-				TextLineRecycler.addLineForReuse(textLine_invalid);
-				i++;
-			}
-
-			//recompose the text flow with the recycled lines
-			tcm.updateContainer();
-
-			//get checksum for recycling on
-			var bits_2:BitmapData = new BitmapData(displayobject.width, displayobject.height);
-			bits_2.draw(TestDisplayObject as IBitmapDrawable);
-			bitmapSnapshot = new Bitmap(bits_2);
-			bits_2 = null;
-			pixels = bitmapSnapshot.bitmapData.getPixels(bitmapSnapshot.bitmapData.rect);
-			pixels.compress();
-			pixels.position = 0;
-			var checksumRecyclingOn:String = MD5.hashBinary(pixels);
-
-			//check if there is any rendering difference
-			assertTrue("the rendering changed between recycle on and off.", checksumRecyclingOn == checksumRecyclingOff);
-			TestCanvas.rawChildren.addChild(DisplayObject(s));
-		}
-		
-		private var tf:TextFlow = new TextFlow();
-		
-		public function embeddedInlineGraphics(callback:Object = null):void
-		{	
-			if(!callback)
-			{
-				callback = true;
-				//tf.addEventListener(StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE,addAsync(embeddedInlineGraphics,2500,null),false,0,true);
-				var TestCanvas:Canvas;
-				TestDisplayObject = testApp.getDisplayObject();
-				if (TestDisplayObject)
-				{
-					TestCanvas = Canvas(TestDisplayObject);
-				}
-				
-				var container:Sprite = new Sprite();
-				TestCanvas.rawChildren.addChild(container);
-
-				var p:ParagraphElement = new ParagraphElement();
-				var span:SpanElement = new SpanElement();
-				
-				// add text to the span
-				span.text = "AAAAAAAA";
-				
-				p.addChild(span);
-				tf.addChild(p);
-				
-				// update controller to display text
-				var controller:ContainerController = new CustomContainerController(container, 400, 200);
-				tf.flowComposer.addController(controller);
-				tf.flowComposer.updateAllControllers();
-				
-				var src:String = "smiley.gif";
-				var width:int = 20;
-				var height:int = 20;
-				var baseImageURL:String = LoaderUtil.createAbsoluteURL(baseURL, "../../test/testFiles/assets/");
-				var selectManager:IEditManager = new EditManager();
-				tf.interactionManager = selectManager;
-						
-				selectManager.setFocus();
-				selectManager.selectRange(3, 3);
-				
-				var inlineGraphicElement:InlineGraphicElement = selectManager.insertInlineGraphic(LoaderUtil.createAbsoluteURL(baseImageURL,src),width,height);
-				tf.flowComposer.updateAllControllers();				
-			}
-			else // Make sure the image is ready before we let the snapshot go
-			{
-					
-				var img:InlineGraphicElement = tf.findLeaf(3) as InlineGraphicElement;
-				if(img.status != InlineGraphicElementStatus.READY)
-				{
-					//tf.addEventListener(StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE,addAsync(embeddedInlineGraphics,2500,null),false,0,true);
-				}
-			}
-			
-		}
-	}
+    }
 }
 
 import flash.display.BlendMode;
-import flash.display.Sprite;
-import flash.display.Shape;
-import flash.display.DisplayObjectContainer;
-import flash.text.engine.TextLine;
-import flashx.textLayout.container.ContainerController;
-import flash.filters.*;
-import flashx.textLayout.tlf_internal;
 import flash.display.DisplayObject;
+import flash.display.DisplayObjectContainer;
+import flash.display.Shape;
+import flash.display.Sprite;
+import flash.filters.*;
+import flash.text.engine.TextBlock;
+import flash.text.engine.TextLine;
+
+import flashx.textLayout.compose.ISWFContext;
+import flashx.textLayout.container.ContainerController;
+import flashx.textLayout.elements.Configuration;
+import flashx.textLayout.tlf_internal;
 
 use namespace tlf_internal;
 
 class CustomContainerController extends ContainerController
 {
-	
-	public function CustomContainerController(container:Sprite,compositionWidth:Number=100,compositionHeight:Number=100)
-	{
-		super(container,compositionWidth,compositionHeight);
 
-		// We'll put all text lines in a nested container
- 		// Filters applied to this container won't affect other objects like selection or background shapes
-		_textLineContainer = new Sprite();
-		//_textLineContainer.filters = [ new DropShadowFilter() ]; // apply a filter  (for illustration)
-		container.addChild(_textLineContainer);
- 	}
-	// Return the index where the first text line should appear in its parent
-	// Since our _textLineContainer only holds text lines, return zero
-	protected override function getFirstTextLineChildIndex():int
-	{
-		return 0;
-	}
-	// Add a text line at the specified index
-	protected override function addTextLine(textLine:TextLine, index:int):void
-	{
-    	if(index == 0)
-        textLine.filters = [ new BlurFilter(3, 3, BitmapFilterQuality.HIGH) ];
+    public function CustomContainerController(container:Sprite, compositionWidth:Number = 100, compositionHeight:Number = 100)
+    {
+        super(container, compositionWidth, compositionHeight);
+
+        // We'll put all text lines in a nested container
+        // Filters applied to this container won't affect other objects like selection or background shapes
+        _textLineContainer = new Sprite();
+        //_textLineContainer.filters = [ new DropShadowFilter() ]; // apply a filter  (for illustration)
+        container.addChild(_textLineContainer);
+    }
+
+    // Return the index where the first text line should appear in its parent
+    // Since our _textLineContainer only holds text lines, return zero
+    protected override function getFirstTextLineChildIndex():int
+    {
+        return 0;
+    }
+
+    // Add a text line at the specified index
+    protected override function addTextLine(textLine:TextLine, index:int):void
+    {
+        if (index == 0)
+            textLine.filters = [new BlurFilter(3, 3, BitmapFilterQuality.HIGH)];
         _textLineContainer.addChildAt(textLine, index);
-	}
-	
-	protected override function addInlineGraphicElement(parent:DisplayObjectContainer, inlineGraphicElement:DisplayObject, index:int):void
-	{
-		parent.addChildAt(inlineGraphicElement, index);
-		
-	}	
-	
-	// Remove a text line, but only if it is in _textLineContainer
-	// (A text line may have moved to another container because of 'shuffling')
-	protected override function removeTextLine(textLine:TextLine):void
-	{
-		if (_textLineContainer.contains(textLine))
-		{
-			textLine.filters = null;
-  			_textLineContainer.removeChild(textLine);
-		}
-	}
+    }
 
-	// Add the container for selection shapes (block or point selection)
-	protected override function addSelectionContainer(selectionContainer:DisplayObjectContainer):void
-	{
-		// If selection container is opaque or has normal blend mode, put selection container behind the text lines, else in front
-		var filter:BlurFilter = new BlurFilter(10, 10, BitmapFilterQuality.HIGH);
-        var myFilters:Array = new Array();
+    protected override function addInlineGraphicElement(parent:DisplayObjectContainer, inlineGraphicElement:DisplayObject, index:int):void
+    {
+        parent.addChildAt(inlineGraphicElement, index);
+
+    }
+
+    // Remove a text line, but only if it is in _textLineContainer
+    // (A text line may have moved to another container because of 'shuffling')
+    protected override function removeTextLine(textLine:TextLine):void
+    {
+        if (_textLineContainer.contains(textLine))
+        {
+            textLine.filters = null;
+            _textLineContainer.removeChild(textLine);
+        }
+    }
+
+    // Add the container for selection shapes (block or point selection)
+    protected override function addSelectionContainer(selectionContainer:DisplayObjectContainer):void
+    {
+        // If selection container is opaque or has normal blend mode, put selection container behind the text lines, else in front
+        var filter:BlurFilter = new BlurFilter(10, 10, BitmapFilterQuality.HIGH);
+        var myFilters:Array = [];
         myFilters.push(filter);
         selectionContainer.filters = myFilters;
-		var index:int = selectionContainer.blendMode == BlendMode.NORMAL && selectionContainer.alpha == 1 ? container.getChildIndex(_textLineContainer) : container.numChildren;
-		container.addChildAt(selectionContainer, index);
-	}
+        var index:int = selectionContainer.blendMode == BlendMode.NORMAL && selectionContainer.alpha == 1 ? container.getChildIndex(_textLineContainer) : container.numChildren;
+        container.addChildAt(selectionContainer, index);
+    }
 
-	// Remove the container for selection shapes
-	protected override function removeSelectionContainer(selectionContainer:DisplayObjectContainer):void
-	{
-		container.removeChild(selectionContainer);
-	}
+    // Remove the container for selection shapes
+    protected override function removeSelectionContainer(selectionContainer:DisplayObjectContainer):void
+    {
+        container.removeChild(selectionContainer);
+    }
 
-	// Add the background shape
-	protected override function addBackgroundShape(shape:Shape):void
-	{
-		container.addChildAt(shape, 0); // behind everything else, so use index 0
-	}
-	private var _textLineContainer:Sprite;
+    // Add the background shape
+    protected override function addBackgroundShape(shape:Shape):void
+    {
+        container.addChildAt(shape, 0); // behind everything else, so use index 0
+    }
+
+    private var _textLineContainer:Sprite;
 
 }
 
-import flashx.textLayout.formats.TextLayoutFormat;
-import flashx.textLayout.compose.ISWFContext;
-import flash.text.engine.TextBlock;
-import flashx.textLayout.elements.Configuration;
-
 class MySwfContext implements ISWFContext
 {
-	public var numLinesCreated:int = 0;
-	public var numRecycledLines:int = 0;
+    public var numLinesCreated:int = 0;
+    public var numRecycledLines:int = 0;
 
-	public function callInContext(fn:Function, thisArg:Object, argsArray:Array, returns:Boolean=true):*
-	{
-		var textBlock:TextBlock = thisArg as TextBlock;
-		if (textBlock)
-		{
-			if (fn == textBlock.createTextLine)
-			{
-				numLinesCreated++;      // COUNT: create a new TextLine
-			}
-			else if (Configuration.playerEnablesArgoFeatures && fn == thisArg["recreateTextLine"])
-			{
-				numRecycledLines++;     // COUNT: make a TextLine using a recycled line
-			}
-		}
-		if (returns)
-			return fn.apply(thisArg, argsArray);
-		fn.apply(thisArg, argsArray);
-	}
+    public function callInContext(fn:Function, thisArg:Object, argsArray:Array, returns:Boolean = true):*
+    {
+        var textBlock:TextBlock = thisArg as TextBlock;
+        if (textBlock)
+        {
+            if (fn == textBlock.createTextLine)
+            {
+                numLinesCreated++;      // COUNT: create a new TextLine
+            }
+            else if (Configuration.playerEnablesArgoFeatures && fn == thisArg["recreateTextLine"])
+            {
+                numRecycledLines++;     // COUNT: make a TextLine using a recycled line
+            }
+        }
+        if (returns)
+            return fn.apply(thisArg, argsArray);
+        fn.apply(thisArg, argsArray);
+    }
 }
 
 
