////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package flashx.textLayout.conversion 
{
	import flash.system.System;
	import flash.text.engine.Kerning;
	import flash.utils.Dictionary;
	
	import flashx.textLayout.debug.assert;
	import flashx.textLayout.elements.BreakElement;
	import flashx.textLayout.elements.Configuration;
	import flashx.textLayout.elements.DivElement;
	import flashx.textLayout.elements.FlowElement;
	import flashx.textLayout.elements.FlowGroupElement;
	import flashx.textLayout.elements.FlowLeafElement;
	import flashx.textLayout.elements.GlobalSettings;
	import flashx.textLayout.elements.IConfiguration;
	import flashx.textLayout.elements.InlineGraphicElement;
	import flashx.textLayout.elements.LinkElement;
	import flashx.textLayout.elements.ListElement;
	import flashx.textLayout.elements.ListItemElement;
	import flashx.textLayout.elements.ParagraphElement;
	import flashx.textLayout.elements.SpanElement;
	import flashx.textLayout.elements.SubParagraphGroupElement;
	import flashx.textLayout.elements.SubParagraphGroupElementBase;
	import flashx.textLayout.elements.TabElement;
	import flashx.textLayout.elements.TextFlow;
	import flashx.textLayout.formats.Float;
	import flashx.textLayout.formats.ITextLayoutFormat;
	import flashx.textLayout.formats.LeadingModel;
	import flashx.textLayout.formats.ListMarkerFormat;
	import flashx.textLayout.formats.ListStyleType;
	import flashx.textLayout.formats.TextLayoutFormat;
	import flashx.textLayout.property.Property;
	import flashx.textLayout.tlf_internal;

	use namespace tlf_internal;
	
	[ExcludeClass]
	/** 
	 * @private
	 * TextFieldHtmlImporter converts from HTML to TextLayout data structures
	 */ 	
	public class TextFieldHtmlImporter extends BaseTextLayoutImporter implements IHTMLImporter
	{	
		// TLF formats to which <font/> attributes map directly
		/** @private */
		static tlf_internal const _fontDescription:Object = {
			color:TextLayoutFormat.colorProperty,
			trackingRight:TextLayoutFormat.trackingRightProperty,
			fontFamily:TextLayoutFormat.fontFamilyProperty
		};
		
		// <font/> attributes that require custom logic for mapping to TLF formats
		/** @private */
		static tlf_internal const _fontMiscDescription:Object = {
			size	: Property.NewStringProperty("size", null, false, null),
			kerning	: Property.NewStringProperty("kerning", null, false, null)
		};
				
		// TLF formats to which <textformat/> attributes map directly		
		/** @private */
		static tlf_internal const _textFormatDescription:Object = {
			paragraphStartIndent:TextLayoutFormat.paragraphStartIndentProperty,
			paragraphEndIndent:TextLayoutFormat.paragraphEndIndentProperty,
			textIndent:TextLayoutFormat.textIndentProperty,
			lineHeight:TextLayoutFormat.lineHeightProperty,
			tabStops:TextLayoutFormat.tabStopsProperty
		};	
		
		// <textformat/> attributes that require custom logic for mapping to TLF formats
		/** @private */
		static tlf_internal const _textFormatMiscDescription:Object = {
			blockIndent	: Property.NewStringProperty("blockIndent", null, false, null)
		};
		
		/** @private */
		static tlf_internal const _paragraphFormatDescription:Object = {
			textAlign:TextLayoutFormat.textAlignProperty
		};
		
		/** @private */
		static tlf_internal const _linkHrefDescription:Object = {
			href	: Property.NewStringProperty("href",   null, false, null)
		};
		
		/** @private */
		static tlf_internal const _linkTargetDescription:Object = {
			target	: Property.NewStringProperty("target", null, false, null)
		};
		
		/** @private */
		static tlf_internal const _imageDescription:Object = {
			height	: InlineGraphicElement.heightPropertyDefinition,
			width	: InlineGraphicElement.widthPropertyDefinition
		};
		
		// Separate description because id value is case-sensitive unlike others
		/** @private */
		static tlf_internal const _imageMiscDescription:Object = {
			src		: Property.NewStringProperty("src", null, false, null),
			align	: Property.NewStringProperty("align", null, false, null)
		};
			
		/** @private Finish defining at run time because it has a member variable "CLASS" which is a reserved keyword. */
		static tlf_internal const _classAndIdDescription:Object = { 
			id		: Property.NewStringProperty("ID", null, false, null)
		};
		
		// For some reason, the following can't be initialized here
		/** @private */
		static tlf_internal var _fontImporter:FontImporter;
		/** @private */
		static tlf_internal var _fontMiscImporter:CaseInsensitiveTLFFormatImporter;
		/** @private */
		static tlf_internal var _textFormatImporter:TextFormatImporter;
		/** @private */
		static tlf_internal var _textFormatMiscImporter:CaseInsensitiveTLFFormatImporter;		
		/** @private */
		static tlf_internal var _paragraphFormatImporter:HtmlCustomParaFormatImporter;
		/** @private */
		static tlf_internal var _linkHrefImporter:CaseInsensitiveTLFFormatImporter;
		/** @private */
		static tlf_internal var _linkTargetImporter:CaseInsensitiveTLFFormatImporter;
		/** @private */
		static tlf_internal var _ilgFormatImporter:CaseInsensitiveTLFFormatImporter;
		/** @private */
		static tlf_internal var _ilgMiscFormatImporter:CaseInsensitiveTLFFormatImporter;
		/** @private */
		static tlf_internal var _classAndIdImporter:CaseInsensitiveTLFFormatImporter;
		
		// Formats specified by formatting elements in the ancestry of the element being parsed currently 
		/** @private */
		static tlf_internal var _activeFormat:TextLayoutFormat = new TextLayoutFormat(); // to be applied to all flow elements
		/** @private */
		static tlf_internal var _activeParaFormat:TextLayoutFormat = new TextLayoutFormat(); // to be applied to paras only
		/** @private */
		static tlf_internal var _activeImpliedParaFormat:TextLayoutFormat = null;
		
		// The basis for relative font size calculation
		/** @private */
		tlf_internal var _baseFontSize:Number; 
		
		/** @private */
		tlf_internal static var _htmlImporterConfig:ImportExportConfiguration;
		
		private var _imageSourceResolveFunction:Function;
		private var _preserveBodyElement:Boolean = false;
		private var _importHtmlElement:Boolean = false;
		
		/** Constructor */
		public function TextFieldHtmlImporter()
		{
			createConfig();
			super(null, _htmlImporterConfig);
		}
		
		/** @private */
		tlf_internal static function createConfig():void
		{
			if (!_htmlImporterConfig)
			{
				_htmlImporterConfig = new ImportExportConfiguration();
				
				_htmlImporterConfig.addIEInfo("BR", BreakElement, BaseTextLayoutImporter.parseBreak, null); 
				_htmlImporterConfig.addIEInfo("P", ParagraphElement, TextFieldHtmlImporter.parsePara, null);
				_htmlImporterConfig.addIEInfo("SPAN", SpanElement, TextFieldHtmlImporter.parseSpan, null);
				_htmlImporterConfig.addIEInfo("A", LinkElement, TextFieldHtmlImporter.parseLink, null);
				_htmlImporterConfig.addIEInfo("IMG", InlineGraphicElement, TextFieldHtmlImporter.parseInlineGraphic, null);
				_htmlImporterConfig.addIEInfo("DIV", DivElement, TextFieldHtmlImporter.parseDiv, null);
				_htmlImporterConfig.addIEInfo("HTML", null, TextFieldHtmlImporter.parseHtmlElement, null);
				_htmlImporterConfig.addIEInfo("BODY", null, TextFieldHtmlImporter.parseBody, null);
			
				// formatting elements
				_htmlImporterConfig.addIEInfo("FONT", null, TextFieldHtmlImporter.parseFont, null);
				_htmlImporterConfig.addIEInfo("TEXTFORMAT", null, TextFieldHtmlImporter.parseTextFormat, null);
				_htmlImporterConfig.addIEInfo("U", null, TextFieldHtmlImporter.parseUnderline, null);
				_htmlImporterConfig.addIEInfo("I", null, TextFieldHtmlImporter.parseItalic, null);
				_htmlImporterConfig.addIEInfo("B", null, TextFieldHtmlImporter.parseBold, null);
				_htmlImporterConfig.addIEInfo("S", null, TextFieldHtmlImporter.parseStrikeThrough, null);
				
				// list stuff
				_htmlImporterConfig.addIEInfo("UL", null, BaseTextLayoutImporter.parseList, null);
				_htmlImporterConfig.addIEInfo("OL", null, BaseTextLayoutImporter.parseList, null);
				_htmlImporterConfig.addIEInfo("LI", null, TextFieldHtmlImporter.parseListItem, null);
				
			}
			
			// create these here - can't be done above
			if (_classAndIdDescription["CLASS"] === undefined)
			{
				_classAndIdDescription["CLASS"] = Property.NewStringProperty("CLASS", null, false, null);
				_paragraphFormatImporter = new HtmlCustomParaFormatImporter(TextLayoutFormat, _paragraphFormatDescription);
				_textFormatImporter = new TextFormatImporter(TextLayoutFormat, _textFormatDescription);
				_fontImporter = new FontImporter(TextLayoutFormat, _fontDescription);
				_fontMiscImporter = new CaseInsensitiveTLFFormatImporter(Dictionary, _fontMiscDescription);		
				_textFormatMiscImporter = new CaseInsensitiveTLFFormatImporter(Dictionary, _textFormatMiscDescription);
				_linkHrefImporter = new CaseInsensitiveTLFFormatImporter(Dictionary,_linkHrefDescription,false);
				_linkTargetImporter = new CaseInsensitiveTLFFormatImporter(Dictionary,_linkTargetDescription);
				_ilgFormatImporter = new CaseInsensitiveTLFFormatImporter(Dictionary,_imageDescription);
				_ilgMiscFormatImporter = new CaseInsensitiveTLFFormatImporter(Dictionary,_imageMiscDescription, false);
				_classAndIdImporter = new CaseInsensitiveTLFFormatImporter(Dictionary,_classAndIdDescription);
			}
		}
		
		/** @copy IHTMLExporter#imageSourceResolveFunction
		 * 
		 * @playerversion Flash 10.0
		 * @playerversion AIR 2.0
		 * @langversion 3.0
		 */
		public function get imageSourceResolveFunction():Function
		{ return _imageSourceResolveFunction; }
		public function set imageSourceResolveFunction(resolver:Function):void
		{ _imageSourceResolveFunction = resolver; }
		
		
		/** @copy IHTMLExporter#preserveBodyElement
		 * 
		 * @playerversion Flash 10.0
		 * @playerversion AIR 2.0
		 * @langversion 3.0
		 */		
		public function get preserveBodyElement():Boolean
		{ return _preserveBodyElement; }
		public function set preserveBodyElement(value:Boolean):void
		{ _preserveBodyElement = value; }
		
		/** @copy IHTMLExporter#preserveHTMLElement
		 *
		 * @playerversion Flash 10.0
		 * @playerversion AIR 2.0
		 * @langversion 3.0
		 */		
		public function get preserveHTMLElement():Boolean
		{ return _importHtmlElement; }
		public function set preserveHTMLElement(value:Boolean):void
		{ _importHtmlElement = value; }

		/** Parse and convert input data
		 * 
		 * @param source - the HTML string
		 */
		protected override function importFromString(source:String):TextFlow
		{	
			var textFlow:TextFlow;
			
			// Use toXML rather than the XML constructor because the latter expects
			// well-formed XML, which source may not be 
			var xml:XML = toXML(source);
			if (xml)
			{
				textFlow = importFromXML(xml);
				if (Configuration.playerEnablesArgoFeatures)
					System["disposeXML"](xml);
				
			}
			return textFlow;
		}

		/** Parse and convert input XML data
		 */
		protected override function importFromXML(xmlSource:XML):TextFlow
		{
			var textFlow:TextFlow = new TextFlow(_textFlowConfiguration);
			// always set html typeName - the convertfromstring to xml code wraps the content in an HTML element.  this makes it all match
			if (this.preserveHTMLElement)
				textFlow.typeName = "html";
			
			// Use font size specified in _textFlowConfiguration.textFlowInitialFormat as the base font size
			// If not specified, use 12
			_baseFontSize = textFlow.fontSize === undefined ? 12 : textFlow.fontSize;
			
			// Unlike other markup formats, the HTML format for TLF does not have a fixed root XML element.
			// <html> and <body> are optional, and flow elements may or may not be encapsulated in formatting 
			// elements like <i> or <textformat>. Use parseObject to handle any (expected) root element.
			CONFIG::debug { assert(xmlSource.name() != null, "Bad XML source"); }
			parseObject(xmlSource.name().localName, xmlSource, textFlow);
			
			// If the last para is implied, there is nothing following it that'll trigger a reset. 
			// For most importers, this is fine (clear will eventually reset it), but the HTML importer has 
			// some special behavior associated with the reset (replacing BreakElements with para splits).
			// Explicitly do so now (must happen before normalization)
			resetImpliedPara();
			
			CONFIG::debug { textFlow.debugCheckNormalizeAll() ; }
			textFlow.normalize();
			textFlow.applyWhiteSpaceCollapse(null);
			
			return textFlow;
		}		

		/** @copy ConverterBase#clear()
		 * @private
		 */
		tlf_internal override function clear():void
		{
			// Reset active formats and base font size
			_activeParaFormat.clearStyles();
			_activeFormat.clearStyles();
			super.clear();
		}
		
		/** @private */
		tlf_internal override function createImpliedParagraph():ParagraphElement
		{
			var rslt:ParagraphElement;
			var savedActiveFormat:TextLayoutFormat = _activeFormat;
			if (_activeImpliedParaFormat)
				_activeFormat = _activeImpliedParaFormat;
			try
			{
				rslt = super.createImpliedParagraph();
			}
			finally
			{
				_activeFormat = savedActiveFormat;
			}
			return rslt;
		}

		/** @private */
		public override function createParagraphFromXML(xmlToParse:XML):ParagraphElement
		{
			var paraElem:ParagraphElement = new ParagraphElement();
				
			// Parse xml attributes for paragraph format
			var formatImporters:Array = [_paragraphFormatImporter, _classAndIdImporter];
			parseAttributes(xmlToParse, formatImporters);
			var paragraphFormat:TextLayoutFormat = new TextLayoutFormat(_paragraphFormatImporter.result as ITextLayoutFormat);
			
			// Apply paragraph format inherited from formatting elements
			if (_activeParaFormat)
				paragraphFormat.apply(_activeParaFormat);
			if (_activeFormat)
				paragraphFormat.apply(_activeFormat);
			
			// A <FONT/> that is the only child of a <P/> specifies formats that apply to the paragraph itself
			// Otherwise (i.e., if it has siblings), the formats apply to the elements nested within the <FONT/>
			// Check for the former case here
			var fontFormattingElement:XML = getSingleFontChild (xmlToParse);
			if (fontFormattingElement)
				paragraphFormat.apply(parseFontAttributes(fontFormattingElement));
				
			if (paragraphFormat.lineHeight !== undefined)
				paragraphFormat.leadingModel = LeadingModel.APPROXIMATE_TEXT_FIELD;
			
			paraElem.format = paragraphFormat;
			
			// Use the value of the 'class' attribute (if present) as styleName
			paraElem.styleName =  _classAndIdImporter.getFormatValue("CLASS"); 
			paraElem.id =  _classAndIdImporter.getFormatValue("ID"); 
					
			return paraElem;
		}
		
		/** @private */
		static public function parseListItem(importer:TextFieldHtmlImporter, xmlToParse:XML, parent:FlowGroupElement):void
		{
			if (!(parent is ListElement))
			{
				var list:ListElement = importer.createListFromXML(null);
				importer.addChild(parent,list);
				CONFIG::debug { assert(list.parent == parent,"TextFieldHtmlImporter.parseListeItem: Bad call to addChild"); }
				parent = list;
			}
			
			var listItem:ListItemElement = importer.createListItemFromXML(xmlToParse);
			if (importer.addChild(parent, listItem))
			{
				importer.parseFlowGroupElementChildren(xmlToParse, listItem);
				//if parsing an empty list item, create a Paragraph for it.
				if (listItem.numChildren == 0)
					listItem.addChild(new ParagraphElement());	
			}
		}
		
		/** @private */
		public override function createListFromXML(xmlToParse:XML):ListElement	// No PMD
		{
			parseAttributes(xmlToParse, [ _classAndIdImporter ]);
			
			// try and make lists look something like TextField but with a bit more - do ordered lists as well not just bullets
			// textField indents lists on the left by 36 pixels.
			
			var list:ListElement = new ListElement();
			list.paddingLeft = 36;
			var name:String = xmlToParse ? xmlToParse.name().localName : null;
			list.listStyleType = name == "OL" ? ListStyleType.DECIMAL : ListStyleType.DISC;
			
			// TextField does equivalent of a 18 pixel start indent but that doesnt look nice with numbered lists.  
			// default bullet is around 4 pixels. so place the marker 14 pixels from the right side
			var lmf:ListMarkerFormat = new ListMarkerFormat();
			lmf.paragraphEndIndent = 14;
			list.listMarkerFormat = lmf;

			list.styleName =  _classAndIdImporter.getFormatValue("CLASS"); 
			list.id =  _classAndIdImporter.getFormatValue("ID"); 		

			return list;
		}
		
		/** @private */
		public override function createListItemFromXML(xmlToParse:XML):ListItemElement	// No PMD
		{
			parseAttributes(xmlToParse, [ _classAndIdImporter ]);

			var listItem:ListItemElement = new ListItemElement();
			listItem.styleName =  _classAndIdImporter.getFormatValue("CLASS"); 
			listItem.id =  _classAndIdImporter.getFormatValue("ID"); 		
			
			return listItem;
		}
		
		/** Parse the supplied XML into a paragraph. Parse the <p/> element and its children.
		 * @private
		 * @param importer	parser object
		 * @param xmlToParse	content to parse
		 * @param parent 		the parent for the new content
		 */
		static public function parsePara(importer:TextFieldHtmlImporter, xmlToParse:XML, parent:FlowGroupElement):void
		{
			var paraElem:ParagraphElement = importer.createParagraphFromXML(xmlToParse);
			
			if (importer.addChild(parent, paraElem))
			{
				// Parse children, but if there is only one child, a <FONT/>, skip to *its* children.
				// That's because the single <FONT/> chuld has already been parsed in createParagraphFromXML.
				var fontFormattingElement:XML = getSingleFontChild (xmlToParse);
				parseChildrenUnderNewActiveFormat (importer, fontFormattingElement ? fontFormattingElement : xmlToParse, paraElem, _activeFormat, null);
				
				//if parsing an empty paragraph, create a Span for it.
				if (paraElem.numChildren == 0)
					paraElem.addChild(importer.createImpliedSpan(""));
			}
			
			// Replace break elements with paragraph splits
			// This must happen before normalization else BreakElements may merge or become spans
			replaceBreakElementsWithParaSplits(paraElem);
		}
		
		/** Parse the supplied XML into a DivElement. Parse the <p/> element and its children.
		 * @private
		 * @param importer	parser object
		 * @param xmlToParse	content to parse
		 * @param parent 		the parent for the new content
		 */
		static public function parseDiv(importer:TextFieldHtmlImporter, xmlToParse:XML, parent:FlowGroupElement):void
		{
			var elem:FlowGroupElement;
			if (parent.canOwnFlowElement(new DivElement()))
				elem = importer.createDivFromXML(xmlToParse);
			else
			{
				elem = importer.createSPGEFromXML(xmlToParse);
				elem.typeName = "div";
			}
			
			importer.addChild(parent,elem);
			importer.parseFlowGroupElementChildren(xmlToParse,elem);
		}
		
		static public function parseHtmlElement(importer:TextFieldHtmlImporter, xmlToParse:XML, parent:FlowGroupElement):void
		{
			// skip the element and descent to the children
			if (importer.preserveHTMLElement)
			{
				if (!(parent is TextFlow))
				{
					var newParent:FlowGroupElement = ((parent is ParagraphElement) || (parent is SubParagraphGroupElementBase)) ? new SubParagraphGroupElement() : new DivElement;
					parent.addChild(newParent);
					parent = newParent;
				}
				importer.parseAttributes(xmlToParse, [ _classAndIdImporter ]);
				parent.typeName = "html";
				parent.styleName =  _classAndIdImporter.getFormatValue("CLASS"); 
				parent.id =  _classAndIdImporter.getFormatValue("ID"); 		
			}
			importer.parseFlowGroupElementChildren(xmlToParse, parent, null, true);
		}
		
		static public function parseBody(importer:TextFieldHtmlImporter, xmlToParse:XML, parent:FlowGroupElement):void
		{
			// skip the element and descent to the children
			if (importer.preserveBodyElement)
			{
				var newParent:FlowGroupElement = ((parent is ParagraphElement) || (parent is SubParagraphGroupElementBase)) ? new SubParagraphGroupElement() : new DivElement;
				parent.addChild(newParent);
				parent = newParent;
				
				importer.parseAttributes(xmlToParse, [ _classAndIdImporter ]);
				parent.typeName = "body";
				parent.styleName =  _classAndIdImporter.getFormatValue("CLASS"); 
				parent.id =  _classAndIdImporter.getFormatValue("ID"); 		
			}
			importer.parseFlowGroupElementChildren(xmlToParse, parent, null, true);
		}

		
		public function createDivFromXML(xmlToParse:XML):DivElement
		{
			parseAttributes(xmlToParse, [ _classAndIdImporter ]);
			
			var divElement:DivElement = new DivElement();
			divElement.styleName =  _classAndIdImporter.getFormatValue("CLASS"); 
			divElement.id =  _classAndIdImporter.getFormatValue("ID"); 		
			
			return divElement;
		}
		
		public function createSPGEFromXML(xmlToParse:XML):SubParagraphGroupElement
		{
			parseAttributes(xmlToParse, [ _classAndIdImporter ]);
			
			var spge:SubParagraphGroupElement = new SubParagraphGroupElement();
			spge.styleName =  _classAndIdImporter.getFormatValue("CLASS"); 
			spge.id =  _classAndIdImporter.getFormatValue("ID"); 		
			
			return spge;
		}
		
		/** @private */
		protected override function onResetImpliedPara(para:ParagraphElement):void
		{
			// Replacing break elements with paragraph splits, even for implied paras
			replaceBreakElementsWithParaSplits (para);
		}
		
		/** If the provided xml has a single child <FONT.../>, get it
		 * @private
		 */
		static private function getSingleFontChild (xmlToParse:XML):XML
		{
			var children:XMLList = xmlToParse.children();
			if (children.length() == 1)
			{
				var child:XML = children[0];
				if (child.name() && child.name().localName.toUpperCase() == "FONT")
					return child;
			}
			
			return null;
		}
			
		private function createLinkFromXML(xmlToParse:XML):LinkElement
		{
			var linkElem:LinkElement = new LinkElement();

			var formatImporters:Array = [ _linkHrefImporter, _linkTargetImporter, _classAndIdImporter ];
			parseAttributes(xmlToParse, formatImporters);
			
			linkElem.href = _linkHrefImporter.getFormatValue("HREF");
			linkElem.target = _linkTargetImporter.getFormatValue("TARGET");
			
			// Handle difference in defaults between TextField and TLF 
			// target "_self" vs. null (equivalent to "_blank")
			if (!linkElem.target)
				linkElem.target = "_self";
				
			//  Apply active format
			linkElem.format = _activeFormat;
			
			linkElem.styleName =  _classAndIdImporter.getFormatValue("CLASS"); 
			linkElem.id =  _classAndIdImporter.getFormatValue("ID"); 

			return linkElem;
		}
		
		/** Parse the supplied XML into a LinkElement. Parse the <a/> element and its children.
		 * @private
		 * @param importer	parser object
		 * @param xmlToParse	content to parse
		 * @param parent 		the parent for the new content
		 */
		static public function parseLink(importer:TextFieldHtmlImporter, xmlToParse:XML, parent:FlowGroupElement):void
		{
			var linkElem:LinkElement = importer.createLinkFromXML(xmlToParse);
			
			if (importer.addChild(parent, linkElem))
			{
				parseChildrenUnderNewActiveFormat (importer, xmlToParse, linkElem, _activeFormat, null);
			}
		}	
		
		/** @private returns a string if its a simple span otherwise null */
		tlf_internal static function extractSimpleSpanText(xmlToParse:XML):String
		{
			var elemList:XMLList = xmlToParse[0].children();
			if (elemList.length() == 0)
				return "";
			if (elemList.length() != 1)
				return null;
			// sniff the first child and test if its a textelement
			for each (var child:XML in elemList)
				break;
			var elemName:String = child.name() ? child.name().localName : null;
			if (elemName != null)
				return null;
			
			var rslt:String = child.toString();
			return rslt ? rslt : "";
		}
		
		/** Static method for constructing a span from XML. Parse the <span> ... </span> tag. 
		 * Insert the new content into its parent
		 * Note: Differs from BaseTextLayoutImporter.parseSpan in that it allows nested <span/> elements. 
		 * @private
		 * @param importer	parser object
		 * @param xmlToParse	content to parse
		 * @param parent 		the parent for the new content
		 */
		static public function parseSpan(importer:TextFieldHtmlImporter, xmlToParse:XML, parent:FlowGroupElement):void
		{
			// Use the value of the 'class' attribute (if present) as styleName
			importer.parseAttributes(xmlToParse,[_classAndIdImporter]);
			
			// if either class or id is set and its not a "simple" span then we need to create an SPGE and descend
			var classFormatValue:* = _classAndIdImporter.getFormatValue("CLASS");
			var idFormatValue:* = _classAndIdImporter.getFormatValue("ID");
			
			var simpleSpanText:String = extractSimpleSpanText(xmlToParse);
			
			if (simpleSpanText == null)
			{
				// if its an interesting span make an SPGE otherwise just parse the children
				if (classFormatValue !== undefined || idFormatValue !== undefined || !TextLayoutFormat.isEqual(_activeFormat,TextLayoutFormat.emptyTextLayoutFormat))
				{
					var spge:SubParagraphGroupElement = new SubParagraphGroupElement();
					spge.format = _activeFormat;
					spge.styleName = classFormatValue;
					spge.id = idFormatValue;
					spge.typeName = "span";
					importer.addChild(parent,spge);
					parent = spge;
				}
				parseChildrenUnderNewActiveFormat (importer, xmlToParse, parent, _activeFormat, null);
				return;
			}
			
			var span:SpanElement = new SpanElement();
			span.format = _activeFormat;
			span.styleName =  classFormatValue; 
			span.id =  idFormatValue; 
			span.text = simpleSpanText;

			importer.addChild(parent, span);
		} 
		
		/** create an implied span with specified text */
		public override function createImpliedSpan(text:String):SpanElement
		{
			var span:SpanElement = super.createImpliedSpan(text);
			span.format = _activeFormat;
			return span;
		}
	
		/** @private */
		protected function createInlineGraphicFromXML(xmlToParse:XML):InlineGraphicElement
		{				
			var imgElem:InlineGraphicElement = new InlineGraphicElement();

			var formatImporters:Array = [_ilgFormatImporter, _ilgMiscFormatImporter, _classAndIdImporter];	
			parseAttributes(xmlToParse,formatImporters);
			
			var source:String = _ilgMiscFormatImporter.getFormatValue("SRC");
			imgElem.source = _imageSourceResolveFunction != null ? _imageSourceResolveFunction(source) : source;
				
			// if not defined then let InlineGraphic set its own default
			imgElem.height = InlineGraphicElement.heightPropertyDefinition.setHelper(imgElem.height,_ilgFormatImporter.getFormatValue("HEIGHT"));
			imgElem.width  = InlineGraphicElement.heightPropertyDefinition.setHelper(imgElem.width,_ilgFormatImporter.getFormatValue("WIDTH"));
				
			var floatVal:String = _ilgMiscFormatImporter.getFormatValue("ALIGN");
			// Handle difference in defaults between TextField and TLF 
			// float "left" vs. "none"
			if (floatVal == Float.LEFT || floatVal == Float.RIGHT)
				imgElem.float = floatVal;
			
			//  Apply active format
			imgElem.format = _activeFormat;
			imgElem.id = _classAndIdImporter.getFormatValue("ID");
			imgElem.styleName = _classAndIdImporter.getFormatValue("CLASS");
			
			return imgElem;
		}

		/** Parse the supplied XML into an InlineGraphicElement. Parse the <img/> element.
		 * @private
		 * @param importer	parser object
		 * @param xmlToParse	content to parse
		 * @param parent 		the parent for the new content
		 */
		static public function parseInlineGraphic(importer:TextFieldHtmlImporter, xmlToParse:XML, parent:FlowGroupElement):void
		{
			var ilg:InlineGraphicElement = importer.createInlineGraphicFromXML(xmlToParse);
			importer.addChild(parent, ilg);
		}
		
		/** @private */
		public override function createTabFromXML(xmlToParse:XML):TabElement
		{
			return null; // no tabs in HTML
		}
			
		/** Parse the attributes of the <Font/> formatting element and returns the corresponding TLF format
		 * @private
		 */
		protected function parseFontAttributes(xmlToParse:XML):ITextLayoutFormat
		{
			var formatImporters:Array = [_fontImporter, _fontMiscImporter];
			parseAttributes(xmlToParse, formatImporters);
			
			var newFormat:TextLayoutFormat = new TextLayoutFormat(_fontImporter.result as ITextLayoutFormat);
			
			var kerning:String = _fontMiscImporter.getFormatValue("KERNING");
			if (kerning)
			{
				var kerningVal:Number = Number(kerning);
				newFormat.kerning = kerningVal == 0 ? Kerning.OFF : Kerning.AUTO;
			}
			
			var size:String = _fontMiscImporter.getFormatValue("SIZE");
			if (size)
			{
				var sizeVal:Number = TextLayoutFormat.fontSizeProperty.setHelper(NaN, size);
				if (!isNaN(sizeVal))
				{
					if (size.search(/\s*(-|\+)/) != -1) // leading whitespace followed by + or -
						sizeVal += _baseFontSize;		// implies relative font sizes
					newFormat.fontSize = sizeVal;
				}
			}
			
			return newFormat;
		}
		
		/** Parse the <Font/> formatting element
		 * Calculates the new format to apply to _activeFormat and continues parsing down the hierarchy
		 * @private
		 */
		static public function parseFont(importer:TextFieldHtmlImporter, xmlToParse:XML, parent:FlowGroupElement):void
		{
			var newFormat:ITextLayoutFormat = importer.parseFontAttributes (xmlToParse);
			parseChildrenUnderNewActiveFormatWithImpliedParaFormat(importer, xmlToParse, parent, newFormat);
		}
		
		/** Parse the <TextFormat> formatting element
		 * Calculates the new format to apply to _activeParaFormat and continues parsing down the hierarchy
		 * @private
		 */
		static public function parseTextFormat(importer:TextFieldHtmlImporter, xmlToParse:XML, parent:FlowGroupElement):void
		{	
			var formatImporters:Array = [_textFormatImporter, _textFormatMiscImporter];
			importer.parseAttributes(xmlToParse, formatImporters);
			
			var newFormat:TextLayoutFormat = new TextLayoutFormat(_textFormatImporter.result as ITextLayoutFormat);
			
			var blockIndent:* = _textFormatMiscImporter.getFormatValue("BLOCKINDENT");
			if (blockIndent !== undefined)
			{
				// TODO: Nested <TextFormat/>?
				blockIndent = TextLayoutFormat.paragraphStartIndentProperty.setHelper(undefined, blockIndent);
				if (blockIndent !== undefined)
				{
					var blockIndentVal:Number = Number(blockIndent);
					newFormat.paragraphStartIndent = newFormat.paragraphStartIndent === undefined ? blockIndentVal : newFormat.paragraphStartIndent + blockIndentVal;
				}
			}
			
			// lineHeight is the only textformat property that must be copied down into subparagraph elements
			var saveLineHeight:* = _activeFormat.lineHeight;
			if (parent is ParagraphElement)
			{
				if (parent.numChildren == 0)
				{
					// if <textFormat> is the first child then promote all the settings to the Paragraph
					var format:TextLayoutFormat = new TextLayoutFormat(parent.format);
					format.apply(newFormat);
					// same as createParagraphFromXML
					if (format.lineHeight !== undefined)
						format.leadingModel = LeadingModel.APPROXIMATE_TEXT_FIELD;
					parent.format = format;
					newFormat.clearStyles();
				}
				else if (newFormat.lineHeight !== undefined)
					_activeFormat.lineHeight = newFormat.lineHeight;
			}

			parseChildrenUnderNewActiveFormat (importer, xmlToParse, parent, _activeParaFormat, newFormat, true);
			
			_activeFormat.lineHeight = saveLineHeight;
		}
		
		/** Parse the <b> formatting element
		 * Calculates the new format to apply to _activeFormat and continues parsing down the hierarchy
		 * @private
		 */
		static public function parseBold(importer:TextFieldHtmlImporter, xmlToParse:XML, parent:FlowGroupElement):void
		{	
			var newFormat:TextLayoutFormat = new TextLayoutFormat();
			newFormat.fontWeight = flash.text.engine.FontWeight.BOLD;
			
			parseChildrenUnderNewActiveFormatWithImpliedParaFormat (importer, xmlToParse, parent, newFormat);
		}
		
		/** Parse the <i> formatting element
		 * Calculates the new format to apply to _activeFormat and continues parsing down the hierarchy
		 * @private
		 */
		static public function parseItalic(importer:TextFieldHtmlImporter, xmlToParse:XML, parent:FlowGroupElement):void
		{	
			var newFormat:TextLayoutFormat = new TextLayoutFormat();
			newFormat.fontStyle = flash.text.engine.FontPosture.ITALIC;
			parseChildrenUnderNewActiveFormatWithImpliedParaFormat (importer, xmlToParse, parent, newFormat);
		}
		
		/** Parse the <b> formatting element
		 * Calculates the new format to apply to _activeFormat and continues parsing down the hierarchy
		 * @private
		 */
		static public function parseStrikeThrough(importer:TextFieldHtmlImporter, xmlToParse:XML, parent:FlowGroupElement):void
		{	
			var newFormat:TextLayoutFormat = new TextLayoutFormat();
			newFormat.lineThrough = true;
			parseChildrenUnderNewActiveFormatWithImpliedParaFormat (importer, xmlToParse, parent, newFormat);
		}
		
		/** Parse the <u> formatting element
		 * Calculates the new format to apply to _activeFormat and continues parsing down the hierarchy
		 * @private
		 */
		static public function parseUnderline(importer:TextFieldHtmlImporter, xmlToParse:XML, parent:FlowGroupElement):void
		{	
			var newFormat:TextLayoutFormat = new TextLayoutFormat();
			newFormat.textDecoration = flashx.textLayout.formats.TextDecoration.UNDERLINE;
			parseChildrenUnderNewActiveFormatWithImpliedParaFormat(importer, xmlToParse, parent, newFormat);

		}
		
		/** @private */
		static protected function parseChildrenUnderNewActiveFormatWithImpliedParaFormat(importer:TextFieldHtmlImporter, xmlToParse:XML, parent:FlowGroupElement, newFormat:ITextLayoutFormat):void
		{
			var oldActiveImpliedParaFormat:TextLayoutFormat = _activeImpliedParaFormat;
			if (_activeImpliedParaFormat == null)
				_activeImpliedParaFormat = new TextLayoutFormat(_activeFormat);
			try
			{
				parseChildrenUnderNewActiveFormat(importer, xmlToParse, parent, _activeFormat, newFormat, true);
			}
			finally
			{
				_activeImpliedParaFormat = oldActiveImpliedParaFormat;
			}
		}
		
		/** Updates the current active format and base font size as specified, parses children, and restores the active format and base font size
		 * There are two different use cases for this method:
		 * - Parsing children of a formatting XML element like <Font/> or <TextFormat/>. In this case, the TLF format corresponding to the formatting element
		 * (newFormat) is applied to the currently active format (_activeFormat in the case of <Font/> and _activeParaFormat in the case of <TextFormat/>). 
		 * Children of the formatting element are parsed under this new active format.
		 * - Parsing children of a flow XML element like <P/> or <A/>. In this case, newFormat is null and the currently active format (_activeFormat) is reset.
		 * Children of the flow element are parsed under this newly reset format. This is to avoid redundancy (the format is already applied to the flow element). 
		 * 
		 * @param importer	parser object
		 * @param xmlToParse	content to parse
		 * @param parent 		the parent for the parsed children
		 * @param currFormat	the active format (_activeFormat or _activeParaFormat)
		 * @param newFormat		the format to apply to currFormat while the children are being parsed. If null, currFormat is to be reset.
		 * @param chainedParent whether parent actually corresponds to xmlToParse or has been chained (such as when xmlToParse is a formatting element). See BaseTextLayoutImporter.parseFlowGroupElementChildren
		 * @private
		 */
		static protected function parseChildrenUnderNewActiveFormat (importer:TextFieldHtmlImporter, xmlToParse:XML, parent:FlowGroupElement, currFormat:TextLayoutFormat, newFormat:ITextLayoutFormat, chainedParent:Boolean=false):void
		{
			// Remember the current state
			var restoreBaseFontSize:Number = importer._baseFontSize;
			var restoreStyles:Object = Property.shallowCopy(currFormat.getStyles());
			
			if (newFormat)
			{
				// Update base font size based on the new format
				if (newFormat.fontSize !== undefined)
					importer._baseFontSize = newFormat.fontSize; 
					
				// Apply the new format
				currFormat.apply(newFormat);
			}
			else
			{
				// Base font size remains unchanged
				
				// Reset the new format
				currFormat.clearStyles();
			}
			
			try
			{
				var beforeCount:int = parent.numChildren;
				importer.parseFlowGroupElementChildren(xmlToParse, parent, null, chainedParent);
				// if nothing was added create something - otherwise this construct fails <p><b/></p>
				if (beforeCount == parent.numChildren)
				{
					var span:SpanElement = importer.createImpliedSpan("");
					importer.addChild(parent,span);
				}
			}
			finally
			{
				// Restore 
				currFormat.setStyles(restoreStyles,false);
				importer._baseFontSize = restoreBaseFontSize;
			}
		}
		
		/** @private */
		protected override function handleUnknownAttribute(elementName:String, propertyName:String):void
		{
			// A toss-up: report error or ignore? Ignore for now
			// If we do end up reporting error, we should add exceptions for documented attributes that we don't handle
			// like align on <img/>
		}
		
		/** @private */
		protected override function handleUnknownElement(name:String, xmlToParse:XML, parent:FlowGroupElement):void
		{
			var newParent:FlowGroupElement;	// scratch
			// Not an error (it may be a styling element like <h1/>); continue parsing children
			
			// a couple of cases
			// 1) must make a div/spge - if activeFormat or id or stylename is set OR parent is a ListElement (otherwise we wind up trying to put ListItems in a Div which is not supported)
			// 2) may make a div/spge - if more than one child is added to parent OR the added child has an id/stylename/typename
			// 3) otherwise just set the typeName of the single added child
			
			// Use the value of the 'class' attribute (if present) as styleName
			parseAttributes(xmlToParse,[_classAndIdImporter]);
			
			// if either class or id is set and its not a "simple" span then we need to create an SPGE and descend
			var classFormatValue:* = _classAndIdImporter.getFormatValue("CLASS");
			var idFormatValue:* = _classAndIdImporter.getFormatValue("ID");
			
			if (classFormatValue !== undefined || idFormatValue !== undefined || !TextLayoutFormat.isEqual(_activeFormat,TextLayoutFormat.emptyTextLayoutFormat) || (parent is ListElement))
			{
				newParent = ((parent is ParagraphElement) || (parent is SubParagraphGroupElementBase)) ? new SubParagraphGroupElement() : new DivElement;
				addChild(parent, newParent);
					
				newParent.format = _activeFormat;
				newParent.typeName = name.toLowerCase();
				newParent.styleName = classFormatValue;
				newParent.id = idFormatValue;
				parseChildrenUnderNewActiveFormat (this, xmlToParse, newParent, _activeFormat, null);	
				return;
			}
			
			var befNumChildren:int = parent.numChildren;
			parseFlowGroupElementChildren(xmlToParse, parent, null, true);
			
			// nothing got added - the custom element will be normalized away so just ignore it
			if (befNumChildren == parent.numChildren)
				return;

			if (befNumChildren+1 == parent.numChildren)
			{
				// exactly one child was added - just tag it with the typeName if possible
				var addedChild:FlowElement = parent.getChildAt(befNumChildren);
				if (addedChild.id == null && addedChild.styleName == null && addedChild.typeName == addedChild.defaultTypeName)
				{
					addedChild.typeName = name.toLowerCase();
					return;
				}
			}
			
			// have to make one - case 1)
			newParent = ((parent is ParagraphElement) || (parent is SubParagraphGroupElementBase)) ? new SubParagraphGroupElement() : new DivElement;
			newParent.typeName = name.toLowerCase();
			newParent.replaceChildren(0,0,parent.mxmlChildren.slice(befNumChildren));
			addChild(parent,newParent);
		}										
		
		tlf_internal override function  parseObject(name:String, xmlToParse:XML, parent:FlowGroupElement, exceptionElements:Object=null):void
		{
			// override to allow upper case tag names
			super.parseObject(name.toUpperCase(), xmlToParse, parent, exceptionElements);
		}
		
		/** @private */
		protected override function checkNamespace(xmlToParse:XML):Boolean
		{	
			/* Ignore namespace */
			return true;
		}
		
		/** Splits the paragraph wherever a break element occurs and removes the latter
		 * This is to replicate TextField handling of <br/>: splits the containing paragraph (implied or otherwise)
		 * The <br/> itself doesn't survive.
		 * @private
		 */
		static protected function replaceBreakElementsWithParaSplits(para:ParagraphElement):void
		{
			// performance: when splitting the paragraph into multiple paragraphs take it out of the TextFlow
			var paraArray:Array;
			var paraIndex:int;
			var paraParent:FlowGroupElement;
	
			// Find each BreakElement and split into a new paragraph
			var elem:FlowLeafElement = para.getFirstLeaf();
			while (elem)
			{
				if (!(elem is BreakElement))
				{
					elem = elem.getNextLeaf(para);
					continue;					
				}
				if (!paraArray)
				{
					paraArray = [ para ];
					paraParent = para.parent;
					paraIndex = paraParent.getChildIndex(para);
					paraParent.removeChildAt(paraIndex);
				}
					
				// Split the para right after the BreakElement
				//CONFIG::debug { assert(elem.textLength == 1,"Bad TextLength in BreakElement"); }
				CONFIG::debug {assert( para.getAbsoluteStart() == 0,"Bad paragraph in replaceBreakElementsWithParaSplits"); }
				para = para.splitAtPosition(elem.getAbsoluteStart()+elem.textLength) as ParagraphElement;
				paraArray.push(para);
					
				// Remove the BreakElement
				elem.parent.removeChild(elem);	
				
				// point elem to the first leaf of the new paragraph
				elem = para.getFirstLeaf();
			}
			
			if (paraArray)
				paraParent.replaceChildren(paraIndex,paraIndex,paraArray);
		}
		
		/** HTML parsing code
		 *  Uses regular expressions for recognizing constructs like comments, tags etc.
		 *  and a hand-coded parser to recognize the document structure and covert to well-formed xml
		 *  TODO-1/16/2009:List caveats
		 */ 
		
		/* Regex for stuff to be stripped: a comment, processing instruction, or a declaration
		 *
		 * <!--.*?--> - comment
		 *   <!-- - start comment
		 *   .*? - anything (including newline character, thanks to the s flag); the ? prevents a greedy match (which could match a --> later in the string) 
		 *  --> - end comment
		 *  
		 * <\?(".*?"|'.*?'|[^>]+)*> - processing instruction
		 *   <\? - start processing instruction
		 *   (".*?"|'.*?'|[^>]+)* - 0 or more of the following (interleaved in any order)
		 *     ".*?" - anything (including >) so long as it is within double quotes; the ? prevents a greedy match (which could match everything until a later " in the string) 
		 *     '.*?' - anything (including >) so long as it is within single quotes; the ? prevents a greedy match (which could match everything until a later ' in the string)
		 *     [^>"']+ - one or more characters other than > (because > ends the processing instruction), " (handled above), ' (handled above) 
		 *   > - end processing instruction
		 *
		 * <!(".*?"|'.*?'|[^>"']+)*> - declaration; 
		 * TODO-1/15/2009:not sure if a declaration can contain > within quotes. Assuming it can, the regex is  
		 *  is exactly like processing instruction above except it uses a ! instead of a ?
		 * @private
		 */
		/** @private */
		tlf_internal static const stripRegex:RegExp = /<!--.*?-->|<\?(".*?"|'.*?'|[^>"']+)*>|<!(".*?"|'.*?'|[^>"']+)*>/sg;
						
		/* Regular expression for an HTML tag
		 * < - open
		 *
		 * (\/?) - start modifier; 0 or 1 occurance of one of /
		 *
		 * (\w+) - tag name; 1 or more name characters
		 *
		 * ((?:\s+\w+(?:\s*=\s*(?:".*?"|'.*?'|[\w\.]+))?)*) - attributes; 0 or more of the following
		 *   (?:\s+\w+(?:\s*=\s*(?:".*?"|'.*?'|[\w\.]+))?) - attribute; 1 or more space, followed by 1 or more name characters optionally followed by
		 *      \s*=\s*(?:".*?"|'.*?'|[\w\.]+) - attribute value assignment; optional space followed by = followed by more optional space followed by one of
		 *         ".*?" - quoted attribute value (using double quotes); the ? prevents a greedy match (which could match everything until a later " in the string)
		 *         '.*?' - quoted attribute value (using single quotes); the ? prevents a greedy match ((which could match everything until a later ' in the string)
		 *         [\w\.]+ - unquoted attribute value; can only contain name characters or a period
		 *  Note: ?: specifies a non-capturing group (i.e., match won't be recorded or used as a numbered back-reference)
		 *
		 * \s* - optional space
		 *
		 * (\/?) - end modifer (0 or 1 occurance of /)
		 *
		 * > - close
		 * @private
		 */
		/** @private */
		tlf_internal static const tagRegex:RegExp = /<(\/?)(\w+)((?:\s+\w+(?:\s*=\s*(?:".*?"|'.*?'|[\w\.]+))?)*)\s*(\/?)>/sg;
		
		/** Regular expression for an attribute. Except for grouping differences, this regex is the same as the one that appears in tagRegex
		 * @private
		 */
		tlf_internal static const attrRegex:RegExp = /\s+(\w+)(?:\s*=\s*(".*?"|'.*?'|[\w\.]+))?/sg;
		
		/** Wrapper for core HTML parsing code that manages XML settings during the process
		 * @private
		 */
		protected function toXML(source:String):XML
		{
			var xml:XML;
			
			var originalSettings:Object = XML.settings();
			try
			{
				XML.ignoreProcessingInstructions = false;		
				XML.ignoreWhitespace = false;	

				xml = toXMLInternal(source);				
			}			
			finally
			{
				XML.setSettings(originalSettings);
			}	
			
			return xml;
		}	
		
		/** Convert HTML string to well-formed xml, accounting for the following HTML oddities
		 * 
		 * 1) Start tags are optional for some elements.
		 * Optional start tag not specified&lt;/html&gt;
		 * TextField dialect: This is true for all elements. 
		 * 
		 * 2) End tags are optional for some elements. Elements with missing end tags may be implicitly closed by
		 *    a) start-tag for a peer element
		 *    &lt;p&gt;p element without end tag; closed by next p start tag
		 *    &lt;p&gt;closes previous p element with missing end tag&lt;/p&gt;
		 * 
		 *    b) end-tag for an ancestor element 
		 * 	  &lt;html&gt;&lt;p&gt;p element without end tag; closed by next end tag of an ancestor&lt;/html&gt;
		 *     TextField dialect: This is true for all elements. 
		 * 
		 * 3) End tags are forbidden for some elements
		 * &lt;br&gt; and &lt;br/&gt; are valid, but &lt;br&gt;&lt;/br&gt; is not
		 * TextField dialect: Does not apply. 
		 * 
		 * 4) Element and attribute names may use any case
		 * &lt;P ALign="left"&gt;&lt;/p&gt;
		 * 
		 * 5) Attribute values may be unquoted
		 * &lt;p align=left/&gt;
		 * 
		 * 6) Boolean attributed may assume a minimized form
		 * &lt;p selected/&gt; is equivalent to &lt;p selected="selected"/&gt;
		 * @private
		 */	
		protected function toXMLInternal(source:String):XML
		{
			// Strip out comments, processing instructions and declaratins	
			source = source.replace(stripRegex, "");
			
			// Parse the source, looking for tags and interleaved text content, creating an XML hierarchy in the process.
			// At any given time, there is a chain of 'open' elements corresponding to unclosed tags, the innermost of which is 
			// tracked by the currElem. Content (element or text) parsed next is added as a child of currElem.
			
			// Root of the XML hierarchy (set to <html/> because the html start tag is optional)
			// Note that source may contain an html start tag, in which case we'll end up with two such elements
			// This is not quite correct, but handled by the importer  
			var root:XML = <HTML/>; 
			var currElem:XML = root;  
			
			var lastIndex:int = tagRegex.lastIndex = 0;
			var openElemName:String;
						
			do
			{						
				var result:Object = tagRegex.exec(source);
				if (!result)
				{
					// No more tags: add text (starting at search index) as a child of the innermost open element and break out
					appendTextChild (currElem, source.substring(lastIndex));
					break;
				}
				
				if (result.index != lastIndex)
				{
					// Add text between tags as a child of the innermost open element
					appendTextChild (currElem, source.substring(lastIndex, result.index));
				}
				
				var tag:String = result[0]; // entire tag
				var hasStartModifier:Boolean = (result[1] == "\/"); // modifier after < (/ for end tag)
				var name:String = result[2].toUpperCase();  // name; use lower case
				var attrs:String = result[3];  // attributes; including whitespace
				var hasEndModifier:Boolean = (result[4] == "\/"); // modifier before > (/ for composite start and end tag)

				if (!hasStartModifier) // start tag 
				{	
					// Special case for implicit closing of <p>
					// TODO-12/23/2008: this will need to be handled more generically				
					if (name == "P" && currElem.name().localName == "P")
						currElem = currElem.parent();
						
					// Create an XML element by constructing a tag that can be fed to the XML constructor. Specifically, ensure
					// - it is a composite tag (start and end tag together) using the terminating slash shorthand
					// - element and attribute names are lower case (this is not required, but doesn't hurt)
					// - attribute values are quoted  	
					// - boolean attributes are fully specified (e.g., selected="selected" rather than selected)
					tag = "<" + name;
					do
					{
						var innerResult:Object = attrRegex.exec(attrs);
						if (!innerResult)
							break;
							
						var attrName:String = innerResult[1].toUpperCase();
						tag += " " + attrName + "="; 
						var val:String = innerResult[2] ? innerResult[2] : attrName; /* boolean attribute with implied value equal to attribute name */
						var startChar:String = val.charAt(0); 
						tag += ((startChar == "'" || startChar == "\"") ? val : ("\"" + val + "\""));
						
					} while (true);	 
					tag += "\/>";
					
					// Add the corresponding element as a child of the innermost open element 
					currElem.appendChild(new XML(tag));
					
					// The new element becomes the innermost open element unless it is already closed because
					// - this is a composite start and end tag (i.e., has an end modifier) 
					// - the start tag itself implies closure
					if (!hasEndModifier && !doesStartTagCloseElement(name))
						currElem = currElem.children()[currElem.children().length()-1];	
				}	
				else // end tag
				{	
					if (hasEndModifier || attrs.length)
					{
						reportError(GlobalSettings.resourceStringFunction("malformedTag",[tag]));
					}
					else
					{
						/*
						// Does not apply to TextField dialect
						if (isEndTagForbidden(name))
						{
							xxxreportError("End tag is not allowed for element " + name); NOTE : MAKE A LOCALIZABLE ERROR IF THIS COMES BACK
							return null;
						}*/
					
						// Move up the chain of open elements looking for a matching name
						// The matching element is closed and its parent becomes the innermost open element
						// Report error if matching element is not found and it requires a start tag
						// All intermediate open elements are also closed provided they don't require end tags
						// Report error if an intermediate element requires end tags
						var openElem:XML = currElem;
						do
						{
							openElemName = openElem.name().localName; 
							openElem = openElem.parent();
							
							if (openElemName == name)
							{
								currElem = openElem;
								break;
							}
							/*
							// Does not apply to TextField dialect
							else if (isEndTagRequired(openElemName))
							{
								xxxreportError("Missing end tag for element " + openElemName);
								return null;
							}*/
	
							
							if (!openElem)
							{
								// Does not apply to TextField dialect
								/*if (isStartTagRequired(name))
								{
									xxxreportError("Unexpected end tag " + name);
									return null;
								}*/
								break;
							}					
						}
						while (true);
					}
				}
				
				lastIndex = tagRegex.lastIndex;
				if (lastIndex == source.length)
					break; // string completely parsed
					
			} while (currElem); // null currElem means <html/> has been closed, so ignore everything else		
			
			// No more string to parse, specifically, no more end tags. 
			// Validate that remaining open elements do not require end tags.
			// Does not apply to TextField dialect
			/* while (currElem)
			{
				openElemName = currElem.name().localName; 
				if (isEndTagRequired(openElemName))
				{
					xxxreportError("Missing end tag for element " + openElemName);
					return null;
				}
				currElem = currElem.parent();
			}*/	
			
			return root;
		}
		
		/** @private */
		protected function doesStartTagCloseElement (tagName:String):Boolean
		{
			switch (tagName)
			{
				case "BR":
				case "IMG":
					return true;
				default:
					return false;
			}
		}
		
		/** @private */
		tlf_internal static const anyPrintChar:RegExp = /[^\u0009\u000a\u000d\u0020]/g;	

		/** Adds text as a descendant of the specified XML element. Adds an intermediate <span> element is created if parent is not a <span>
		 *  No action is taken for whitespace-only text
		 * @private
		 */
		protected function appendTextChild(parent:XML, text:String):void
		{
			// No whitespace collapse
			// if (text.match(anyPrintChar).length != 0) 
			{
				var parentIsSpan:Boolean = (parent.localName() == "SPAN");
				var elemName:String = parentIsSpan ? "DUMMY" : "SPAN";
				
				//var xml:XML = <{elemName}/>;
				//xml.appendChild(text);
				// The commented-out code above doesn't handle character entities like &lt; 
				// The following lets the XML constructor handle them 
				var xmlText:String = "<" + elemName + ">" + text + "<\/" + elemName + ">";
				try
				{
					var xml:XML = new XML(xmlText);
					parent.appendChild(parentIsSpan ? xml.children()[0] : xml);
				}
				catch (e:*)
				{
					// Report malformed content like "<" instead of "&lt;"
					reportError(GlobalSettings.resourceStringFunction("malformedMarkup",[text]));
				}
					
			}
		}	
	}
}

import flashx.textLayout.conversion.TLFormatImporter;

/** Specialized to provide case insensitivity (as required by TEXT_FIELD_HTML_FORMAT)
 *  Keys need to be lower-cased. Values may or may not based on a flag passed to the constructor. 
 */
class CaseInsensitiveTLFFormatImporter extends TLFormatImporter
{
	private var _convertValuesToLowerCase:Boolean;

	public function CaseInsensitiveTLFFormatImporter(classType:Class,description:Object, convertValuesToLowerCase:Boolean=true)
	{
		_convertValuesToLowerCase = convertValuesToLowerCase;
		
		var lowerCaseDescription:Object = new Object();
		for (var prop:Object in description)
		{
			lowerCaseDescription[prop.toUpperCase()] = description[prop];
		}
		
		super(classType, lowerCaseDescription);
	}
	
	public override function importOneFormat(key:String,val:String):Boolean
	{
		return super.importOneFormat(key.toUpperCase(), _convertValuesToLowerCase ? val.toLowerCase() : val);  
	} 
	
	public function getFormatValue (key:String):*
	{
		return result ? result[key.toUpperCase()] : undefined;
	}
	
}

class HtmlCustomParaFormatImporter extends TLFormatImporter
{
	public function HtmlCustomParaFormatImporter(classType:Class,description:Object)
	{
		super(classType,description);
	}
	
	public override function importOneFormat(key:String,val:String):Boolean
	{
		key = key.toUpperCase();
		
		if (key == "ALIGN")
			key = "textAlign";
		return super.importOneFormat(key,val.toLowerCase()); // covert val to lowercase because TLF won't accept, say, "RIGHT"
	} 
}

class TextFormatImporter extends TLFormatImporter
{
	public function TextFormatImporter(classType:Class,description:Object)
	{
		super(classType,description);
	}
	
	public override function importOneFormat(key:String,val:String):Boolean
	{
		key = key.toUpperCase();
		
		if (key == "LEFTMARGIN")
			key = "paragraphStartIndent"; // assumed to be left-to-right text since we don't handle DIR attribute
		else if (key == "RIGHTMARGIN")
			key = "paragraphEndIndent";   // assumed to be left-to-right text since we don't handle DIR attribute
		else if (key == "INDENT")
			key = "textIndent";
		else if (key == "LEADING")
			key = "lineHeight";
		else if (key == "TABSTOPS")
		{
			key = "tabStops";
			// Comma-delimited in TextField HTML format, space delimited in TLF
			val = val.replace(/,/g, ' '); 
		}
		return super.importOneFormat(key,val); // no case-coversion required, values for these formats in TLF are case-insensitive
	} 
}

class FontImporter extends TLFormatImporter
{
	public function FontImporter(classType:Class,description:Object)
	{
		super(classType,description);
	}
	
	public override function importOneFormat(key:String,val:String):Boolean
	{
		key = key.toUpperCase();
		if (key == "LETTERSPACING")
			key = "trackingRight";
		else if (key == "FACE")
			key = "fontFamily";
		else if (key == "COLOR")
			key = "color";
		return super.importOneFormat(key,val);  // no case-coversion required, values for these formats in TLF are case-insensitive
	} 
}

