diff --git a/automation_tests/src/AllTestsSuite.as b/automation_tests/src/AllTestsSuite.as
index 9690325..d2caa00 100644
--- a/automation_tests/src/AllTestsSuite.as
+++ b/automation_tests/src/AllTestsSuite.as
@@ -39,6 +39,7 @@
     import UnitTest.Tests.GeneralFunctionsTest;
     import UnitTest.Tests.HorizontalScrollingTest;
     import UnitTest.Tests.ImpliedParagraphTest;
+    import UnitTest.Tests.ImportAPITest;
     import UnitTest.Tests.OperationTest;
     import UnitTest.Tests.ScrollingTest;
     import UnitTest.Tests.TabTest;
@@ -76,6 +77,7 @@
         public var tabTest:TabTest;
         public var horizontalScrollingTest:HorizontalScrollingTest;
         public var impliedParagraphTest:ImpliedParagraphTest;
+        public var importApiTest:ImportAPITest;
     }
 
 }
diff --git a/automation_tests/src/UnitTest/Tests/ImportAPITest.as b/automation_tests/src/UnitTest/Tests/ImportAPITest.as
index b0d251d..075818b 100644
--- a/automation_tests/src/UnitTest/Tests/ImportAPITest.as
+++ b/automation_tests/src/UnitTest/Tests/ImportAPITest.as
@@ -26,1137 +26,1148 @@
 
 package UnitTest.Tests
 {
-	import UnitTest.ExtendedClasses.TestDescriptor;
-	import UnitTest.ExtendedClasses.TestSuiteExtended;
-	import UnitTest.ExtendedClasses.VellumTestCase;
-	import UnitTest.Fixtures.TestConfig;
-	
-	import flashx.textLayout.TextLayoutVersion;
-	import flashx.textLayout.conversion.ConversionType;
-	import flashx.textLayout.conversion.FormatDescriptor;
-	import flashx.textLayout.conversion.IHTMLImporter;
-	import flashx.textLayout.conversion.ITextExporter;
-	import flashx.textLayout.conversion.ITextImporter;
-	import flashx.textLayout.conversion.ITextLayoutImporter;
-	import flashx.textLayout.conversion.PlainTextExporter;
-	import flashx.textLayout.conversion.TextConverter;
-	import flashx.textLayout.edit.TextClipboard;
-	import flashx.textLayout.edit.TextScrap;
-	import flashx.textLayout.elements.FlowLeafElement;
-	import flashx.textLayout.elements.InlineGraphicElement;
-	import flashx.textLayout.elements.ParagraphElement;
-	import flashx.textLayout.elements.SpanElement;
-	import flashx.textLayout.elements.TextFlow;
-	import flashx.textLayout.formats.BlockProgression;
-	import flashx.textLayout.formats.Direction;
-	import flashx.textLayout.tlf_internal;
+    import UnitTest.ExtendedClasses.VellumTestCase;
+    import UnitTest.Fixtures.TestConfig;
+
+    import flashx.textLayout.TextLayoutVersion;
+    import flashx.textLayout.conversion.ConversionType;
+    import flashx.textLayout.conversion.FormatDescriptor;
+    import flashx.textLayout.conversion.IHTMLImporter;
+    import flashx.textLayout.conversion.ITextExporter;
+    import flashx.textLayout.conversion.ITextImporter;
+    import flashx.textLayout.conversion.ITextLayoutImporter;
+    import flashx.textLayout.conversion.PlainTextExporter;
+    import flashx.textLayout.conversion.TextConverter;
+    import flashx.textLayout.edit.TextClipboard;
+    import flashx.textLayout.edit.TextScrap;
+    import flashx.textLayout.elements.FlowLeafElement;
+    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 org.flexunit.asserts.assertTrue;
 
     use namespace tlf_internal;
 
- 	public class ImportAPITest extends VellumTestCase
-	{
-		public function ImportAPITest(methodName:String, testID:String, testConfig:TestConfig, testXML:XML = null)
-		{
-			super(methodName, testID, testConfig);
+    [TestCase(order=27)]
+    public class ImportAPITest extends VellumTestCase
+    {
 
-			// Note: These must correspond to a Watson product area (case-sensitive)
-			metaData.productArea = "Import/Export";
-		}
+        private static const htmlTest1:XML = <HTML>
+            <BODY>
+                <P ALIGN="left">
+                    <FONT FACE="Arial" SIZE="12" COLOR="#AA0000" LETTERSPACING="0" KERNING="1">
+                        <b>
+                            <i>hello</i>
+                        </b>
+                    </FONT>
+                </P>
+            </BODY>
+        </HTML>;
 
-		public static function suite(testConfig:TestConfig, ts:TestSuiteExtended):void
-		{
-			// We only need one version of these tests
-			if (testConfig.writingDirection[0] == BlockProgression.TB && testConfig.writingDirection[1] == Direction.LTR)
-			{
-				testConfig = testConfig.copyTestConfig();
-				testConfig.containerType = "custom";
+        private static const htmlTest2:XML = <HTML>
+            <BODY>
+                <P ALIGN="left">
+                    <FONT FACE="Arial" SIZE="12" COLOR="#AA0000" LETTERSPACING="0" KERNING="1">
+                        <b>
+                            <i></i>
+                        </b>
+                    </FONT>
+                </P>
+            </BODY>
+        </HTML>;
 
-				ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "importMultipleTimes_TCAL", testConfig ) );
-		   		ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "exportMultipleTimes_TCAL", testConfig ) );
-		   		ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "importMultipleTimes_Plain", testConfig ) );
-		   		ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "exportMultipleTimes_Plain", testConfig ) );
-		   		ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "importNewlines_Plain", testConfig ) );
-		   		ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "customExportSettings_Plain", testConfig ) );
-		   		ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "roundTripLeadingSpace", testConfig ) );
-		   		ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "testTabAndBreakMergingInSpanImport", testConfig ) );
-		   		ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "testTextImportErrors", testConfig ) );
-		   		ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "testHTMLImportErrors", testConfig ) );
-		   		ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "testMarkupImportErrors", testConfig ) );
-		   		ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "testMarkupImport", testConfig ) );
-		   		ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "normalizeTest", testConfig ) );
-				ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "testInvalidListStyleTypeErrors", testConfig ) );
-				ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "imgSourceFilterFunction", testConfig ) );
-				ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "versionCompatibilityPadding", testConfig ) );
-				ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "testHTMLMarkup", testConfig ) );
-				ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "testHTMLMarkupClassAndId", testConfig ) );
-				ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "testHTMLMarkupCustomTag", testConfig ) );
-				ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "addAndRemoveFormat", testConfig ) );
-				ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "clipboardImporterTest", testConfig ) );
-				ts.addTestDescriptor (new TestDescriptor (ImportAPITest, "clipboardExporterTest", testConfig ) );
-			}
-		}
+        private static const htmlTest3:XML = <p>
+            <font>
+                <b/>
+            </font>
+        </p>;
 
-		public function versionCompatibilityPadding():void
-		{
-			const markup:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' fontSize='14' textIndent='15' paragraphSpaceAfter='15' paddingTop='4' paddingLeft='4'><flow:p fontSize='24' textAlign='center'><flow:span>Ethan Brand</flow:span></flow:p><flow:p><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><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,...</flow:span></flow:p></flow:TextFlow>";
-			
-			var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
+        private static const htmlTest4a:XML = <p>
+            <b/>
+        </p>;
+        private static const htmlTest4b:XML = <p>Some Text</p>;
 
-			// Exporting should always get us a <TextFlow> with a version attribute set the current version
-			var testVersionExistence:XML = TextConverter.export(textFlow, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.XML_TYPE) as XML;
-			assertTrue("Expected version attribute set to current version", testVersionExistence.@["version"] == TextLayoutVersion.getVersionString(TextLayoutVersion.CURRENT_VERSION));
-			
-			// Importing a 2.0 or later TextFlow should get padding anywhere it was applied
-			const markup20WithPadding:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' version='2.0.0' paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:p paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:span>Ethan Brand</flow:span><flow:img paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'/></flow:p><flow:p paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:span>There are many </flow:span></flow:p></flow:TextFlow>";
-			textFlow = TextConverter.importToFlow(markup20WithPadding, TextConverter.TEXT_LAYOUT_FORMAT);
-			checkPaddingResults(textFlow, false /* expect padding kept */);
+        // as XML all the leading/trailing whitespace gets stripped.  Next two should produce indentical results
+        private static const htmlTest5a:String = '<p><textformat leading="200%"><i><b>BoldItalic</b></i> </textformat>Plain <i>Italic</i> Plain <b>Bold</b></p>';
+        private static const htmlTest5b:String = '<textformat leading="200%"><i><b>BoldItalic</b></i> </textformat>Plain <i>Italic</i> Plain <b>Bold</b>';
 
-			// Importing a 1.0 with no version specified should get padding only on TextFlow
-			const markup10WithPadding:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:p paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:span>Ethan Brand</flow:span><flow:img paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'/></flow:p><flow:p paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:span>There are many </flow:span></flow:p></flow:TextFlow>";
-			textFlow = TextConverter.importToFlow(markup10WithPadding, TextConverter.TEXT_LAYOUT_FORMAT);
-			checkPaddingResults(textFlow, true /* expect padding removed */);
+        // strikeThrough test
+        private static const htmlTest6:String = '<p><s><i><b>StrikeThroughBoldItalic</b></i></b></s></p>';
 
-			// Same results if version is explicitly set to 1.0 or 1.1
-			const markup10ExplicitWithPadding:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' version='1.0.0' paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:p paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:span>Ethan Brand</flow:span><flow:img paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'/></flow:p><flow:p paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:span>There are many </flow:span></flow:p></flow:TextFlow>";
-			textFlow = TextConverter.importToFlow(markup10ExplicitWithPadding, TextConverter.TEXT_LAYOUT_FORMAT);
-			checkPaddingResults(textFlow, true /* expect padding removed */);
+        // naked listitem test
+        private static const htmlTest7:String = '<li>abcd</li>';
 
-			// Same results if version is explicitly set to 1.0 or 1.1
-			const markup11ExplicitWithPadding:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' version='1.1.0' paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:p paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:span>Ethan Brand</flow:span><flow:img paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'/></flow:p><flow:p paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:span>There are many </flow:span></flow:p></flow:TextFlow>";
-			textFlow = TextConverter.importToFlow(markup11ExplicitWithPadding, TextConverter.TEXT_LAYOUT_FORMAT);
-			checkPaddingResults(textFlow, true /* expect padding removed */);
+        // tests that the group created by the parent of the tested span has the correct typename
+        private static const htmlTest8:String = '<P ALIGN="left"><span class="xyz"><FONT FACE="Arial" SIZE="12" COLOR="#000000" LETTERSPACING="0" KERNING="1"><B>Hello</B> <I>World</I></FONT><span></P>';
 
-			// Should get an error for an unknown version
-			const markup12ExplicitWithPadding:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' version='1.2.0' paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:p paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:span>Ethan Brand</flow:span><flow:img paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'/></flow:p><flow:p paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:span>There are many </flow:span></flow:p></flow:TextFlow>";
-			var textImporter:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_LAYOUT_FORMAT);
-			textImporter.importToFlow(markup12ExplicitWithPadding);
-			assertTrue("Expected unsupported import error",textImporter.errors != null);
-		}
-		
-		private function checkPaddingResults(textFlow:TextFlow, expectRemoved:Boolean):void
-		{
-			var firstPara:ParagraphElement = textFlow.getFirstLeaf().getParagraph();
-			var lastPara:ParagraphElement = textFlow.getLastLeaf().getParagraph();
-			var img:InlineGraphicElement = firstPara.getFirstLeaf().getNextSibling() as InlineGraphicElement;
-			
-			assertTrue("Padding was not propagated to TextFlow", textFlow.format.paddingTop == 4 && textFlow.format.paddingLeft == 4 && textFlow.format.paddingRight == 2 && textFlow.format.paddingBottom == 1);
-			
-			if (expectRemoved)
-			{
-				assertTrue("Padding was not removed from first paragraph", firstPara.paddingTop === undefined && firstPara.paddingLeft === undefined && firstPara.paddingRight === undefined && firstPara.paddingBottom === undefined);
-				assertTrue("Padding was not removed from last paragraph", lastPara.paddingTop === undefined && lastPara.paddingLeft === undefined && lastPara.paddingRight  === undefined && lastPara.paddingBottom === undefined);
-				assertTrue("Padding was not removed from img", img.paddingTop  === undefined && img.paddingLeft  === undefined && img.paddingRight === undefined && img.paddingBottom  === undefined);
-			}
-			else
-			{
-				assertTrue("Padding was not propagated to first paragraph", firstPara.format.paddingTop == 4 && firstPara.format.paddingLeft == 4 && firstPara.format.paddingRight == 2 && firstPara.format.paddingBottom == 1);
-				assertTrue("Padding was not propagated to last paragraph", lastPara.format.paddingTop == 4 && lastPara.format.paddingLeft == 4 && lastPara.format.paddingRight == 2 && lastPara.format.paddingBottom == 1);
-				assertTrue("Padding was not propagated to img", img.format.paddingTop == 4 && img.format.paddingLeft == 4 && img.format.paddingRight == 2 && img.format.paddingBottom == 1);
-			}
-		}
-		
-		public function roundTripLeadingSpace():void
-		{
-			const markup:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' fontSize='14' textIndent='15' paragraphSpaceAfter='15' paddingTop='4' paddingLeft='4'><flow:p fontSize='24' textAlign='center'><flow:span>Ethan Brand</flow:span></flow:p><flow:p><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><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,...</flow:span></flow:p></flow:TextFlow>";
+        private static const htmlCIDTest1:String = '<span id="x1">abcd</span>';
+        private static const htmlCIDTest2:String = '<span id="x1"><span>abcd</span><b>XYZ</b></span>';
+        private static const htmlCIDTest3:String = '<span><span>abcd</span><b>XYZ</b></span>';
 
-			var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
-			var markupAfterFirstExport:String = TextConverter.export(textFlow, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
-			textFlow = TextConverter.importToFlow(markupAfterFirstExport, TextConverter.TEXT_LAYOUT_FORMAT);
+        private static const htmlCIDTest4:String = '<i><span id="x1"><span>abcd</span><b>XYZ</b></span></i>';
+        private static const htmlCIDTest5:String = '<i><span><span>abcd</span><b>XYZ</b></span></i>';
 
-			var secondPara:ParagraphElement = textFlow.getChildAt(1) as ParagraphElement;
-			var firstSpan:SpanElement = secondPara.getChildAt(0) as SpanElement;
-			assertTrue("Expected trailing space", firstSpan.text.charCodeAt(firstSpan.text.length - 1) == 32);
-			var markupAfterSecondExport:String = TextConverter.export(textFlow, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
-			assertTrue("Roundtrip not matching", markupAfterFirstExport == markupAfterSecondExport);
-		}
+        private static const htmlCIDTest6:String = '<span class="x1"><span>abcd</span><b>XYZ</b></span>';
+        private static const htmlCIDTest7:String = '<span><span>abcd</span><b>XYZ</b></span>';
 
-		public function importMultipleTimes_TCAL():void
-		{
-			const markup1:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008'><flow:p><flow:span>Hello</flow:span></flow:p></flow:TextFlow>";
-			const markup2:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008'><flow:p><flow:span>Goodbye</flow:span></flow:p></flow:TextFlow>";
+        private static const htmlCIDTest8:String = '<i><span class="x1"><span>abcd</span><b>XYZ</b></span></i>';
+        private static const htmlCIDTest9:String = '<i><span><span>abcd</span><b>XYZ</b></span></i>';
 
-			importMultipleTimes(TextConverter.TEXT_LAYOUT_FORMAT, markup1, markup2);
-		}
+        private static const htmlCIDTest10:String = '<ul id="ulid"><li id="liid"><p id="pid">noid<span id="spanid">spanid</span><img id="imgid"/></p></li></ul><ol id="olid">olid</ol>';
+        private static const htmlCIDTest11:String = '<ul class="ulid"><li class="liclass"><p class="pclass">noclass<span class="spanclass">spanclass</span><img class="imgclass"/></p></li></ul><ol class="olclass">olclass</ol>';
 
-		public function exportMultipleTimes_TCAL():void
-		{
-			const markup1:String = "<flow:TextFlow  xmlns:flow='http://ns.adobe.com/textLayout/2008'><flow:p><flow:span>Hello</flow:span></flow:p></flow:TextFlow>";
-			const markup2:String = "<flow:TextFlow  xmlns:flow='http://ns.adobe.com/textLayout/2008'><flow:p><flow:span>Goodbye</flow:span></flow:p></flow:TextFlow>";
+        private static const customTag1:String = '<foo>ABCD</foo>';
+        private static const customTag2:String = '<p><foo><a>ABCD</a></foo></p>';
+        private static const customTag3:String = '<p><foo><span>ABCD</span><i> ITALIC</i></foo></p>';
+        private static const customTag4:String = '<foo><div id="a">text</div></foo>';
+        private static const customTag5:String = '<foo><div>text</div></foo>';
+        private static const customTag6:String = '<foo><div>text</div><div>text</div></foo>';
+        private static const customTag7:String = '<foo><bar>ABCD</bar></foo>';
 
-			exportMultipleTimes(TextConverter.TEXT_LAYOUT_FORMAT, markup1, markup2);
-		}
+        public function ImportAPITest()
+        {
+            TestConfig.getInstance().containerType = "custom";
+            super("", "ImportAPITest", TestConfig.getInstance());
 
-		public function importMultipleTimes_Plain():void
-		{
-			const markup1:String = "Hello";
-			const markup2:String = "Goodbye";
+            metaData = {};
 
-			importMultipleTimes(TextConverter.PLAIN_TEXT_FORMAT, markup1, markup2);
-		}
+            // Note: These must correspond to a Watson product area (case-sensitive)
+            metaData.productArea = "Import/Export";
+        }
 
-		public function exportMultipleTimes_Plain():void
-		{
-			const markup1:String = "Hello";
-			const markup2:String = "Goodbye";
+        [Before]
+        override public function setUpTest():void
+        {
+            super.setUpTest();
+        }
 
-			exportMultipleTimes(TextConverter.PLAIN_TEXT_FORMAT, markup1, markup2);
-		}
+        [After]
+        override public function tearDownTest():void
+        {
+            super.tearDownTest();
+        }
 
-		public function importNewlines_Plain():void
-		{
-			const markup:String = "0\r1\n2\r\n3";
-			var textImporter:ITextImporter = TextConverter.getImporter(TextConverter.PLAIN_TEXT_FORMAT);
-			var textFlow:TextFlow = textImporter.importToFlow(markup);
+        [Test]
+        public function versionCompatibilityPadding():void
+        {
+            const markup:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' fontSize='14' textIndent='15' paragraphSpaceAfter='15' paddingTop='4' paddingLeft='4'><flow:p fontSize='24' textAlign='center'><flow:span>Ethan Brand</flow:span></flow:p><flow:p><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><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,...</flow:span></flow:p></flow:TextFlow>";
 
-			var para:ParagraphElement = textFlow.getFirstLeaf().getParagraph();
-			var i:int = 0;
-			while (para != null)
-			{
-				var paraText:String = para.getText();
-				assertTrue("Not all allowed newline indicators recognized as such", int(paraText) == i);
-				para = para.getNextParagraph();
-				i++;
-			}
-			assertTrue("Not all allowed newline indicators recognized as such", i == 4);
-		}
+            var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
 
-		public function customExportSettings_Plain():void
-		{
-			var markup:String = "dis" + "\u00AD" + "cre" + "\u00AD" + "tion" + "\u00AD" + "a" + "\u00AD" + "ry";
-			var textImporter:ITextImporter = TextConverter.getImporter(TextConverter.PLAIN_TEXT_FORMAT);
-			var textFlow:TextFlow = textImporter.importToFlow(markup);
+            // Exporting should always get us a <TextFlow> with a version attribute set the current version
+            var testVersionExistence:XML = TextConverter.export(textFlow, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.XML_TYPE) as XML;
+            assertTrue("Expected version attribute set to current version", testVersionExistence.@["version"] == TextLayoutVersion.getVersionString(TextLayoutVersion.CURRENT_VERSION));
 
-			var exporter:PlainTextExporter = new PlainTextExporter();
-			assertTrue("Discretionary hyphens not stripped by default", exporter.export(textFlow, ConversionType.STRING_TYPE) == "discretionary");
+            // Importing a 2.0 or later TextFlow should get padding anywhere it was applied
+            const markup20WithPadding:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' version='2.0.0' paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:p paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:span>Ethan Brand</flow:span><flow:img paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'/></flow:p><flow:p paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:span>There are many </flow:span></flow:p></flow:TextFlow>";
+            textFlow = TextConverter.importToFlow(markup20WithPadding, TextConverter.TEXT_LAYOUT_FORMAT);
+            checkPaddingResults(textFlow, false /* expect padding kept */);
 
-			exporter.stripDiscretionaryHyphens = false;
-			assertTrue("Discretionary hyphens stripped even when stripDiscretionaryHyphens is false", exporter.export(textFlow, ConversionType.STRING_TYPE) == markup);
+            // Importing a 1.0 with no version specified should get padding only on TextFlow
+            const markup10WithPadding:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:p paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:span>Ethan Brand</flow:span><flow:img paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'/></flow:p><flow:p paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:span>There are many </flow:span></flow:p></flow:TextFlow>";
+            textFlow = TextConverter.importToFlow(markup10WithPadding, TextConverter.TEXT_LAYOUT_FORMAT);
+            checkPaddingResults(textFlow, true /* expect padding removed */);
 
-			markup = "0\r1";
-			textFlow = textImporter.importToFlow(markup);
+            // Same results if version is explicitly set to 1.0 or 1.1
+            const markup10ExplicitWithPadding:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' version='1.0.0' paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:p paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:span>Ethan Brand</flow:span><flow:img paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'/></flow:p><flow:p paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:span>There are many </flow:span></flow:p></flow:TextFlow>";
+            textFlow = TextConverter.importToFlow(markup10ExplicitWithPadding, TextConverter.TEXT_LAYOUT_FORMAT);
+            checkPaddingResults(textFlow, true /* expect padding removed */);
 
-			assertTrue("Plain text exporter does not use default para separator as expected", exporter.export(textFlow, ConversionType.STRING_TYPE) == "0\n1");
+            // Same results if version is explicitly set to 1.0 or 1.1
+            const markup11ExplicitWithPadding:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' version='1.1.0' paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:p paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:span>Ethan Brand</flow:span><flow:img paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'/></flow:p><flow:p paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:span>There are many </flow:span></flow:p></flow:TextFlow>";
+            textFlow = TextConverter.importToFlow(markup11ExplicitWithPadding, TextConverter.TEXT_LAYOUT_FORMAT);
+            checkPaddingResults(textFlow, true /* expect padding removed */);
 
-			exporter.paragraphSeparator = "\r";
-			assertTrue("Plain text export does not honor custom para separator as expected", exporter.export(textFlow, ConversionType.STRING_TYPE) == "0\r1")
-		}
+            // Should get an error for an unknown version
+            const markup12ExplicitWithPadding:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' version='1.2.0' paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:p paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:span>Ethan Brand</flow:span><flow:img paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'/></flow:p><flow:p paddingTop='4' paddingLeft='4' paddingRight='2' paddingBottom='1'><flow:span>There are many </flow:span></flow:p></flow:TextFlow>";
+            var textImporter:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_LAYOUT_FORMAT);
+            textImporter.importToFlow(markup12ExplicitWithPadding);
+            assertTrue("Expected unsupported import error", textImporter.errors != null);
+        }
 
-		private function importMultipleTimes(format:String, markup1:String, markup2:String):void
-		{
-			var textFlow:TextFlow;
-			var textImporter:ITextImporter = TextConverter.getImporter(format);
-			textFlow = textImporter.importToFlow(markup1);
-			assertTrue("Expected string 'Hello'", SpanElement(textFlow.getFirstLeaf()).text == 'Hello');
-			assertTrue("Expected no errors import",textImporter.errors == null);
-			textFlow = textImporter.importToFlow(markup2);
-			assertTrue("Expected string 'Hello'", SpanElement(textFlow.getFirstLeaf()).text == 'Goodbye');
-			assertTrue("Expected no errors import",textImporter.errors == null);
-		}
+        [Test]
+        public function roundTripLeadingSpace():void
+        {
+            const markup:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008' fontSize='14' textIndent='15' paragraphSpaceAfter='15' paddingTop='4' paddingLeft='4'><flow:p fontSize='24' textAlign='center'><flow:span>Ethan Brand</flow:span></flow:p><flow:p><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><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,...</flow:span></flow:p></flow:TextFlow>";
 
-		private function exportMultipleTimes(format:String, markup1:String, markup2:String):void
-		{
-			var textImporter:ITextImporter = TextConverter.getImporter(format);
-			var textExporter:ITextExporter = TextConverter.getExporter(format);
-			importAndExport(markup1, textImporter, textExporter);
-			importAndExport(markup2, textImporter, textExporter);
-		}
+            var textFlow:TextFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT);
+            var markupAfterFirstExport:String = TextConverter.export(textFlow, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
+            textFlow = TextConverter.importToFlow(markupAfterFirstExport, TextConverter.TEXT_LAYOUT_FORMAT);
 
-		private function importAndExport(markup:String, textImporter:ITextImporter, textExporter:ITextExporter):void
-		{
-			// Import, export, re-import, and compare result
-			var textFlow:TextFlow = textImporter.importToFlow(markup);
-			var textBefore:String = SpanElement(textFlow.getFirstLeaf()).text;
-			var markupResult:String = textExporter.export(textFlow, ConversionType.STRING_TYPE) as String;
-			textFlow = textImporter.importToFlow(markupResult);
-			assertTrue("Export from TextFlow doesn't match import", textBefore == SpanElement(textFlow.getFirstLeaf()).text);
-			assertTrue("Expected no errors import",textImporter.errors == null);
-		}
+            var secondPara:ParagraphElement = textFlow.getChildAt(1) as ParagraphElement;
+            var firstSpan:SpanElement = secondPara.getChildAt(0) as SpanElement;
+            assertTrue("Expected trailing space", firstSpan.text.charCodeAt(firstSpan.text.length - 1) == 32);
+            var markupAfterSecondExport:String = TextConverter.export(textFlow, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
+            assertTrue("Roundtrip not matching", markupAfterFirstExport == markupAfterSecondExport);
+        }
 
-		public function testTabAndBreakMergingInSpanImport():void
-		{
-			var textImporter:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_LAYOUT_FORMAT);
-			var textFlow:TextFlow;
+        [Test]
+        public function importMultipleTimes_TCAL():void
+        {
+            const markup1:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008'><flow:p><flow:span>Hello</flow:span></flow:p></flow:TextFlow>";
+            const markup2:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008'><flow:p><flow:span>Goodbye</flow:span></flow:p></flow:TextFlow>";
 
-			const markup1:String = "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><p><span fontSize='24'>Hello<tab/>World<br/>Goodbye</span></p></TextFlow>";
-			textFlow = textImporter.importToFlow(markup1);
-			// should all be merged into a single leaf
-			assertTrue("Import of tab/break does not merge properly", textFlow.getFirstLeaf() == textFlow.getLastLeaf());
-			assertTrue("Expected no errors import",textImporter.errors == null);
+            importMultipleTimes(TextConverter.TEXT_LAYOUT_FORMAT, markup1, markup2);
+        }
 
-			const markup2:String = "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><p><span fontSize='24'><tab/>Hello World<br/></span></p></TextFlow>";
-			textFlow = textImporter.importToFlow(markup2);
-			// should all be merged into a single leaf
-			assertTrue("Import of tab/break does not merge properly", textFlow.getFirstLeaf() == textFlow.getLastLeaf());
-			assertTrue("Expected no errors import",textImporter.errors == null);
-		}
+        [Test]
+        public function exportMultipleTimes_TCAL():void
+        {
+            const markup1:String = "<flow:TextFlow  xmlns:flow='http://ns.adobe.com/textLayout/2008'><flow:p><flow:span>Hello</flow:span></flow:p></flow:TextFlow>";
+            const markup2:String = "<flow:TextFlow  xmlns:flow='http://ns.adobe.com/textLayout/2008'><flow:p><flow:span>Goodbye</flow:span></flow:p></flow:TextFlow>";
 
-		public function testTextImportErrors():void
-		{
-			var textImporter:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_LAYOUT_FORMAT);
-			var textFlow:TextFlow;
+            exportMultipleTimes(TextConverter.TEXT_LAYOUT_FORMAT, markup1, markup2);
+        }
 
-			// no namespace specififed - an error
-			const markup1:String = "<TextFlow><p><span>No namespace - must fail</span></p></TextFlow>";
-			textFlow = textImporter.importToFlow(markup1);
-			assertTrue("Expected one error on import and no TextFlow",textImporter.errors != null && textImporter.errors.length ==1 && textFlow == null);
+        [Test]
+        public function importMultipleTimes_Plain():void
+        {
+            const markup1:String = "Hello";
+            const markup2:String = "Goodbye";
 
-			// wrong namespace specififed - an error
-			const markup2:String = "<TextFlow xmlns='http://not.ns.adobe.com/textLayout/2008'><p><span>Bad namespace - must fail</span></p></TextFlow>";
-			textFlow = textImporter.importToFlow(markup2);
-			assertTrue("Expected one error on import and no TextFlow",textImporter.errors != null && textImporter.errors.length ==1 && textFlow == null);
+            importMultipleTimes(TextConverter.PLAIN_TEXT_FORMAT, markup1, markup2);
+        }
 
-			// bad element - an error
-			const markup3:String = "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><xyz/></TextFlow>";
-			textFlow = textImporter.importToFlow(markup3);
-			assertTrue("Expected one error on import and no TextFlow",textImporter.errors != null && textImporter.errors.length == 1);
+        [Test]
+        public function exportMultipleTimes_Plain():void
+        {
+            const markup1:String = "Hello";
+            const markup2:String = "Goodbye";
 
-			// bad element in span
-			const markup4:String = "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><p><span>Hello<p/>World</span></p></TextFlow>";
-			textFlow = textImporter.importToFlow(markup4);
-			assertTrue("Expected one error on import and no TextFlow",textImporter.errors != null && textImporter.errors.length == 1);
+            exportMultipleTimes(TextConverter.PLAIN_TEXT_FORMAT, markup1, markup2);
+        }
 
-		}
+        [Test]
+        public function importNewlines_Plain():void
+        {
+            const markup:String = "0\r1\n2\r\n3";
+            var textImporter:ITextImporter = TextConverter.getImporter(TextConverter.PLAIN_TEXT_FORMAT);
+            var textFlow:TextFlow = textImporter.importToFlow(markup);
 
-		public function testHTMLImportErrors():void
-		{
-			var textImporter:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_FIELD_HTML_FORMAT);
-			var textFlow:TextFlow;
+            var para:ParagraphElement = textFlow.getFirstLeaf().getParagraph();
+            var i:int = 0;
+            while (para != null)
+            {
+                var paraText:String = para.getText();
+                assertTrue("Not all allowed newline indicators recognized as such", int(paraText) == i);
+                para = para.getNextParagraph();
+                i++;
+            }
+            assertTrue("Not all allowed newline indicators recognized as such", i == 4);
+        }
 
-			// start and end modifier
-			const markup3:String = '<p>Malformed tag next</p/>';
-			textFlow = textImporter.importToFlow(markup3);
-			assertTrue("Expected one error on import",textImporter.errors != null && textImporter.errors.length == 1);
+        [Test]
+        public function customExportSettings_Plain():void
+        {
+            var markup:String = "dis" + "\u00AD" + "cre" + "\u00AD" + "tion" + "\u00AD" + "a" + "\u00AD" + "ry";
+            var textImporter:ITextImporter = TextConverter.getImporter(TextConverter.PLAIN_TEXT_FORMAT);
+            var textFlow:TextFlow = textImporter.importToFlow(markup);
 
-			// attr on end tag
-			const markup2:String = '<p>Malformed tag next</p align="left">';
-			textFlow = textImporter.importToFlow(markup2);
-			assertTrue("Expected one error on import ",textImporter.errors != null && textImporter.errors.length ==1);
+            var exporter:PlainTextExporter = new PlainTextExporter();
+            assertTrue("Discretionary hyphens not stripped by default", exporter.export(textFlow, ConversionType.STRING_TYPE) == "discretionary");
 
-			// bad text node
-			const markup10:String = 'a < b + c'; // should be 'a &lt; b + c'
-			textFlow = textImporter.importToFlow(markup10);
-			assertTrue("Expected one error on import",textImporter.errors != null && textImporter.errors.length ==1);
+            exporter.stripDiscretionaryHyphens = false;
+            assertTrue("Discretionary hyphens stripped even when stripDiscretionaryHyphens is false", exporter.export(textFlow, ConversionType.STRING_TYPE) == markup);
 
-			// invalid attribute value
-			const markup11:String = '<p align="middle">blah</p>'; // should be "center"
-			textFlow = textImporter.importToFlow(markup11);
-			assertTrue("Expected one error on import",textImporter.errors != null && textImporter.errors.length ==1);
+            markup = "0\r1";
+            textFlow = textImporter.importToFlow(markup);
 
+            assertTrue("Plain text exporter does not use default para separator as expected", exporter.export(textFlow, ConversionType.STRING_TYPE) == "0\n1");
 
-			// These cases do not apply to the TextFiled HTML dialect, which is what we
-			// are supporting now.
+            exporter.paragraphSeparator = "\r";
+            assertTrue("Plain text export does not honor custom para separator as expected", exporter.export(textFlow, ConversionType.STRING_TYPE) == "0\r1")
+        }
 
-			// forbidden end tag
-			/*
-			const markup1:String = '<br></br>';
-			textFlow = textImporter.importToFlow(markup1);
-			assertTrue("Expected one error on import and no TextFlow",textImporter.errors != null && textImporter.errors.length ==1 && textFlow == null);
+        private function importMultipleTimes(format:String, markup1:String, markup2:String):void
+        {
+            var textFlow:TextFlow;
+            var textImporter:ITextImporter = TextConverter.getImporter(format);
+            textFlow = textImporter.importToFlow(markup1);
+            assertTrue("Expected string 'Hello'", SpanElement(textFlow.getFirstLeaf()).text == 'Hello');
+            assertTrue("Expected no errors import", textImporter.errors == null);
+            textFlow = textImporter.importToFlow(markup2);
+            assertTrue("Expected string 'Hello'", SpanElement(textFlow.getFirstLeaf()).text == 'Goodbye');
+            assertTrue("Expected no errors import", textImporter.errors == null);
+        }
 
-			// missing end tag
-			const markup4:String = '<font size="20">end tag is not optional for font element';
-			textFlow = textImporter.importToFlow(markup4);
-			assertTrue("Expected one error on import and no TextFlow",textImporter.errors != null && textImporter.errors.length == 1);
+        private function exportMultipleTimes(format:String, markup1:String, markup2:String):void
+        {
+            var textImporter:ITextImporter = TextConverter.getImporter(format);
+            var textExporter:ITextExporter = TextConverter.getExporter(format);
+            importAndExport(markup1, textImporter, textExporter);
+            importAndExport(markup2, textImporter, textExporter);
+        }
+
+        private function importAndExport(markup:String, textImporter:ITextImporter, textExporter:ITextExporter):void
+        {
+            // Import, export, re-import, and compare result
+            var textFlow:TextFlow = textImporter.importToFlow(markup);
+            var textBefore:String = SpanElement(textFlow.getFirstLeaf()).text;
+            var markupResult:String = textExporter.export(textFlow, ConversionType.STRING_TYPE) as String;
+            textFlow = textImporter.importToFlow(markupResult);
+            assertTrue("Export from TextFlow doesn't match import", textBefore == SpanElement(textFlow.getFirstLeaf()).text);
+            assertTrue("Expected no errors import", textImporter.errors == null);
+        }
+
+        [Test]
+        public function testTabAndBreakMergingInSpanImport():void
+        {
+            var textImporter:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_LAYOUT_FORMAT);
+            var textFlow:TextFlow;
+
+            const markup1:String = "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><p><span fontSize='24'>Hello<tab/>World<br/>Goodbye</span></p></TextFlow>";
+            textFlow = textImporter.importToFlow(markup1);
+            // should all be merged into a single leaf
+            assertTrue("Import of tab/break does not merge properly", textFlow.getFirstLeaf() == textFlow.getLastLeaf());
+            assertTrue("Expected no errors import", textImporter.errors == null);
+
+            const markup2:String = "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><p><span fontSize='24'><tab/>Hello World<br/></span></p></TextFlow>";
+            textFlow = textImporter.importToFlow(markup2);
+            // should all be merged into a single leaf
+            assertTrue("Import of tab/break does not merge properly", textFlow.getFirstLeaf() == textFlow.getLastLeaf());
+            assertTrue("Expected no errors import", textImporter.errors == null);
+        }
+
+        [Test]
+        public function testTextImportErrors():void
+        {
+            var textImporter:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_LAYOUT_FORMAT);
+            var textFlow:TextFlow;
+
+            // no namespace specififed - an error
+            const markup1:String = "<TextFlow><p><span>No namespace - must fail</span></p></TextFlow>";
+            textFlow = textImporter.importToFlow(markup1);
+            assertTrue("Expected one error on import and no TextFlow", textImporter.errors != null && textImporter.errors.length == 1 && textFlow == null);
+
+            // wrong namespace specififed - an error
+            const markup2:String = "<TextFlow xmlns='http://not.ns.adobe.com/textLayout/2008'><p><span>Bad namespace - must fail</span></p></TextFlow>";
+            textFlow = textImporter.importToFlow(markup2);
+            assertTrue("Expected one error on import and no TextFlow", textImporter.errors != null && textImporter.errors.length == 1 && textFlow == null);
+
+            // bad element - an error
+            const markup3:String = "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><xyz/></TextFlow>";
+            textFlow = textImporter.importToFlow(markup3);
+            assertTrue("Expected one error on import and no TextFlow", textImporter.errors != null && textImporter.errors.length == 1);
+
+            // bad element in span
+            const markup4:String = "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><p><span>Hello<p/>World</span></p></TextFlow>";
+            textFlow = textImporter.importToFlow(markup4);
+            assertTrue("Expected one error on import and no TextFlow", textImporter.errors != null && textImporter.errors.length == 1);
+
+        }
+
+        [Test]
+        public function testHTMLImportErrors():void
+        {
+            var textImporter:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_FIELD_HTML_FORMAT);
+            var textFlow:TextFlow;
+
+            // start and end modifier
+            const markup3:String = '<p>Malformed tag next</p/>';
+            textFlow = textImporter.importToFlow(markup3);
+            assertTrue("Expected one error on import", textImporter.errors != null && textImporter.errors.length == 1);
+
+            // attr on end tag
+            const markup2:String = '<p>Malformed tag next</p align="left">';
+            textFlow = textImporter.importToFlow(markup2);
+            assertTrue("Expected one error on import ", textImporter.errors != null && textImporter.errors.length == 1);
+
+            // bad text node
+            const markup10:String = 'a < b + c'; // should be 'a &lt; b + c'
+            textFlow = textImporter.importToFlow(markup10);
+            assertTrue("Expected one error on import", textImporter.errors != null && textImporter.errors.length == 1);
+
+            // invalid attribute value
+            const markup11:String = '<p align="middle">blah</p>'; // should be "center"
+            textFlow = textImporter.importToFlow(markup11);
+            assertTrue("Expected one error on import", textImporter.errors != null && textImporter.errors.length == 1);
+
+
+            // These cases do not apply to the TextFiled HTML dialect, which is what we
+            // are supporting now.
+
+            // forbidden end tag
+            /*
+             const markup1:String = '<br></br>';
+             textFlow = textImporter.importToFlow(markup1);
+             assertTrue("Expected one error on import and no TextFlow",textImporter.errors != null && textImporter.errors.length ==1 && textFlow == null);
+
+             // missing end tag
+             const markup4:String = '<font size="20">end tag is not optional for font element';
+             textFlow = textImporter.importToFlow(markup4);
+             assertTrue("Expected one error on import and no TextFlow",textImporter.errors != null && textImporter.errors.length == 1);
+
+             // missing end tag
+             const markup5:String = '<p><font size="20">end tag is not optional for font element</p>';
+             textFlow = textImporter.importToFlow(markup5);
+             assertTrue("Expected one error on import and no TextFlow",textImporter.errors != null && textImporter.errors.length == 1);
+
+             // missing start tag
+             const markup6:String = 'start tag is not optional for p element</p>';
+             textFlow = textImporter.importToFlow(markup6);
+             assertTrue("Expected one error on import and no TextFlow",textImporter.errors != null && textImporter.errors.length == 1);
+
+             // unknown element
+             const markup8:String = '<image height="19" width="19" src="surprised.png" align="right">';
+             textFlow = textImporter.importToFlow(markup8);
+             assertTrue("Expected one error on import and no TextFlow",textImporter.errors != null && textImporter.errors.length == 1);
+
+             // unknown attribute
+             const markup9:String = '<p textAlign="center">Wrong attr name</p>';
+             textFlow = textImporter.importToFlow(markup9);
+             assertTrue("Expected one error on import and no TextFlow",textImporter.errors != null && textImporter.errors.length == 1);
+
+             */
+        }
+
+        [Test]
+        public function testMarkupImportErrors():void
+        {
+            const markup:String = "<TextFlow columnCount='inherit' columnGap='inherit' columnWidth='inherit' lineBreak='inherit' " +
+                    " paddingBottom='inherit' paddingLeft='inherit' paddingRight='inherit' paddingTop='inherit'" +
+                    " verticalAlign='inherit' whiteSpaceCollapse='preserve'" +
+                    " xmlns='http://ns.adobe.com/textLayout/2008'><p><a href='http://www.4literature.net/Nathaniel_Hawthorne/Ethan_Brand/' target='_self'>" +
+                    " <linkHoverFormat color='#ff0000'/>" +
+                    " <linkActiveFormat color='#00ff00' textDecoration='underline'/>" +
+                    " <linkNormalFormat color='#0000ff'/>" +
+                    " <span>Ethan Brand</span></a></p></TextFlow>";
+
+            var textImporter:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_LAYOUT_FORMAT);
+            var textFlow:TextFlow = textImporter.importToFlow(markup);
+            assertTrue("Expected one error on import and no TextFlow", textImporter.errors[0] == "Expected one and only one TextLayoutFormat in http://ns.adobe.com/textLayout/2008::linkHoverFormat"
+                    && textImporter.errors[1] == "Expected one and only one TextLayoutFormat in http://ns.adobe.com/textLayout/2008::linkActiveFormat"
+                    && textImporter.errors[2] == "Expected one and only one TextLayoutFormat in http://ns.adobe.com/textLayout/2008::linkNormalFormat"
+            );
+        }
+
+        public function testMarkupImport():void
+        {
+            const markup:String = "<TextFlow columnCount='inherit' columnGap='inherit' columnWidth='inherit' lineBreak='inherit' " +
+                    " paddingBottom='inherit' paddingLeft='inherit' paddingRight='inherit' paddingTop='inherit'" +
+                    " verticalAlign='inherit' whiteSpaceCollapse='preserve'" +
+                    " xmlns='http://ns.adobe.com/textLayout/2008'><p><a href='http://www.4literature.net/Nathaniel_Hawthorne/Ethan_Brand/' target='_self'>" +
+                    " <linkHoverFormat><TextLayoutFormat color='#ff0000'/></linkHoverFormat>" +
+                    " <linkActiveFormat><TextLayoutFormat color='#00ff00' textDecoration='underline'/></linkActiveFormat>" +
+                    " <linkNormalFormat><TextLayoutFormat color='#0000ff'/></linkNormalFormat>" +
+                    " <span>Ethan Brand</span></a></p></TextFlow>";
+
+            var textImporter:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_LAYOUT_FORMAT);
+            var textFlow:TextFlow;
+            textFlow = textImporter.importToFlow(markup);
+            assertTrue("Import markup failed. Expected no errors on import", textImporter.errors == null);
+        }
+
+        [Test]
+        public function normalizeTest():void
+        {
+            var textImporter:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_LAYOUT_FORMAT);
+
+            var textFlow:TextFlow;
+            var leaf:FlowLeafElement;
+
+            const markup1:String = "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><a><span></span></a><a></a></TextFlow>";
+            textFlow = textImporter.importToFlow(markup1);
+            leaf = textFlow.getFirstLeaf()
+            // result is a single paragraph with a single empty span
+            // assertTrue("Markup1 - expected paragraph with empty span",textFlow.textLength == 1 && leaf && leaf == textFlow.getLastLeaf() && leaf.parent == textFlow.getChildAt(0));
+
+            const markup2:String = "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><a/></TextFlow>";
+            textFlow = textImporter.importToFlow(markup2);
+            leaf = textFlow.getFirstLeaf()
+            // result is a single paragraph with a single empty span
+            assertTrue("Markup2 - expected paragraph with empty span", textFlow.textLength == 1 && leaf && leaf == textFlow.getLastLeaf() && leaf.parent == textFlow.getChildAt(0));
+
+            const markup3:String = "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><a/><span/></TextFlow>";
+            textFlow = textImporter.importToFlow(markup3);
+            leaf = textFlow.getFirstLeaf()
+            // result is a single paragraph with a single empty span
+            assertTrue("Markup2 - expected paragraph with empty span", textFlow.textLength == 1 && leaf && leaf == textFlow.getLastLeaf() && leaf.parent == textFlow.getChildAt(0));
+        }
+
+        [Test]
+        public function testInvalidListStyleTypeErrors():void
+        {
+            var textImporter:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_LAYOUT_FORMAT);
+            var textFlow:TextFlow;
+
+            // wrong listSytleTyle underline
+            const markup1:String = "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><list paddingRight='24' paddingLeft='24' listStyleType='underline'><li>underline item</li><li>another</li></list></TextFlow>";
+            textFlow = textImporter.importToFlow(markup1);
+            assertTrue("Expected out of range error",
+                    textImporter.errors[0] == "Property listStyleType value underline is out of range")
+
+            // wrong listStyleTyle StrikThrough
+            const markup2:String = "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><list paddingRight='24' paddingLeft='24' listStyleType='Strikethrough'><li>Strikethrough item</li><li>another</li></list></TextFlow>";
+            textFlow = textImporter.importToFlow(markup2);
+            assertTrue("Expected out of range error",
+                    textImporter.errors[0] == "Property listStyleType value Strikethrough is out of range")
+
+            // wrong listSytleTyle aaaa
+            const markup3:String = "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><list paddingRight='24' paddingLeft='24' listStyleType='aaaa'><li>aaaa item</li><li>another</li></list></TextFlow>";
+            textFlow = textImporter.importToFlow(markup3);
+            assertTrue("Expected out of range error",
+                    textImporter.errors[0] == "Property listStyleType value aaaa is out of range")
+        }
+
+        [Test]
+        public function imgSourceFilterFunction():void
+        {
+            var textFlow:TextFlow;
+            var elem:FlowLeafElement;
+            var textImporter:ITextImporter;
+            var replacedSource:String;
+
+            // TEXT_LAYOUT_FORMAT
+            replacedSource = "XYZ:";
+            textImporter = TextConverter.getImporter(TextConverter.TEXT_LAYOUT_FORMAT);
+            (textImporter as ITextLayoutImporter).imageSourceResolveFunction = function (source:String):String
+            {
+                replacedSource += source;
+                return replacedSource;
+            };
+            textFlow = textImporter.importToFlow("<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><img source='xyz.jpg'/></TextFlow>");
+            assertTrue("TextLayoutFormat: Too many calls to imgSourceFilterFunction", replacedSource == "XYZ:xyz.jpg");
+            elem = textFlow.getFirstLeaf();
+            assertTrue("TextLayoutFormat: Incorrect source on first leaf", elem is InlineGraphicElement && (elem as InlineGraphicElement).source == "XYZ:xyz.jpg");
+
+            // TEXT_FIELD_HTML_FORMAT
+            replacedSource = "XYZ:";
+            textImporter = TextConverter.getImporter(TextConverter.TEXT_FIELD_HTML_FORMAT);
+            (textImporter as IHTMLImporter).imageSourceResolveFunction = function (source:String):String
+            {
+                replacedSource += source;
+                return replacedSource;
+            };
+            textFlow = textImporter.importToFlow("<img src='xyz.jpg'/>");
+            assertTrue("TextFieldHTMLFormat: Too many calls to imgSourceFilterFunction", replacedSource == "XYZ:xyz.jpg");
+            elem = textFlow.getFirstLeaf();
+            assertTrue("TextFieldHTMLFormat: Incorrect source on first leaf", elem is InlineGraphicElement && (elem as InlineGraphicElement).source == "XYZ:xyz.jpg");
+        }
+
+        // helper function convert XML to a string without pretty printing
+        static public function makeXMLIntoString(source:XML):String
+        {
+            var rslt:String;
+            // turn off pretty printing when making the string
+            var savedPretty:Boolean = XML.prettyPrinting;
+            try
+            {
+                XML.prettyPrinting = false;
+                rslt = source.toString();
+            }
+            finally
+            {
+                XML.prettyPrinting = savedPretty;
+            }
+            return rslt;
+        }
+
+        // helper function - imports and then checks an expected result
+        static public function validateMarkup(importer:ITextImporter, testName:String, source:*, expectedResult:String, expectHtmlType:Boolean = false, expectBodyType:Boolean = false):void
+        {
+            var prefix:String;
+            var postfix:String;
+            if (expectHtmlType)
+                prefix = '<TextFlow typeName="html" whiteSpaceCollapse="preserve" version="3.0.0" xmlns="http://ns.adobe.com/textLayout/2008">';
+            else
+                prefix = '<TextFlow whiteSpaceCollapse="preserve" version="3.0.0" xmlns="http://ns.adobe.com/textLayout/2008">';
+
+            if (expectBodyType)
+            {
+                prefix += '<div typeName="body">';
+                postfix = '</div></TextFlow>'
+            }
+            else
+                postfix = '</TextFlow>';
+
+            expectedResult = prefix + expectedResult + postfix;
+
+            var textFlow:TextFlow = importer.importToFlow(source);
+            var rslt:String = TextConverter.export(textFlow, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
+            /*if (rslt != expectedResult)
+             {
+             trace(expectedResult);
+             trace(rslt);
+             }*/
+            assertTrue(testName + ": failed", rslt == expectedResult);
+        }
+
+        [Test]
+        public function testHTMLMarkup():void
+        {
+            var importer:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_FIELD_HTML_FORMAT);
+
+            validateMarkup(importer, "testHTMLMarkup:htmlTest1", htmlTest1, '<p color="#aa0000" fontFamily="Arial" fontSize="12" kerning="auto" textAlign="left" trackingRight="0"><span fontStyle="italic" fontWeight="bold">hello</span></p>');
+            validateMarkup(importer, "testHTMLMarkup:htmlTest2", htmlTest2, '<p color="#aa0000" fontFamily="Arial" fontSize="12" kerning="auto" textAlign="left" trackingRight="0"><span fontStyle="italic" fontWeight="bold"></span></p>');
+            validateMarkup(importer, "testHTMLMarkup:htmlTest3", htmlTest3, '<p><span fontWeight="bold"></span></p>');
+            validateMarkup(importer, "testHTMLMarkup:htmlTest4a", htmlTest4a, '<p><span fontWeight="bold"></span></p>');
+            validateMarkup(importer, "testHTMLMarkup:htmlTest4b", htmlTest4b, '<p><span>Some Text</span></p>');
+
+            validateMarkup(importer, "testHTMLMarkup:htmlTest1.toString()", makeXMLIntoString(htmlTest1), '<p color="#aa0000" fontFamily="Arial" fontSize="12" kerning="auto" textAlign="left" trackingRight="0"><span fontStyle="italic" fontWeight="bold">hello</span></p>');
+            validateMarkup(importer, "testHTMLMarkup:htmlTest2.toString()", makeXMLIntoString(htmlTest2), '<p color="#aa0000" fontFamily="Arial" fontSize="12" kerning="auto" textAlign="left" trackingRight="0"><span fontStyle="italic" fontWeight="bold"></span></p>');
+            // validateMarkup(importer, "testHTMLMarkup:htmlTest3.toString()", makeXMLIntoString(htmlTest3),'<p><span fontWeight="bold"></span></p>');
+            // validateMarkup(importer, "testHTMLMarkup:htmlTest4.toString()", makeXMLIntoString(htmlTest4),'<p><span fontWeight="bold"></span></p>');
+            var test5Result:String = '<p leadingModel="approximateTextField" lineHeight="200%"><span fontStyle="italic" fontWeight="bold">BoldItalic</span><span> Plain </span><span fontStyle="italic">Italic</span><span> Plain </span><span fontWeight="bold">Bold</span></p>';
+            validateMarkup(importer, "testHTMLMarkup:htmlTest5a", htmlTest5a, test5Result);
+            validateMarkup(importer, "testHTMLMarkup:htmlTest5b", htmlTest5b, test5Result);
+            validateMarkup(importer, "testHTMLMarkup:htmlTest6", htmlTest6, '<p><span fontStyle="italic" fontWeight="bold" lineThrough="true">StrikeThroughBoldItalic</span></p>');
+            validateMarkup(importer, "testHTMLMarkup:htmlTest7", htmlTest7, '<list listStyleType="disc" paddingLeft="36"><listMarkerFormat><ListMarkerFormat paragraphEndIndent="14"/></listMarkerFormat><li><p><span>abcd</span></p></li></list>');
+            validateMarkup(importer, "testHTMLMarkup:htmlTest8", htmlTest8, '<p textAlign="left"><g styleName="xyz" typeName="span"><span color="#000000" fontFamily="Arial" fontSize="12" fontWeight="bold" kerning="auto" trackingRight="0">Hello</span><span color="#000000" fontFamily="Arial" fontSize="12" kerning="auto" trackingRight="0"> </span><span color="#000000" fontFamily="Arial" fontSize="12" fontStyle="italic" kerning="auto" trackingRight="0">World</span></g></p>');
+
+            // enable body/html tags
+            (importer as IHTMLImporter).preserveHTMLElement = true;
+            (importer as IHTMLImporter).preserveBodyElement = true;
+
+            validateMarkup(importer, "testHTMLMarkup:htmlTest1", htmlTest1, '<p color="#aa0000" fontFamily="Arial" fontSize="12" kerning="auto" textAlign="left" trackingRight="0"><span fontStyle="italic" fontWeight="bold">hello</span></p>', true, true);
+            validateMarkup(importer, "testHTMLMarkup:htmlTest2", htmlTest2, '<p color="#aa0000" fontFamily="Arial" fontSize="12" kerning="auto" textAlign="left" trackingRight="0"><span fontStyle="italic" fontWeight="bold"></span></p>', true, true);
+            validateMarkup(importer, "testHTMLMarkup:htmlTest1.toString()", makeXMLIntoString(htmlTest1), '<p color="#aa0000" fontFamily="Arial" fontSize="12" kerning="auto" textAlign="left" trackingRight="0"><span fontStyle="italic" fontWeight="bold">hello</span></p>', true, true);
+            validateMarkup(importer, "testHTMLMarkup:htmlTest2.toString()", makeXMLIntoString(htmlTest2), '<p color="#aa0000" fontFamily="Arial" fontSize="12" kerning="auto" textAlign="left" trackingRight="0"><span fontStyle="italic" fontWeight="bold"></span></p>', true, true);
+
+        }
+
+        [Test]
+        public function testHTMLMarkupClassAndId():void
+        {
+            var importer:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_FIELD_HTML_FORMAT);
+            validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest1", htmlCIDTest1, '<p><span id="x1">abcd</span></p>');
+            validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest2", htmlCIDTest2, '<p><g id="x1" typeName="span"><span>abcd</span><span fontWeight="bold">XYZ</span></g></p>');
+            validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest3", htmlCIDTest3, '<p><span>abcd</span><span fontWeight="bold">XYZ</span></p>');
+            validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest4", htmlCIDTest4, '<p><g fontStyle="italic" id="x1" typeName="span"><span>abcd</span><span fontWeight="bold">XYZ</span></g></p>');
+            validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest5", htmlCIDTest5, '<p><g fontStyle="italic" typeName="span"><span>abcd</span><span fontWeight="bold">XYZ</span></g></p>');
+            validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest6", htmlCIDTest6, '<p><g styleName="x1" typeName="span"><span>abcd</span><span fontWeight="bold">XYZ</span></g></p>');
+            validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest7", htmlCIDTest7, '<p><span>abcd</span><span fontWeight="bold">XYZ</span></p>');
+            validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest8", htmlCIDTest8, '<p><g fontStyle="italic" styleName="x1" typeName="span"><span>abcd</span><span fontWeight="bold">XYZ</span></g></p>');
+            validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest9", htmlCIDTest9, '<p><g fontStyle="italic" typeName="span"><span>abcd</span><span fontWeight="bold">XYZ</span></g></p>');
+            validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest10", htmlCIDTest10, '<list listStyleType="disc" paddingLeft="36" id="ulid"><listMarkerFormat><ListMarkerFormat paragraphEndIndent="14"/></listMarkerFormat><li id="liid"><p id="pid"><span>noid</span><span id="spanid">spanid</span><img id="imgid"/><span></span></p></li></list><list listStyleType="decimal" paddingLeft="36" id="olid"><listMarkerFormat><ListMarkerFormat paragraphEndIndent="14"/></listMarkerFormat><p><span>olid</span></p></list>');
+            validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest11", htmlCIDTest11, '<list listStyleType="disc" paddingLeft="36" styleName="ulid"><listMarkerFormat><ListMarkerFormat paragraphEndIndent="14"/></listMarkerFormat><li styleName="liclass"><p styleName="pclass"><span>noclass</span><span styleName="spanclass">spanclass</span><img styleName="imgclass"/><span styleName="imgclass"></span></p></li></list><list listStyleType="decimal" paddingLeft="36" styleName="olclass"><listMarkerFormat><ListMarkerFormat paragraphEndIndent="14"/></listMarkerFormat><p><span>olclass</span></p></list>');
+        }
 
-			// missing end tag
-			const markup5:String = '<p><font size="20">end tag is not optional for font element</p>';
-			textFlow = textImporter.importToFlow(markup5);
-			assertTrue("Expected one error on import and no TextFlow",textImporter.errors != null && textImporter.errors.length == 1);
+        [Test]
+        public function testHTMLMarkupCustomTag():void
+        {
+            var importer:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_FIELD_HTML_FORMAT);
+            validateMarkup(importer, "testHTMLMarkupCustomTag:customTag1", customTag1, '<p typeName="foo"><span>ABCD</span></p>');
+            validateMarkup(importer, "testHTMLMarkupCustomTag:customTag2", customTag2, '<p><a typeName="foo" target="_self"><span>ABCD</span></a></p>');
+            validateMarkup(importer, "testHTMLMarkupCustomTag:customTag3", customTag3, '<p><g typeName="foo"><span>ABCD</span><span fontStyle="italic"> ITALIC</span></g></p>');
+            validateMarkup(importer, "testHTMLMarkupCustomTag:customTag4", customTag4, '<div typeName="foo"><div id="a"><p><span>text</span></p></div></div>');
+            validateMarkup(importer, "testHTMLMarkupCustomTag:customTag5", customTag5, '<div typeName="foo"><p><span>text</span></p></div>');
+            validateMarkup(importer, "testHTMLMarkupCustomTag:customTag6", customTag6, '<div typeName="foo"><div><p><span>text</span></p></div><div><p><span>text</span></p></div></div>');
+            validateMarkup(importer, "testHTMLMarkupCustomTag:customTag7", customTag7, '<div typeName="foo"><p typeName="bar"><span>ABCD</span></p></div>');
+        }
 
-			// missing start tag
-			const markup6:String = 'start tag is not optional for p element</p>';
-			textFlow = textImporter.importToFlow(markup6);
-			assertTrue("Expected one error on import and no TextFlow",textImporter.errors != null && textImporter.errors.length == 1);
+        private static function isEqualDescriptor(descriptor1:FormatDescriptor, descriptor2:FormatDescriptor):Boolean
+        {
+            return descriptor1.format == descriptor2.format && descriptor1.importerClass == descriptor2.importerClass &&
+                    descriptor1.exporterClass == descriptor2.exporterClass && descriptor1.clipboardFormat == descriptor2.clipboardFormat;
+        }
 
-			// unknown element
-			const markup8:String = '<image height="19" width="19" src="surprised.png" align="right">';
-			textFlow = textImporter.importToFlow(markup8);
-			assertTrue("Expected one error on import and no TextFlow",textImporter.errors != null && textImporter.errors.length == 1);
+        [Test]
+        public function addAndRemoveFormat():void
+        {
+            var i:int;
 
-			// unknown attribute
-			const markup9:String = '<p textAlign="center">Wrong attr name</p>';
-			textFlow = textImporter.importToFlow(markup9);
-			assertTrue("Expected one error on import and no TextFlow",textImporter.errors != null && textImporter.errors.length == 1);
+            var descriptor:FormatDescriptor;
+            var protoDescriptor:FormatDescriptor = new FormatDescriptor("foo", MyImporter, MyExporter, "air:text");
+            // Test simple addFormat, removeFormatAt
+            var numFormats:int = TextConverter.numFormats;
+            var descriptorArray:Array = [];
+            for (i = 0; i < numFormats; ++i)
+                descriptorArray.push(TextConverter.getFormatDescriptorAt(i));
+            TextConverter.addFormat(protoDescriptor.format, protoDescriptor.importerClass, protoDescriptor.exporterClass, protoDescriptor.clipboardFormat);
+            assertTrue("Expected format count to increase by one", TextConverter.numFormats == numFormats + 1);
+            for (i = 0; i < numFormats; ++i)
+            {
+                descriptor = TextConverter.getFormatDescriptorAt(i);
+                assertTrue(isEqualDescriptor(descriptor, descriptorArray[i]), "Expected previously existing descriptor to remain unchanged");
+            }
+            descriptor = TextConverter.getFormatDescriptorAt(TextConverter.numFormats - 1);
+            assertTrue(isEqualDescriptor(descriptor, protoDescriptor), "New format doesn't have the correct parameters");
+            TextConverter.removeFormatAt(numFormats);
+            for (i = 0; i < numFormats; ++i)
+            {
+                descriptor = TextConverter.getFormatDescriptorAt(i);
+                assertTrue(isEqualDescriptor(descriptor, descriptorArray[i]), "Expected previously existing descriptor to remain unchanged");
+            }
 
-			*/
-		}
+            // Add at a specified position
+            var position:int = 2;
+            TextConverter.addFormatAt(position, protoDescriptor.format, protoDescriptor.importerClass, protoDescriptor.exporterClass, protoDescriptor.clipboardFormat);
+            assertTrue("Expected format count to increase by one", TextConverter.numFormats == numFormats + 1);
+            for (i = 0; i < TextConverter.numFormats; ++i)
+            {
+                descriptor = TextConverter.getFormatDescriptorAt(i);
+                if (i == position)
+                    assertTrue(isEqualDescriptor(descriptor, protoDescriptor), "Expected previously new descriptor to match parameters to addFormat");
+                else if (i < 2)
+                    assertTrue(isEqualDescriptor(descriptor, descriptorArray[i]), "Expected previously existing descriptor to remain unchanged");
+                else
+                    assertTrue(isEqualDescriptor(descriptor, descriptorArray[i - 1]), "Expected previously existing descriptor to remain unchanged");
+            }
 
-		public function testMarkupImportErrors():void
-		{
-			const markup:String = "<TextFlow columnCount='inherit' columnGap='inherit' columnWidth='inherit' lineBreak='inherit' " +
-			" paddingBottom='inherit' paddingLeft='inherit' paddingRight='inherit' paddingTop='inherit'" +
-			" verticalAlign='inherit' whiteSpaceCollapse='preserve'" +
-			" xmlns='http://ns.adobe.com/textLayout/2008'><p><a href='http://www.4literature.net/Nathaniel_Hawthorne/Ethan_Brand/' target='_self'>" +
-			" <linkHoverFormat color='#ff0000'/>" +
-			" <linkActiveFormat color='#00ff00' textDecoration='underline'/>" +
-			" <linkNormalFormat color='#0000ff'/>" +
-			" <span>Ethan Brand</span></a></p></TextFlow>";
+            // Add a duplicate
+            var duplicateDescriptor:FormatDescriptor = new FormatDescriptor("foo", MyImporter, null, null);
+            numFormats = TextConverter.numFormats;
+            TextConverter.addFormatAt(0, duplicateDescriptor.format, duplicateDescriptor.importerClass, duplicateDescriptor.exporterClass, duplicateDescriptor.clipboardFormat);
+            assertTrue("Expected format count to increase by one", TextConverter.numFormats == numFormats + 1);
+            for (i = 0; i < TextConverter.numFormats; ++i)
+            {
+                descriptor = TextConverter.getFormatDescriptorAt(i);
+                if (i == 0)
+                    assertTrue(isEqualDescriptor(descriptor, duplicateDescriptor), "Expected new dup descriptor to match parameters to addFormat");
+                else if (i == position)
+                    assertTrue(isEqualDescriptor(descriptor, protoDescriptor), "Expected new descriptor to match parameters to addFormat");
+                else if (i < position + 1)
+                    assertTrue(isEqualDescriptor(descriptor, descriptorArray[i - 1]), "Expected previously existing descriptor to remain unchanged");
+                else
+                    assertTrue(isEqualDescriptor(descriptor, descriptorArray[i - 2]), "Expected previously existing descriptor to remain unchanged");
+            }
+            var format:String = TextConverter.getFormatAt(position + 1);
+            assertTrue("Lookup by index ignores dup", format == protoDescriptor.format);
+            var importer:ITextImporter = TextConverter.getImporter(protoDescriptor.format);
+            assertTrue("Should use first format found when dups exist", importer is duplicateDescriptor.importerClass);
+            TextConverter.removeFormat(duplicateDescriptor.format);
+            importer = TextConverter.getImporter(protoDescriptor.format);
+            assertTrue("Should remove first format found when dups exist", importer is protoDescriptor.importerClass);
+            TextConverter.removeFormatAt(position);
+            for (i = 0; i < TextConverter.numFormats; ++i)
+            {
+                descriptor = TextConverter.getFormatDescriptorAt(i);
+                assertTrue(isEqualDescriptor(descriptor, descriptorArray[i]), "Expected previously existing descriptor to remain unchanged");
+            }
+        }
 
-			var textImporter:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_LAYOUT_FORMAT);
-			var textFlow:TextFlow;
-			textFlow = textImporter.importToFlow(markup);
-			assertTrue("Expected one error on import and no TextFlow",textImporter.errors[0] == "Expected one and only one TextLayoutFormat in http://ns.adobe.com/textLayout/2008::linkHoverFormat"
-			           && textImporter.errors[1] == "Expected one and only one TextLayoutFormat in http://ns.adobe.com/textLayout/2008::linkActiveFormat"
-			           && textImporter.errors[2] == "Expected one and only one TextLayoutFormat in http://ns.adobe.com/textLayout/2008::linkNormalFormat"
-						);
-		}
+        [Test]
+        public function clipboardImporterTest():void
+        {
+            SelManager.selectAll();
+            SelManager.deleteText();
+            SelManager.selectRange(0, 0);
+            var tf:TextFlow = SelManager.textFlow;
+            tf.removeChildAt(0);
+            var para1:ParagraphElement = new ParagraphElement();
+            var para2:ParagraphElement = new ParagraphElement();
+            var span1:SpanElement = new SpanElement();
+            var span2:SpanElement = new SpanElement();
+            span1.text = "This is a test!";
+            span2.text = "There are two paragraph.";
+            span1.color = "#FF0000";
+            span2.color = "#0000FF";
+            para1.addChild(span1);
+            para2.addChild(span2);
+            tf.addChild(para1);
+            tf.addChild(para2);
 
-		public function testMarkupImport():void
-		{
-			const markup:String = "<TextFlow columnCount='inherit' columnGap='inherit' columnWidth='inherit' lineBreak='inherit' " +
-			" paddingBottom='inherit' paddingLeft='inherit' paddingRight='inherit' paddingTop='inherit'" +
-			" verticalAlign='inherit' whiteSpaceCollapse='preserve'" +
-			" xmlns='http://ns.adobe.com/textLayout/2008'><p><a href='http://www.4literature.net/Nathaniel_Hawthorne/Ethan_Brand/' target='_self'>" +
-			" <linkHoverFormat><TextLayoutFormat color='#ff0000'/></linkHoverFormat>" +
-			" <linkActiveFormat><TextLayoutFormat color='#00ff00' textDecoration='underline'/></linkActiveFormat>" +
-			" <linkNormalFormat><TextLayoutFormat color='#0000ff'/></linkNormalFormat>" +
-			" <span>Ethan Brand</span></a></p></TextFlow>";
+            TextConverter.addFormatAt(0, "VowelsOnly", VowelsOnlyImporter, PlainTextExporter, "air:text");
+            TextConverter.addFormatAt(1, "NoVowels", NoVowelsImporter, PlainTextExporter, "air:text");
+            tf.flowComposer.updateAllControllers();
+            var originalMarkup:String = TextConverter.export(tf, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
+            //trace(originalMarkup);
+            SelManager.selectRange(16, 40);
+            var scrap:TextScrap = SelManager.cutTextScrap();
+            var markupAfterCut:String = TextConverter.export(tf, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
+            //trace(markupAfterCut);
+            assertTrue("Expected less text after cut", markupAfterCut != originalMarkup && markupAfterCut.length < originalMarkup.length);
+            SelManager.selectRange(16, 16);
+            SelManager.pasteTextScrap(scrap);
+            var markupAfterPaste:String = TextConverter.export(tf, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
+            //trace(markupAfterPaste);
+            assertTrue("Expected paste to return to original state", markupAfterPaste == originalMarkup);
 
-			var textImporter:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_LAYOUT_FORMAT);
-			var textFlow:TextFlow;
-			textFlow = textImporter.importToFlow(markup);
-			assertTrue("Import markup failed. Expected no errors on import", textImporter.errors == null);
-		}
+            SelManager.selectRange(16, 40);
+            scrap = SelManager.cutTextScrap();
+            var clipboard:Object = new Object();
+            TextClipboard.exportScrap(scrap, exportToClipboard);
+            SelManager.selectRange(0, 0);
+            scrap = TextClipboard.importScrap(importFromClipboard);
+            SelManager.pasteTextScrap(scrap);
+            var markupAfterMangledPaste:String = TextConverter.export(tf, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
+            //trace(markupAfterMangledPaste);
+            assertTrue("Expected paste to *not* to return to original state", markupAfterMangledPaste != originalMarkup);
+            var expectedMarkup:String = "<TextFlow blockProgression=\"tb\" direction=\"ltr\" fontFamily=\"Times New Roman\" fontSize=\"14\" paddingLeft=\"4\" paddingTop=\"4\" textIndent=\"15\" whiteSpaceCollapse=\"preserve\" version=\"3.0.0\" xmlns=\"http://ns.adobe.com/textLayout/2008\">"
+                    + "<p><span color=\"#ff0000\">Thr r tw prgrph.This is a test!</span></p>"
+                    + "<p><span color=\"#0000ff\"></span></p>"
+                    + "</TextFlow>";
+            assertTrue("Markup after paste from clipboard with custom format doesn't matched expected result", markupAfterMangledPaste == expectedMarkup);
 
-		public function normalizeTest():void
-		{
-			var textImporter:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_LAYOUT_FORMAT);
+            function exportToClipboard(clipboardFormat:String, clipboardData:String):void
+            {
+                clipboard[clipboardFormat] = clipboardData;
+            }
 
-			var textFlow:TextFlow;
-			var leaf:FlowLeafElement;
+            function importFromClipboard(clipboardFormat:String):String
+            {
+                return clipboard.hasOwnProperty(clipboardFormat) ? clipboard[clipboardFormat] : null;
+            }
+        }
 
-			const markup1:String = "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><a><span></span></a><a></a></TextFlow>";
-			textFlow = textImporter.importToFlow(markup1);
-			leaf = textFlow.getFirstLeaf()
-			// result is a single paragraph with a single empty span
-			// assertTrue("Markup1 - expected paragraph with empty span",textFlow.textLength == 1 && leaf && leaf == textFlow.getLastLeaf() && leaf.parent == textFlow.getChildAt(0));
+        [Test]
+        public function clipboardExporterTest():void
+        {
+            SelManager.selectAll();
+            SelManager.deleteText();
+            SelManager.selectRange(0, 0);
+            var tf:TextFlow = SelManager.textFlow;
+            tf.removeChildAt(0);
+            var para1:ParagraphElement = new ParagraphElement();
+            var para2:ParagraphElement = new ParagraphElement();
+            var span1:SpanElement = new SpanElement();
+            var span2:SpanElement = new SpanElement();
+            span1.color = "#FF0000";
+            span2.color = "#0000FF";
+            span1.text = "This is a test!";
+            span2.text = "There are two paragraph.";
+            para1.addChild(span1);
+            para2.addChild(span2);
+            tf.addChild(para1);
+            tf.addChild(para2);
+            //format NewSeperator will be triggered
+            TextConverter.addFormatAt(0, "NewSeperator", PlainTextImporter, NewSeperatorExporter, "air:text");
+            TextConverter.addFormatAt(1, "AdditionalList", TLFImporter, AdditionalListExporter, "air:text");
+            tf.flowComposer.updateAllControllers();
+            var originalMarkup:String = TextConverter.export(tf, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
+            //trace(originalMarkup);
+            SelManager.selectRange(0, 40);
+            var scrap:TextScrap = SelManager.cutTextScrap();
+            var clipboard:Object = new Object();
+            TextClipboard.exportScrap(scrap, exportToClipboard);
+            SelManager.selectRange(0, 0);
+            scrap = TextClipboard.importScrap(importFromClipboard);
+            SelManager.pasteTextScrap(scrap);
+            var markupAfterMangledPaste:String = TextConverter.export(tf, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
+            //trace(markupAfterMangledPaste);
+            var expectedMarkup:String = "<TextFlow blockProgression=\"tb\" direction=\"ltr\" fontFamily=\"Times New Roman\" fontSize=\"14\" paddingLeft=\"4\" paddingTop=\"4\" textIndent=\"15\" whiteSpaceCollapse=\"preserve\" version=\"3.0.0\" xmlns=\"http://ns.adobe.com/textLayout/2008\">"
+                    + "<p><span color=\"#ff0000\">This is a test!</span></p>"
+                    + "<p><span color=\"#ff0000\">new seperator</span></p>"
+                    + "<p><span color=\"#ff0000\">There are two paragraph.</span></p>"
+                    + "</TextFlow>";
+            assertTrue("Markup after paste from clipboard with NewSeperator format doesn't matched expected result", markupAfterMangledPaste == expectedMarkup);
 
-			const markup2:String = "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><a/></TextFlow>";
-			textFlow = textImporter.importToFlow(markup2);
-			leaf = textFlow.getFirstLeaf()
-			// result is a single paragraph with a single empty span
-			assertTrue("Markup2 - expected paragraph with empty span",textFlow.textLength == 1 && leaf && leaf == textFlow.getLastLeaf() && leaf.parent == textFlow.getChildAt(0));
+            //start a new case and get the original textflow
+            SelManager.selectAll();
+            SelManager.deleteText();
+            SelManager.selectRange(0, 0);
+            tf = SelManager.textFlow;
+            tf.removeChildAt(0);
+            para1.addChild(span1);
+            para2.addChild(span2);
+            tf.addChild(para1);
+            tf.addChild(para2);
+            //format PlainTextImporter will be triggered
+            TextConverter.addFormatAt(0, "PlainTextImporter", TLFImporter, AdditionalListExporter, "air:text");
+            TextConverter.addFormatAt(1, "NewSeperator", PlainTextImporter, NewSeperatorExporter, "air:text");
+            tf.flowComposer.updateAllControllers();
+            originalMarkup = TextConverter.export(tf, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
+            //trace(originalMarkup);
 
-			const markup3:String = "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><a/><span/></TextFlow>";
-			textFlow = textImporter.importToFlow(markup3);
-			leaf = textFlow.getFirstLeaf()
-			// result is a single paragraph with a single empty span
-			assertTrue("Markup2 - expected paragraph with empty span",textFlow.textLength == 1 && leaf && leaf == textFlow.getLastLeaf() && leaf.parent == textFlow.getChildAt(0));
-		}
-		
-		public function testInvalidListStyleTypeErrors():void
-		{
-			var textImporter:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_LAYOUT_FORMAT);
-			var textFlow:TextFlow;
-			
-			// wrong listSytleTyle underline
-			const markup1:String = "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><list paddingRight='24' paddingLeft='24' listStyleType='underline'><li>underline item</li><li>another</li></list></TextFlow>";
-			textFlow = textImporter.importToFlow(markup1);
-			assertTrue("Expected out of range error",
-				textImporter.errors[0] == "Property listStyleType value underline is out of range")
-			
-			// wrong listStyleTyle StrikThrough
-			const markup2:String = "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><list paddingRight='24' paddingLeft='24' listStyleType='Strikethrough'><li>Strikethrough item</li><li>another</li></list></TextFlow>";
-			textFlow = textImporter.importToFlow(markup2);
-			assertTrue("Expected out of range error",
-				textImporter.errors[0] == "Property listStyleType value Strikethrough is out of range")
-			
-			// wrong listSytleTyle aaaa
-			const markup3:String = "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><list paddingRight='24' paddingLeft='24' listStyleType='aaaa'><li>aaaa item</li><li>another</li></list></TextFlow>";
-			textFlow = textImporter.importToFlow(markup3);
-			assertTrue("Expected out of range error",
-				textImporter.errors[0] == "Property listStyleType value aaaa is out of range")
-		}
-		
-		public function imgSourceFilterFunction():void
-		{
-			var textFlow:TextFlow;
-			var elem:FlowLeafElement;
-			var textImporter:ITextImporter;
-			var replacedSource:String;
-			
-			// TEXT_LAYOUT_FORMAT
-			replacedSource = "XYZ:";
-			textImporter = TextConverter.getImporter(TextConverter.TEXT_LAYOUT_FORMAT);
-			(textImporter as ITextLayoutImporter).imageSourceResolveFunction = function (source:String):String { replacedSource += source; return replacedSource; };
-			textFlow = textImporter.importToFlow("<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><img source='xyz.jpg'/></TextFlow>");
-			assertTrue("TextLayoutFormat: Too many calls to imgSourceFilterFunction",replacedSource == "XYZ:xyz.jpg");
-			elem = textFlow.getFirstLeaf();
-			assertTrue("TextLayoutFormat: Incorrect source on first leaf",elem is InlineGraphicElement && (elem as InlineGraphicElement).source == "XYZ:xyz.jpg");
-			
-			// TEXT_FIELD_HTML_FORMAT
-			replacedSource = "XYZ:";
-			textImporter = TextConverter.getImporter(TextConverter.TEXT_FIELD_HTML_FORMAT);
-			(textImporter as IHTMLImporter).imageSourceResolveFunction = function (source:String):String { replacedSource += source; return replacedSource; };
-			textFlow = textImporter.importToFlow("<img src='xyz.jpg'/>");
-			assertTrue("TextFieldHTMLFormat: Too many calls to imgSourceFilterFunction",replacedSource == "XYZ:xyz.jpg");
-			elem = textFlow.getFirstLeaf();
-			assertTrue("TextFieldHTMLFormat: Incorrect source on first leaf",elem is InlineGraphicElement && (elem as InlineGraphicElement).source == "XYZ:xyz.jpg");			
-		}
-		
-		// helper function convert XML to a string without pretty printing
-		static public function makeXMLIntoString(source:XML):String
-		{
-			var rslt:String;
-			// turn off pretty printing when making the string
-			var savedPretty:Boolean = XML.prettyPrinting;
-			try
-			{
-				XML.prettyPrinting = false;
-				rslt = source.toString();
-			}
-			finally
-			{
-				XML.prettyPrinting = savedPretty;
-			}
-			return rslt;
-		}
-		
-		// helper function - imports and then checks an expected result
-		static public function validateMarkup(importer:ITextImporter, testName:String,source:*,expectedResult:String,expectHtmlType:Boolean = false,expectBodyType:Boolean = false):void
-		{
-			var prefix:String;
-			var postfix:String;
-			if (expectHtmlType)
-				prefix = '<TextFlow typeName="html" whiteSpaceCollapse="preserve" version="3.0.0" xmlns="http://ns.adobe.com/textLayout/2008">';
-			else
-				prefix = '<TextFlow whiteSpaceCollapse="preserve" version="3.0.0" xmlns="http://ns.adobe.com/textLayout/2008">';
-			
-			if (expectBodyType)
-			{
-				prefix += '<div typeName="body">';
-				postfix = '</div></TextFlow>'
-			}
-			else
-				postfix = '</TextFlow>';
-			
-			expectedResult = prefix + expectedResult + postfix;
-			
-			var textFlow:TextFlow = importer.importToFlow(source);
-			var rslt:String = TextConverter.export(textFlow,TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
-			/*if (rslt != expectedResult)
-			{
-				trace(expectedResult);
-				trace(rslt);
-			}*/
-			assertTrue(testName + ": failed",rslt == expectedResult);
-		}
-		
-		static private const htmlTest1:XML = <HTML> 
-		  <BODY> 
-			<P ALIGN="left">
-			  <FONT FACE="Arial" SIZE="12" COLOR="#AA0000" LETTERSPACING="0" KERNING="1"> 
-				  <b><i>hello</i></b> 
-				</FONT> 
-			</P> 
-		  </BODY> 
-		</HTML>;
-		
-		static private const htmlTest2:XML = <HTML> 
-		  <BODY> 
-			<P ALIGN="left">
-			  <FONT FACE="Arial" SIZE="12" COLOR="#AA0000" LETTERSPACING="0" KERNING="1"> 
-				  <b><i></i></b> 
-				</FONT> 
-			</P> 
-		  </BODY> 
-		</HTML>;
-		
-		static private const htmlTest3:XML = <p><font><b/></font></p>;
-		
-		static private const htmlTest4a:XML = <p><b/></p>;
-		static private const htmlTest4b:XML = <p>Some Text</p>;
-		
-		// as XML all the leading/trailing whitespace gets stripped.  Next two should produce indentical results
-		static private const htmlTest5a:String = '<p><textformat leading="200%"><i><b>BoldItalic</b></i> </textformat>Plain <i>Italic</i> Plain <b>Bold</b></p>';
-		static private const htmlTest5b:String = '<textformat leading="200%"><i><b>BoldItalic</b></i> </textformat>Plain <i>Italic</i> Plain <b>Bold</b>';
-		
-		// strikeThrough test
-		static private const htmlTest6:String = '<p><s><i><b>StrikeThroughBoldItalic</b></i></b></s></p>';
-		
-		// naked listitem test
-		static private const htmlTest7:String = '<li>abcd</li>';
-		
-		// tests that the group created by the parent of the tested span has the correct typename
-		static private const htmlTest8:String = '<P ALIGN="left"><span class="xyz"><FONT FACE="Arial" SIZE="12" COLOR="#000000" LETTERSPACING="0" KERNING="1"><B>Hello</B> <I>World</I></FONT><span></P>'
-		
-		public function testHTMLMarkup():void
-		{
-			var importer:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_FIELD_HTML_FORMAT);
-			
-			validateMarkup(importer, "testHTMLMarkup:htmlTest1",htmlTest1,'<p color="#aa0000" fontFamily="Arial" fontSize="12" kerning="auto" textAlign="left" trackingRight="0"><span fontStyle="italic" fontWeight="bold">hello</span></p>');
-			validateMarkup(importer, "testHTMLMarkup:htmlTest2",htmlTest2,'<p color="#aa0000" fontFamily="Arial" fontSize="12" kerning="auto" textAlign="left" trackingRight="0"><span fontStyle="italic" fontWeight="bold"></span></p>');
-			validateMarkup(importer, "testHTMLMarkup:htmlTest3",htmlTest3,'<p><span fontWeight="bold"></span></p>');
-			validateMarkup(importer, "testHTMLMarkup:htmlTest4a",htmlTest4a,'<p><span fontWeight="bold"></span></p>');
-			validateMarkup(importer, "testHTMLMarkup:htmlTest4b",htmlTest4b,'<p><span>Some Text</span></p>');
-			
-			validateMarkup(importer, "testHTMLMarkup:htmlTest1.toString()",makeXMLIntoString(htmlTest1),'<p color="#aa0000" fontFamily="Arial" fontSize="12" kerning="auto" textAlign="left" trackingRight="0"><span fontStyle="italic" fontWeight="bold">hello</span></p>');
-			validateMarkup(importer, "testHTMLMarkup:htmlTest2.toString()",makeXMLIntoString(htmlTest2),'<p color="#aa0000" fontFamily="Arial" fontSize="12" kerning="auto" textAlign="left" trackingRight="0"><span fontStyle="italic" fontWeight="bold"></span></p>');
-			// validateMarkup(importer, "testHTMLMarkup:htmlTest3.toString()", makeXMLIntoString(htmlTest3),'<p><span fontWeight="bold"></span></p>');
-			// validateMarkup(importer, "testHTMLMarkup:htmlTest4.toString()", makeXMLIntoString(htmlTest4),'<p><span fontWeight="bold"></span></p>');
-			var test5Result:String = '<p leadingModel="approximateTextField" lineHeight="200%"><span fontStyle="italic" fontWeight="bold">BoldItalic</span><span> Plain </span><span fontStyle="italic">Italic</span><span> Plain </span><span fontWeight="bold">Bold</span></p>';
-			validateMarkup(importer, "testHTMLMarkup:htmlTest5a", htmlTest5a, test5Result);
-			validateMarkup(importer, "testHTMLMarkup:htmlTest5b", htmlTest5b, test5Result);
-			validateMarkup(importer, "testHTMLMarkup:htmlTest6",htmlTest6,'<p><span fontStyle="italic" fontWeight="bold" lineThrough="true">StrikeThroughBoldItalic</span></p>');
-			validateMarkup(importer, "testHTMLMarkup:htmlTest7",htmlTest7,'<list listStyleType="disc" paddingLeft="36"><listMarkerFormat><ListMarkerFormat paragraphEndIndent="14"/></listMarkerFormat><li><p><span>abcd</span></p></li></list>');
-			validateMarkup(importer, "testHTMLMarkup:htmlTest8",htmlTest8,'<p textAlign="left"><g styleName="xyz" typeName="span"><span color="#000000" fontFamily="Arial" fontSize="12" fontWeight="bold" kerning="auto" trackingRight="0">Hello</span><span color="#000000" fontFamily="Arial" fontSize="12" kerning="auto" trackingRight="0"> </span><span color="#000000" fontFamily="Arial" fontSize="12" fontStyle="italic" kerning="auto" trackingRight="0">World</span></g></p>');
-			
-			// enable body/html tags
-			(importer as IHTMLImporter).preserveHTMLElement = true;
-			(importer as IHTMLImporter).preserveBodyElement = true;
-			
-			validateMarkup(importer, "testHTMLMarkup:htmlTest1",htmlTest1,'<p color="#aa0000" fontFamily="Arial" fontSize="12" kerning="auto" textAlign="left" trackingRight="0"><span fontStyle="italic" fontWeight="bold">hello</span></p>',true, true);
-			validateMarkup(importer, "testHTMLMarkup:htmlTest2",htmlTest2,'<p color="#aa0000" fontFamily="Arial" fontSize="12" kerning="auto" textAlign="left" trackingRight="0"><span fontStyle="italic" fontWeight="bold"></span></p>',true, true);
-			validateMarkup(importer, "testHTMLMarkup:htmlTest1.toString()",makeXMLIntoString(htmlTest1),'<p color="#aa0000" fontFamily="Arial" fontSize="12" kerning="auto" textAlign="left" trackingRight="0"><span fontStyle="italic" fontWeight="bold">hello</span></p>',true, true);
-			validateMarkup(importer, "testHTMLMarkup:htmlTest2.toString()",makeXMLIntoString(htmlTest2),'<p color="#aa0000" fontFamily="Arial" fontSize="12" kerning="auto" textAlign="left" trackingRight="0"><span fontStyle="italic" fontWeight="bold"></span></p>',true, true);
+            SelManager.selectRange(0, 40);
+            scrap = SelManager.cutTextScrap();
+            clipboard = new Object();
+            TextClipboard.exportScrap(scrap, exportToClipboard);
+            SelManager.selectRange(0, 0);
+            scrap = TextClipboard.importScrap(importFromClipboard);
+            SelManager.pasteTextScrap(scrap);
+            markupAfterMangledPaste = TextConverter.export(tf, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
+            //trace(markupAfterMangledPaste);
+            expectedMarkup = "<TextFlow blockProgression=\"tb\" direction=\"ltr\" fontFamily=\"Times New Roman\" fontSize=\"14\" paddingLeft=\"4\" paddingTop=\"4\" textIndent=\"15\" whiteSpaceCollapse=\"preserve\" version=\"3.0.0\" xmlns=\"http://ns.adobe.com/textLayout/2008\">"
+            + "<p><span color=\"#ff0000\">This is a test!</span></p>"
+            + "<p><span color=\"#0000ff\">There are two paragraph.</span>"
+            + "</p><list><li><p><span>ab</span></p></li><li><p><span>cd</span></p></li></list>"
+            + "<p><span color=\"#0000ff\"></span></p>"
+            + "</TextFlow>";
+            assertTrue("Markup after paste from clipboard with AdditionalList format doesn't matched expected result", markupAfterMangledPaste == expectedMarkup);
+            function exportToClipboard(clipboardFormat:String, clipboardData:String):void
+            {
+                clipboard[clipboardFormat] = clipboardData;
+            }
 
-		}
-		
-		static private const htmlCIDTest1:String = '<span id="x1">abcd</span>';
-		static private const htmlCIDTest2:String = '<span id="x1"><span>abcd</span><b>XYZ</b></span>';
-		static private const htmlCIDTest3:String = '<span><span>abcd</span><b>XYZ</b></span>';
-			
-		static private const htmlCIDTest4:String = '<i><span id="x1"><span>abcd</span><b>XYZ</b></span></i>';
-		static private const htmlCIDTest5:String = '<i><span><span>abcd</span><b>XYZ</b></span></i>';
-	
-		static private const htmlCIDTest6:String = '<span class="x1"><span>abcd</span><b>XYZ</b></span>';
-		static private const htmlCIDTest7:String = '<span><span>abcd</span><b>XYZ</b></span>';
-			
-		static private const htmlCIDTest8:String = '<i><span class="x1"><span>abcd</span><b>XYZ</b></span></i>';
-		static private const htmlCIDTest9:String = '<i><span><span>abcd</span><b>XYZ</b></span></i>';
-		
-		static private const htmlCIDTest10:String = '<ul id="ulid"><li id="liid"><p id="pid">noid<span id="spanid">spanid</span><img id="imgid"/></p></li></ul><ol id="olid">olid</ol>';
-		static private const htmlCIDTest11:String = '<ul class="ulid"><li class="liclass"><p class="pclass">noclass<span class="spanclass">spanclass</span><img class="imgclass"/></p></li></ul><ol class="olclass">olclass</ol>';
+            function importFromClipboard(clipboardFormat:String):String
+            {
+                return clipboard.hasOwnProperty(clipboardFormat) ? clipboard[clipboardFormat] : null;
+            }
+        }
 
-		
-		public function testHTMLMarkupClassAndId():void
-		{
-			var importer:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_FIELD_HTML_FORMAT);
-			validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest1",htmlCIDTest1,'<p><span id="x1">abcd</span></p>');
-			validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest2",htmlCIDTest2,'<p><g id="x1" typeName="span"><span>abcd</span><span fontWeight="bold">XYZ</span></g></p>');
-			validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest3",htmlCIDTest3,'<p><span>abcd</span><span fontWeight="bold">XYZ</span></p>');
-			validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest4",htmlCIDTest4,'<p><g fontStyle="italic" id="x1" typeName="span"><span>abcd</span><span fontWeight="bold">XYZ</span></g></p>');
-			validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest5",htmlCIDTest5,'<p><g fontStyle="italic" typeName="span"><span>abcd</span><span fontWeight="bold">XYZ</span></g></p>');
-			validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest6",htmlCIDTest6,'<p><g styleName="x1" typeName="span"><span>abcd</span><span fontWeight="bold">XYZ</span></g></p>');
-			validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest7",htmlCIDTest7,'<p><span>abcd</span><span fontWeight="bold">XYZ</span></p>');
-			validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest8",htmlCIDTest8,'<p><g fontStyle="italic" styleName="x1" typeName="span"><span>abcd</span><span fontWeight="bold">XYZ</span></g></p>');
-			validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest9",htmlCIDTest9,'<p><g fontStyle="italic" typeName="span"><span>abcd</span><span fontWeight="bold">XYZ</span></g></p>');
-			validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest10",htmlCIDTest10,'<list listStyleType="disc" paddingLeft="36" id="ulid"><listMarkerFormat><ListMarkerFormat paragraphEndIndent="14"/></listMarkerFormat><li id="liid"><p id="pid"><span>noid</span><span id="spanid">spanid</span><img id="imgid"/><span></span></p></li></list><list listStyleType="decimal" paddingLeft="36" id="olid"><listMarkerFormat><ListMarkerFormat paragraphEndIndent="14"/></listMarkerFormat><p><span>olid</span></p></list>');
-			validateMarkup(importer, "testHTMLMarkupClassAndId:htmlCIDTest11",htmlCIDTest11,'<list listStyleType="disc" paddingLeft="36" styleName="ulid"><listMarkerFormat><ListMarkerFormat paragraphEndIndent="14"/></listMarkerFormat><li styleName="liclass"><p styleName="pclass"><span>noclass</span><span styleName="spanclass">spanclass</span><img styleName="imgclass"/><span styleName="imgclass"></span></p></li></list><list listStyleType="decimal" paddingLeft="36" styleName="olclass"><listMarkerFormat><ListMarkerFormat paragraphEndIndent="14"/></listMarkerFormat><p><span>olclass</span></p></list>');
-		}
-		static private const customTag1:String = '<foo>ABCD</foo>';
-		static private const customTag2:String = '<p><foo><a>ABCD</a></foo></p>';
-		static private const customTag3:String = '<p><foo><span>ABCD</span><i> ITALIC</i></foo></p>';
-		static private const customTag4:String = '<foo><div id="a">text</div></foo>';
-		static private const customTag5:String = '<foo><div>text</div></foo>';
-		static private const customTag6:String = '<foo><div>text</div><div>text</div></foo>';
-		static private const customTag7:String = '<foo><bar>ABCD</bar></foo>';
+        private function checkPaddingResults(textFlow:TextFlow, expectRemoved:Boolean):void
+        {
+            var firstPara:ParagraphElement = textFlow.getFirstLeaf().getParagraph();
+            var lastPara:ParagraphElement = textFlow.getLastLeaf().getParagraph();
+            var img:InlineGraphicElement = firstPara.getFirstLeaf().getNextSibling() as InlineGraphicElement;
 
-		public function testHTMLMarkupCustomTag():void
-		{
-			var importer:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_FIELD_HTML_FORMAT);
-			validateMarkup(importer, "testHTMLMarkupCustomTag:customTag1", customTag1, '<p typeName="foo"><span>ABCD</span></p>');
-			validateMarkup(importer, "testHTMLMarkupCustomTag:customTag2", customTag2, '<p><a typeName="foo" target="_self"><span>ABCD</span></a></p>');
-			validateMarkup(importer, "testHTMLMarkupCustomTag:customTag3", customTag3, '<p><g typeName="foo"><span>ABCD</span><span fontStyle="italic"> ITALIC</span></g></p>');
-			validateMarkup(importer, "testHTMLMarkupCustomTag:customTag4", customTag4, '<div typeName="foo"><div id="a"><p><span>text</span></p></div></div>');
-			validateMarkup(importer, "testHTMLMarkupCustomTag:customTag5", customTag5, '<div typeName="foo"><p><span>text</span></p></div>');
-			validateMarkup(importer, "testHTMLMarkupCustomTag:customTag6", customTag6, '<div typeName="foo"><div><p><span>text</span></p></div><div><p><span>text</span></p></div></div>');
-			validateMarkup(importer, "testHTMLMarkupCustomTag:customTag7", customTag7, '<div typeName="foo"><p typeName="bar"><span>ABCD</span></p></div>');
-		}
-		
-		private static function isEqualDescriptor(descriptor1:FormatDescriptor, descriptor2:FormatDescriptor):Boolean
-		{
-			return descriptor1.format == descriptor2.format && descriptor1.importerClass == descriptor2.importerClass &&
-				descriptor1.exporterClass == descriptor2.exporterClass && descriptor1.clipboardFormat == descriptor2.clipboardFormat;
-		}
-		
-		public function addAndRemoveFormat():void
-		{
-			var i:int;
-			
-			var descriptor:FormatDescriptor;
-			var protoDescriptor:FormatDescriptor = new FormatDescriptor("foo", MyImporter, MyExporter, "air:text");
-			// Test simple addFormat, removeFormatAt
-			var numFormats:int = TextConverter.numFormats;
-			var descriptorArray:Array = [];
-			for (i = 0; i < numFormats; ++i)
-				descriptorArray.push(TextConverter.getFormatDescriptorAt(i));
-			TextConverter.addFormat(protoDescriptor.format, protoDescriptor.importerClass, protoDescriptor.exporterClass, protoDescriptor.clipboardFormat);
-			assertTrue("Expected format count to increase by one", TextConverter.numFormats == numFormats + 1);
-			for (i = 0; i < numFormats; ++i)
-			{
-				descriptor = TextConverter.getFormatDescriptorAt(i);
-				assertTrue(isEqualDescriptor(descriptor, descriptorArray[i]), "Expected previously existing descriptor to remain unchanged");
-			}
-			descriptor = TextConverter.getFormatDescriptorAt(TextConverter.numFormats - 1);
-			assertTrue(isEqualDescriptor(descriptor, protoDescriptor), "New format doesn't have the correct parameters");
-			TextConverter.removeFormatAt(numFormats);
-			for (i = 0; i < numFormats; ++i)
-			{
-				descriptor = TextConverter.getFormatDescriptorAt(i);
-				assertTrue(isEqualDescriptor(descriptor, descriptorArray[i]), "Expected previously existing descriptor to remain unchanged");
-			}
+            assertTrue("Padding was not propagated to TextFlow", textFlow.format.paddingTop == 4 && textFlow.format.paddingLeft == 4 && textFlow.format.paddingRight == 2 && textFlow.format.paddingBottom == 1);
 
-			// Add at a specified position
-			var position:int = 2;
-			TextConverter.addFormatAt(position, protoDescriptor.format, protoDescriptor.importerClass, protoDescriptor.exporterClass, protoDescriptor.clipboardFormat);
-			assertTrue("Expected format count to increase by one", TextConverter.numFormats == numFormats + 1);
-			for (i = 0; i < TextConverter.numFormats; ++i)
-			{
-				descriptor = TextConverter.getFormatDescriptorAt(i);
-				if (i == position)
-					assertTrue(isEqualDescriptor(descriptor, protoDescriptor), "Expected previously new descriptor to match parameters to addFormat");
-				else if (i < 2)
-					assertTrue(isEqualDescriptor(descriptor, descriptorArray[i]), "Expected previously existing descriptor to remain unchanged");
-				else 
-					assertTrue(isEqualDescriptor(descriptor, descriptorArray[i - 1]), "Expected previously existing descriptor to remain unchanged");
-			}
-			
-			// Add a duplicate
-			var duplicateDescriptor:FormatDescriptor = new FormatDescriptor("foo", MyImporter, null, null);
-			numFormats = TextConverter.numFormats;
-			TextConverter.addFormatAt(0, duplicateDescriptor.format, duplicateDescriptor.importerClass, duplicateDescriptor.exporterClass, duplicateDescriptor.clipboardFormat);
-			assertTrue("Expected format count to increase by one", TextConverter.numFormats == numFormats + 1);
-			for (i = 0; i < TextConverter.numFormats; ++i)
-			{
-				descriptor = TextConverter.getFormatDescriptorAt(i);
-				if (i == 0)
-					assertTrue(isEqualDescriptor(descriptor, duplicateDescriptor), "Expected new dup descriptor to match parameters to addFormat");
-				else if (i == position)
-					assertTrue(isEqualDescriptor(descriptor, protoDescriptor), "Expected new descriptor to match parameters to addFormat");
-				else if (i < position + 1)
-					assertTrue(isEqualDescriptor(descriptor, descriptorArray[i - 1]), "Expected previously existing descriptor to remain unchanged");
-				else 
-					assertTrue(isEqualDescriptor(descriptor, descriptorArray[i - 2]), "Expected previously existing descriptor to remain unchanged");
-			}
-			var format:String = TextConverter.getFormatAt(position + 1);
-			assertTrue("Lookup by index ignores dup", format == protoDescriptor.format);
-			var importer:ITextImporter = TextConverter.getImporter(protoDescriptor.format);
-			assertTrue("Should use first format found when dups exist", importer is duplicateDescriptor.importerClass);
-			TextConverter.removeFormat(duplicateDescriptor.format);
-			importer = TextConverter.getImporter(protoDescriptor.format);
-			assertTrue("Should remove first format found when dups exist", importer is protoDescriptor.importerClass);
-			TextConverter.removeFormatAt(position);
-			for (i = 0; i < TextConverter.numFormats; ++i)
-			{
-				descriptor = TextConverter.getFormatDescriptorAt(i);
-				assertTrue(isEqualDescriptor(descriptor, descriptorArray[i]), "Expected previously existing descriptor to remain unchanged");
-			}
-		}
-		
-		public function clipboardImporterTest():void
-		{
-			SelManager.selectAll();
-			SelManager.deleteText();
-			SelManager.selectRange(0,0);
-			var tf:TextFlow = SelManager.textFlow;
-			tf.removeChildAt(0);			
-			var para1:ParagraphElement = new ParagraphElement();
-			var para2:ParagraphElement = new ParagraphElement();
-			var span1:SpanElement = new SpanElement();
-			var span2:SpanElement = new SpanElement();
-			span1.text = "This is a test!";
-			span2.text = "There are two paragraph.";
-			span1.color = "#FF0000";
-			span2.color = "#0000FF";
-			para1.addChild(span1);
-			para2.addChild(span2);
-			tf.addChild(para1);
-			tf.addChild(para2);
-			
-			TextConverter.addFormatAt(0, "VowelsOnly", VowelsOnlyImporter, PlainTextExporter, "air:text");
-			TextConverter.addFormatAt(1, "NoVowels", NoVowelsImporter, PlainTextExporter, "air:text" );
-			tf.flowComposer.updateAllControllers();
-			var originalMarkup:String = TextConverter.export(tf, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
-			//trace(originalMarkup);
-			SelManager.selectRange(16,40);
-			var scrap:TextScrap = SelManager.cutTextScrap();
-			var markupAfterCut:String = TextConverter.export(tf, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
-			//trace(markupAfterCut);
-			assertTrue("Expected less text after cut", markupAfterCut != originalMarkup && markupAfterCut.length < originalMarkup.length);
-			SelManager.selectRange(16,16);
-			SelManager.pasteTextScrap(scrap);
-			var markupAfterPaste:String = TextConverter.export(tf, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
-			//trace(markupAfterPaste);
-			assertTrue("Expected paste to return to original state", markupAfterPaste == originalMarkup);
-			
-			SelManager.selectRange(16,40);
-			scrap = SelManager.cutTextScrap();
-			var clipboard:Object = new Object();
-			TextClipboard.exportScrap(scrap, exportToClipboard);
-			SelManager.selectRange(0,0);
-			scrap = TextClipboard.importScrap(importFromClipboard);
-			SelManager.pasteTextScrap(scrap);
-			var markupAfterMangledPaste:String = TextConverter.export(tf, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
-			//trace(markupAfterMangledPaste);
-			assertTrue("Expected paste to *not* to return to original state", markupAfterMangledPaste != originalMarkup);
-			var expectedMarkup:String = "<TextFlow blockProgression=\"tb\" direction=\"ltr\" fontFamily=\"Times New Roman\" fontSize=\"14\" paddingLeft=\"4\" paddingTop=\"4\" textIndent=\"15\" whiteSpaceCollapse=\"preserve\" version=\"3.0.0\" xmlns=\"http://ns.adobe.com/textLayout/2008\">" 
-				+"<p><span color=\"#ff0000\">Thr r tw prgrph.This is a test!</span></p>" 
-				+"<p><span color=\"#0000ff\"></span></p>" 
-				+"</TextFlow>";
-			assertTrue("Markup after paste from clipboard with custom format doesn't matched expected result", markupAfterMangledPaste == expectedMarkup );
-			
-			function exportToClipboard(clipboardFormat:String, clipboardData:String):void
-			{
-				clipboard[clipboardFormat] = clipboardData;
-			}
-			function importFromClipboard(clipboardFormat:String):String
-			{
-				return clipboard.hasOwnProperty(clipboardFormat) ? clipboard[clipboardFormat] : null;
-			}
-		}
-		
-		public function clipboardExporterTest():void
-		{
-			SelManager.selectAll();
-			SelManager.deleteText();
-			SelManager.selectRange(0,0);
-			var tf:TextFlow = SelManager.textFlow;
-			tf.removeChildAt(0);			
-			var para1:ParagraphElement = new ParagraphElement();
-			var para2:ParagraphElement = new ParagraphElement();
-			var span1:SpanElement = new SpanElement();
-			var span2:SpanElement = new SpanElement();
-			span1.color = "#FF0000";
-			span2.color = "#0000FF";
-			span1.text = "This is a test!";
-			span2.text = "There are two paragraph.";
-			para1.addChild(span1);
-			para2.addChild(span2);
-			tf.addChild(para1);
-			tf.addChild(para2);
-			//format NewSeperator will be triggered
-			TextConverter.addFormatAt(0, "NewSeperator", PlainTextImporter, NewSeperatorExporter, "air:text");
-			TextConverter.addFormatAt(1, "AdditionalList", TLFImporter, AdditionalListExporter, "air:text" );
-			tf.flowComposer.updateAllControllers();
-			var originalMarkup:String = TextConverter.export(tf, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
-			//trace(originalMarkup);		
-			SelManager.selectRange(0,40);
-			var scrap:TextScrap = SelManager.cutTextScrap();
-			var clipboard:Object = new Object();
-			TextClipboard.exportScrap(scrap, exportToClipboard);
-			SelManager.selectRange(0,0);
-			scrap = TextClipboard.importScrap(importFromClipboard);
-			SelManager.pasteTextScrap(scrap);
-			var markupAfterMangledPaste:String = TextConverter.export(tf, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
-			//trace(markupAfterMangledPaste);
-			var expectedMarkup:String = "<TextFlow blockProgression=\"tb\" direction=\"ltr\" fontFamily=\"Times New Roman\" fontSize=\"14\" paddingLeft=\"4\" paddingTop=\"4\" textIndent=\"15\" whiteSpaceCollapse=\"preserve\" version=\"3.0.0\" xmlns=\"http://ns.adobe.com/textLayout/2008\">"
-				+ "<p><span color=\"#ff0000\">This is a test!</span></p>"
-				+ "<p><span color=\"#ff0000\">new seperator</span></p>" 
-				+ "<p><span color=\"#ff0000\">There are two paragraph.</span></p>" 
-				+ "</TextFlow>";
-			assertTrue("Markup after paste from clipboard with NewSeperator format doesn't matched expected result", markupAfterMangledPaste == expectedMarkup );
-			
-			//start a new case and get the original textflow
-			SelManager.selectAll();
-			SelManager.deleteText();
-			SelManager.selectRange(0,0);
-			tf = SelManager.textFlow;
-			tf.removeChildAt(0);			
-			para1.addChild(span1);
-			para2.addChild(span2);
-			tf.addChild(para1);
-			tf.addChild(para2);
-			//format PlainTextImporter will be triggered
-			TextConverter.addFormatAt(0, "PlainTextImporter", TLFImporter, AdditionalListExporter, "air:text" );
-			TextConverter.addFormatAt(1, "NewSeperator", PlainTextImporter, NewSeperatorExporter, "air:text");
-			tf.flowComposer.updateAllControllers();
-			originalMarkup = TextConverter.export(tf, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
-			//trace(originalMarkup);
-			
-			SelManager.selectRange(0,40);
-			scrap = SelManager.cutTextScrap();
-			clipboard = new Object();
-			TextClipboard.exportScrap(scrap, exportToClipboard);
-			SelManager.selectRange(0,0);
-			scrap = TextClipboard.importScrap(importFromClipboard);
-			SelManager.pasteTextScrap(scrap);
-			markupAfterMangledPaste = TextConverter.export(tf, TextConverter.TEXT_LAYOUT_FORMAT, ConversionType.STRING_TYPE) as String;
-			//trace(markupAfterMangledPaste);
-			expectedMarkup = "<TextFlow blockProgression=\"tb\" direction=\"ltr\" fontFamily=\"Times New Roman\" fontSize=\"14\" paddingLeft=\"4\" paddingTop=\"4\" textIndent=\"15\" whiteSpaceCollapse=\"preserve\" version=\"3.0.0\" xmlns=\"http://ns.adobe.com/textLayout/2008\">" 
-				+"<p><span color=\"#ff0000\">This is a test!</span></p>"
-				+"<p><span color=\"#0000ff\">There are two paragraph.</span>"
-				+"</p><list><li><p><span>ab</span></p></li><li><p><span>cd</span></p></li></list>"
-				+"<p><span color=\"#0000ff\"></span></p>"
-				+"</TextFlow>";
-			assertTrue("Markup after paste from clipboard with AdditionalList format doesn't matched expected result", markupAfterMangledPaste == expectedMarkup );
-			function exportToClipboard(clipboardFormat:String, clipboardData:String):void
-			{
-				clipboard[clipboardFormat] = clipboardData;
-			}
-			function importFromClipboard(clipboardFormat:String):String
-			{
-				return clipboard.hasOwnProperty(clipboardFormat) ? clipboard[clipboardFormat] : null;
-			}
-		}
-	}
+            if (expectRemoved)
+            {
+                assertTrue("Padding was not removed from first paragraph", firstPara.paddingTop === undefined && firstPara.paddingLeft === undefined && firstPara.paddingRight === undefined && firstPara.paddingBottom === undefined);
+                assertTrue("Padding was not removed from last paragraph", lastPara.paddingTop === undefined && lastPara.paddingLeft === undefined && lastPara.paddingRight === undefined && lastPara.paddingBottom === undefined);
+                assertTrue("Padding was not removed from img", img.paddingTop === undefined && img.paddingLeft === undefined && img.paddingRight === undefined && img.paddingBottom === undefined);
+            }
+            else
+            {
+                assertTrue("Padding was not propagated to first paragraph", firstPara.format.paddingTop == 4 && firstPara.format.paddingLeft == 4 && firstPara.format.paddingRight == 2 && firstPara.format.paddingBottom == 1);
+                assertTrue("Padding was not propagated to last paragraph", lastPara.format.paddingTop == 4 && lastPara.format.paddingLeft == 4 && lastPara.format.paddingRight == 2 && lastPara.format.paddingBottom == 1);
+                assertTrue("Padding was not propagated to img", img.format.paddingTop == 4 && img.format.paddingLeft == 4 && img.format.paddingRight == 2 && img.format.paddingBottom == 1);
+            }
+        }
+    }
 }
 
-import flashx.textLayout.conversion.ITextImporter;
 import flashx.textLayout.conversion.ConverterBase;
+import flashx.textLayout.conversion.ITextExporter;
+import flashx.textLayout.conversion.ITextImporter;
+import flashx.textLayout.conversion.PlainTextExporter;
+import flashx.textLayout.conversion.TextConverter;
 import flashx.textLayout.elements.IConfiguration;
+import flashx.textLayout.elements.ListElement;
+import flashx.textLayout.elements.ListItemElement;
+import flashx.textLayout.elements.ParagraphElement;
+import flashx.textLayout.elements.SpanElement;
 import flashx.textLayout.elements.TextFlow;
 
 class MyImporter extends ConverterBase implements ITextImporter
-{	
-	private var _config:IConfiguration;
-	
-	/** Constructor */
-	public function MyImporter()
-	{
-		super();
-	}
-	
-	public function importToFlow(source:Object):TextFlow
-	{
-		return null;
-	}
-	public function get configuration():IConfiguration
-	{
-		return _config;
-	}
-	
-	public function set configuration(value:IConfiguration):void
-	{
-		_config = value;
-	}
+{
+    private var _config:IConfiguration;
+
+    /** Constructor */
+    public function MyImporter()
+    {
+        super();
+    }
+
+    public function importToFlow(source:Object):TextFlow
+    {
+        return null;
+    }
+
+    public function get configuration():IConfiguration
+    {
+        return _config;
+    }
+
+    public function set configuration(value:IConfiguration):void
+    {
+        _config = value;
+    }
 }
 
 
-import flashx.textLayout.conversion.ITextImporter;
-import flashx.textLayout.conversion.ConverterBase;
-import flashx.textLayout.elements.TextFlow;
-
 class DupImporter extends MyImporter implements ITextImporter
-{	
-	/** Constructor */
-	public function DupImporter()
-	{
-		super();
-	}
+{
+    /** Constructor */
+    public function DupImporter()
+    {
+        super();
+    }
 }
 
 
-import flashx.textLayout.conversion.ITextExporter;
-import flashx.textLayout.conversion.ConverterBase;
-import flashx.textLayout.elements.TextFlow;
-
 class MyExporter extends ConverterBase implements ITextExporter
-{	
-	/** Constructor */
-	public function MyExporter()
-	{
-		super();
-	}
-	
-	public function export(source:TextFlow, conversionType:String):Object
-	{
-		return null;
-	}
-}
+{
+    /** Constructor */
+    public function MyExporter()
+    {
+        super();
+    }
 
-import flashx.textLayout.conversion.TextConverter;
+    public function export(source:TextFlow, conversionType:String):Object
+    {
+        return null;
+    }
+}
 
 class VowelsOnlyImporter extends ConverterBase implements ITextImporter
 {
-	protected var _config:IConfiguration = null;
-	
-	/** Constructor */
-	public function VowelsOnlyImporter()
-	{
-		super();
-	}
-	
-	public function importToFlow(source:Object):TextFlow
-	{
-		if (source is String)
-		{
-			var firstChar:String = (source as String).charAt(0);
-			firstChar = firstChar.toLowerCase();
-			// This filter only applies if the first character is a vowel
-			if (firstChar == 'a' || firstChar == 'i' || firstChar == 'e' || firstChar == 'o' || firstChar == 'u')
-			{
-				var pattern:RegExp = /([b-df-hj-np-tv-z])*/g;
-				source = source.replace(pattern, "");
-				var importer:ITextImporter = TextConverter.getImporter(TextConverter.PLAIN_TEXT_FORMAT);
-				importer.useClipboardAnnotations = this.useClipboardAnnotations;
-				importer.configuration = _config;
-				return importer.importToFlow(source);
-			}
-		}
-		return null;
-	}
-	
-	public function get configuration():IConfiguration
-	{
-		return _config;
-	}
-	
-	public function set configuration(value:IConfiguration):void
-	{
-		_config = value;
-	}
+    protected var _config:IConfiguration = null;
+
+    /** Constructor */
+    public function VowelsOnlyImporter()
+    {
+        super();
+    }
+
+    public function importToFlow(source:Object):TextFlow
+    {
+        if (source is String)
+        {
+            var firstChar:String = (source as String).charAt(0);
+            firstChar = firstChar.toLowerCase();
+            // This filter only applies if the first character is a vowel
+            if (firstChar == 'a' || firstChar == 'i' || firstChar == 'e' || firstChar == 'o' || firstChar == 'u')
+            {
+                var pattern:RegExp = /([b-df-hj-np-tv-z])*/g;
+                source = source.replace(pattern, "");
+                var importer:ITextImporter = TextConverter.getImporter(TextConverter.PLAIN_TEXT_FORMAT);
+                importer.useClipboardAnnotations = this.useClipboardAnnotations;
+                importer.configuration = _config;
+                return importer.importToFlow(source);
+            }
+        }
+        return null;
+    }
+
+    public function get configuration():IConfiguration
+    {
+        return _config;
+    }
+
+    public function set configuration(value:IConfiguration):void
+    {
+        _config = value;
+    }
 }
 
 class NoVowelsImporter extends ConverterBase implements ITextImporter
 {
-	protected var _config:IConfiguration = null;
-	
-	/** Constructor */
-	public function NoVowelsImporter()
-	{
-		super();
-	}
-	
-	public function importToFlow(source:Object):TextFlow
-	{
-		if (source is String)
-		{
-			var firstChar:String = (source as String).charAt(0);
-			firstChar = firstChar.toLowerCase();
-			// This filter only applies if the first character is a vowel
-			if (!(firstChar == 'a' || firstChar == 'i' || firstChar == 'e' || firstChar == 'o' || firstChar == 'u'))
-			{
-				var pattern:RegExp = /([aieouAIEOU])*/g;
-				source = source.replace(pattern, "");
-				var importer:ITextImporter = TextConverter.getImporter(TextConverter.PLAIN_TEXT_FORMAT);
-				importer.useClipboardAnnotations = this.useClipboardAnnotations;
-				importer.configuration = _config;
-				return importer.importToFlow(source);
-			}
-		}
-		return null;
-	}
-	
-	public function get configuration():IConfiguration
-	{
-		return _config;
-	}
-	
-	public function set configuration(value:IConfiguration):void
-	{
-		_config = value;
-	}
-}
-import flashx.textLayout.conversion.PlainTextExporter;
+    protected var _config:IConfiguration = null;
 
+    /** Constructor */
+    public function NoVowelsImporter()
+    {
+        super();
+    }
+
+    public function importToFlow(source:Object):TextFlow
+    {
+        if (source is String)
+        {
+            var firstChar:String = (source as String).charAt(0);
+            firstChar = firstChar.toLowerCase();
+            // This filter only applies if the first character is a vowel
+            if (!(firstChar == 'a' || firstChar == 'i' || firstChar == 'e' || firstChar == 'o' || firstChar == 'u'))
+            {
+                var pattern:RegExp = /([aieouAIEOU])*/g;
+                source = source.replace(pattern, "");
+                var importer:ITextImporter = TextConverter.getImporter(TextConverter.PLAIN_TEXT_FORMAT);
+                importer.useClipboardAnnotations = this.useClipboardAnnotations;
+                importer.configuration = _config;
+                return importer.importToFlow(source);
+            }
+        }
+        return null;
+    }
+
+    public function get configuration():IConfiguration
+    {
+        return _config;
+    }
+
+    public function set configuration(value:IConfiguration):void
+    {
+        _config = value;
+    }
+}
 class NewSeperatorExporter extends PlainTextExporter
 {
-	/** Constructor */
-	public function NewSeperatorExporter()	
-	{
-		super();
-		this.paragraphSeparator = "\nnew seperator\n";
-	}
+    /** Constructor */
+    public function NewSeperatorExporter()
+    {
+        super();
+        this.paragraphSeparator = "\nnew seperator\n";
+    }
 }
 
-import flashx.textLayout.elements.ParagraphElement;
-import flashx.textLayout.elements.SpanElement;
-import flashx.textLayout.elements.ListElement;
-import flashx.textLayout.elements.ListItemElement;
-
 class AdditionalListExporter extends ConverterBase implements ITextExporter
 {
-	/** Constructor */
-	public function AdditionalListExporter()	
-	{
-		super();
-	}
-	
-	public function export(source:TextFlow, conversionType:String):Object
-	{
-		if (source is TextFlow)
-		{
-			source.getChildAt(source.numChildren - 1).setStyle(MERGE_TO_NEXT_ON_PASTE, false);
-			
-			var list:ListElement = new ListElement();
-			var item1:ListItemElement = new ListItemElement();
-			var item2:ListItemElement = new ListItemElement();
-			var para1:ParagraphElement = new ParagraphElement();
-			var para2:ParagraphElement = new ParagraphElement();
-			var span1:SpanElement = new SpanElement();
-			span1.text = "ab";
-			var span2:SpanElement = new SpanElement();
-			span2.text = "cd";
-			list.addChild(item1);
-			list.addChild(item2);
-			item1.addChild(para1);
-			para1.addChild(span1);
-			item2.addChild(para2);
-			para2.addChild(span2);
-			source.addChild(list);
-			
-			var exporter:ITextExporter = TextConverter.getExporter(TextConverter.TEXT_LAYOUT_FORMAT);
-			exporter.useClipboardAnnotations = this.useClipboardAnnotations;
-			return exporter.export(source, conversionType);	
-		}
-		return null;
-	}
+    /** Constructor */
+    public function AdditionalListExporter()
+    {
+        super();
+    }
+
+    public function export(source:TextFlow, conversionType:String):Object
+    {
+        if (source is TextFlow)
+        {
+            source.getChildAt(source.numChildren - 1).setStyle(MERGE_TO_NEXT_ON_PASTE, false);
+
+            var list:ListElement = new ListElement();
+            var item1:ListItemElement = new ListItemElement();
+            var item2:ListItemElement = new ListItemElement();
+            var para1:ParagraphElement = new ParagraphElement();
+            var para2:ParagraphElement = new ParagraphElement();
+            var span1:SpanElement = new SpanElement();
+            span1.text = "ab";
+            var span2:SpanElement = new SpanElement();
+            span2.text = "cd";
+            list.addChild(item1);
+            list.addChild(item2);
+            item1.addChild(para1);
+            para1.addChild(span1);
+            item2.addChild(para2);
+            para2.addChild(span2);
+            source.addChild(list);
+
+            var exporter:ITextExporter = TextConverter.getExporter(TextConverter.TEXT_LAYOUT_FORMAT);
+            exporter.useClipboardAnnotations = this.useClipboardAnnotations;
+            return exporter.export(source, conversionType);
+        }
+        return null;
+    }
 }
 
 class PlainTextImporter extends ConverterBase implements ITextImporter
 {
-	protected var _config:IConfiguration = null;
-	
-	/** Constructor */
-	public function PlainTextImporter()	
-	{
-		super();
-	}
-	
-	public function importToFlow(source:Object):TextFlow
-	{
-		if (source is String)
-		{
-			var importer:ITextImporter = TextConverter.getImporter(TextConverter.PLAIN_TEXT_FORMAT);
-			importer.useClipboardAnnotations = this.useClipboardAnnotations;
-			importer.configuration = _config;
-			return importer.importToFlow(source);
-		}
-		return null;
-	}
-	
-	public function get configuration():IConfiguration
-	{
-		return _config;
-	}
-	
-	public function set configuration(value:IConfiguration):void
-	{
-		_config = value;
-	}
+    protected var _config:IConfiguration = null;
+
+    /** Constructor */
+    public function PlainTextImporter()
+    {
+        super();
+    }
+
+    public function importToFlow(source:Object):TextFlow
+    {
+        if (source is String)
+        {
+            var importer:ITextImporter = TextConverter.getImporter(TextConverter.PLAIN_TEXT_FORMAT);
+            importer.useClipboardAnnotations = this.useClipboardAnnotations;
+            importer.configuration = _config;
+            return importer.importToFlow(source);
+        }
+        return null;
+    }
+
+    public function get configuration():IConfiguration
+    {
+        return _config;
+    }
+
+    public function set configuration(value:IConfiguration):void
+    {
+        _config = value;
+    }
 }
 
 class TLFImporter extends ConverterBase implements ITextImporter
 {
-	protected var _config:IConfiguration = null;
-	
-	/** Constructor */
-	public function TLFImporter()	
-	{
-		super();
-	}
-	
-	public function importToFlow(source:Object):TextFlow
-	{
-		if (source is String)
-		{
-			var importer:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_LAYOUT_FORMAT);
-			importer.useClipboardAnnotations = this.useClipboardAnnotations;
-			importer.configuration = _config;
-			return importer.importToFlow(source);
-		}
-		return null;
-	}
-	
-	public function get configuration():IConfiguration
-	{
-		return _config;
-	}
-	
-	public function set configuration(value:IConfiguration):void
-	{
-		_config = value;
-	}
+    protected var _config:IConfiguration = null;
+
+    /** Constructor */
+    public function TLFImporter()
+    {
+        super();
+    }
+
+    public function importToFlow(source:Object):TextFlow
+    {
+        if (source is String)
+        {
+            var importer:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_LAYOUT_FORMAT);
+            importer.useClipboardAnnotations = this.useClipboardAnnotations;
+            importer.configuration = _config;
+            return importer.importToFlow(source);
+        }
+        return null;
+    }
+
+    public function get configuration():IConfiguration
+    {
+        return _config;
+    }
+
+    public function set configuration(value:IConfiguration):void
+    {
+        _config = value;
+    }
 }
