http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/utils/HTMLDocumentExporter.as
----------------------------------------------------------------------
diff --git a/Radii8Library/src/com/flexcapacitor/utils/HTMLDocumentExporter.as 
b/Radii8Library/src/com/flexcapacitor/utils/HTMLDocumentExporter.as
new file mode 100644
index 0000000..c179e86
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/utils/HTMLDocumentExporter.as
@@ -0,0 +1,1370 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 com.flexcapacitor.utils {
+       import com.flexcapacitor.model.IDocument;
+       import com.flexcapacitor.utils.supportClasses.ComponentDescription;
+       import com.flexcapacitor.views.supportClasses.Styles;
+       
+       import flash.display.BitmapData;
+       import flash.display.DisplayObject;
+       import flash.display.JPEGEncoderOptions;
+       import flash.display.PNGEncoderOptions;
+       import flash.geom.Rectangle;
+       import flash.utils.ByteArray;
+       import flash.utils.Dictionary;
+       import flash.utils.getTimer;
+       
+       import mx.core.IUIComponent;
+       import mx.core.IVisualElement;
+       import mx.core.IVisualElementContainer;
+       import mx.graphics.codec.JPEGEncoder;
+       import mx.graphics.codec.PNGEncoder;
+       import mx.styles.IStyleClient;
+       import mx.utils.Base64Encoder;
+       
+       import spark.components.BorderContainer;
+       import spark.components.HGroup;
+       import spark.components.supportClasses.GroupBase;
+       import spark.layouts.BasicLayout;
+       import spark.layouts.HorizontalLayout;
+       import spark.layouts.TileLayout;
+       import spark.layouts.VerticalLayout;
+       import spark.utils.BitmapUtil;
+       
+       /**
+        * Exports a document to HTML
+        * */
+       public class HTMLDocumentExporter extends DocumentExporter {
+               
+               public function HTMLDocumentExporter() {
+               
+               }
+               
+               /**
+                * Sets explicit size regardless if size is explicit
+                * */
+               public var setExplicitSize:Boolean = true;
+               
+               /**
+                * Sets styles inline
+                * */
+               public var useInlineStyles:Boolean;
+               
+               /**
+                * Name of token in the template that is replaced by the 
+                * */
+               public var contentToken:String = "<!--template_content-->";
+               
+               /**
+                * CSS to add to 
+                * */
+               public var css:String;
+               
+               /**
+                * Adds border box CSS 
+                * */
+               public var borderBoxCSS:String;
+               
+               /**
+                * Show outline 
+                * */
+               public var showBordersCSS:String;
+               
+               /**
+                * Zoom CSS
+                * */
+               public var zoomCSS:String;
+               
+               /**
+                * Page zoom level
+                * */
+               public var scaleLevel:Number;
+               
+               /**
+                * CSS for SVG button
+                * */
+               public var buttonCSS:String;
+               
+               public var buttonCSS2:String;
+               
+               public var stylesheets:String;
+               
+               public var template:String;
+               
+               /**
+                * Creates a snapshot of the application and sets it as the 
background image
+                * */
+               public var showScreenshotBackground:Boolean = false;
+               
+               /**
+                * Alpha of the background image
+                * */
+               public var backgroundImageAlpha:Number = .5;
+               
+               /**
+                * Used to create PNG images
+                * */
+               public var pngEncoder:PNGEncoder;
+               
+               /**
+                * Used to create JPEG images
+                * */
+               public var jpegEncoder:JPEGEncoder;
+               
+               /**
+                * Extension of the document when exporting to a file. 
+                * */
+               public var extension:String;
+               
+               /**
+                * Indicates when the user has typed in the text area
+                * */
+               [Bindable]
+               public var isCodeModifiedByUser:Boolean;
+               
+               /**
+                * Show borders around HTML elements
+                * */
+               [Bindable]
+               public var showBorders:Boolean;
+               
+               /**
+                * Use SVG button class
+                * */
+               [Bindable]
+               public var useSVGButtonClass:Boolean = true;
+               
+               /**
+                * Show full HTML page source
+                * */
+               [Bindable]
+               public var showFullHTMLPageSource:Boolean = false;
+               
+               /**
+                * Last source code
+                * */
+               [Bindable]
+               public var sourceCode:String;
+               
+               public var includePreviewCode:Boolean;
+               
+               public var horizontalPositions:Array = 
["x","left","right","horizontalCenter"];
+               public var horizontalCenterPosition:String = "horizontalCenter";
+               public var verticalPositions:Array = 
["y","top","bottom","verticalCenter"];
+               public var verticalCenterPosition:String = "verticalCenter";
+               public var sizesPositions:Array = ["width","height"];
+               
+               public var addZoom:Boolean;
+               public var output:String = "";
+               public var cssOutput:String = "";
+               public var wrapInPreview:Boolean;
+               
+               /**
+                * 
+                * */
+               public var useWrapperDivs:Boolean;
+               public var showOnlyHTML:Boolean;
+               public var showOnlyCSS:Boolean;
+               
+               /**
+                * @inheritDoc
+                * */
+               public function export(iDocument:IDocument, reference:Boolean = 
false, target:Object = null):String {
+                       var XML1:XML;
+                       var application:Object = iDocument ? iDocument.instance 
: null;
+                       var targetDescription:ComponentDescription;
+                       var componentTree:ComponentDescription;
+                       var zoomOutput:String;
+                       var xml:XML;
+                       
+                       componentTree = iDocument.componentDescription;
+                       cssOutput = "";
+                       
+                       // find target in display list and get it's code
+                       targetDescription = 
DisplayObjectUtils.getTargetInComponentDisplayList(target, componentTree);
+                       
+                       
+                       if (targetDescription) {
+                               
+                               // see the top of this document on how to 
generate source code
+                               getAppliedPropertiesFromHistory(iDocument, 
targetDescription);
+                       
+                               if (!reference) {
+                                       //output = 
getHTMLOutputString(iDocument, iDocument.componentDescription);
+                                       
+                                       var includePreviewCode:Boolean = true;
+                                       var tabDepth:String = "";
+                                       
+                                       if (showFullHTMLPageSource) {
+                                               tabDepth = ""; //"\t\t\t";
+                                       }
+                                       
+                                       output = getHTMLOutputString(iDocument, 
targetDescription, true, tabDepth, includePreviewCode);
+                                       output += "\n";
+                                       
+                                       var applicationContainerID:String = 
"applicationContainer";
+                                       var zoomInID:String = wrapInPreview ? 
application.name : applicationContainerID;
+                                       
+                                       // not enabled at the moment - see code 
inspector
+                                       if (wrapInPreview) {
+                                               var wrapper:String = "<div 
id=\"" + applicationContainerID +"\" style=\"position:absolute;";
+                                               //output += "width:" + 
(component.instance.width + 40) + "px;";
+                                               wrapper += "width:100%;";
+                                               wrapper += "height:" + 
(targetDescription.instance.height + 40) + "px;";
+                                               wrapper += 
"background-color:#666666;\">\n" + output + "</div>";
+                                               output = wrapper;
+                                       }
+                                       
+                                       if (stylesheets) {
+                                               output += "\n" + stylesheets;
+                                       }
+                                       
+                                       var styles:String = "";
+                                       
+                                       if (showOnlyCSS) {
+                                               
+                                               // SPOT NUMBER 1
+                                               // you have to include css 
options in another spot as well below
+                                               // SEE SPOT NUMBER 2
+                                               // refactor
+                                               if (!useInlineStyles) {
+                                                       styles = "\n" + 
cssOutput;
+                                               }
+                                               
+                                               if (css) {
+                                                       styles += "\n" + css;
+                                               }
+                                               
+                                               if (useSVGButtonClass) {
+                                                       styles += "\n" + 
buttonCSS2;
+                                               }
+                                               
+                                               if (showBorders) {
+                                                       styles += "\n" + 
showBordersCSS;
+                                               }
+                                               
+                                               if (addZoom) {
+                                                       //zoomOutput = 
zoomCSS.replace(/IFRAME_ID/g, "#" + application.name);
+                                                       zoomOutput = 
zoomCSS.replace(/IFRAME_ID/g, "#" + zoomInID);
+                                                       zoomOutput = 
zoomOutput.replace(/ZOOM_VALUE/g, iDocument.scale);
+                                                       styles += "\n" + 
zoomOutput;
+                                               }
+                                               
+                                               output = styles;
+                                       }
+                                       else if (showOnlyHTML) {
+                                               
+                                               if (showFullHTMLPageSource) {
+                                                       output = 
template.replace(contentToken, output);
+                                               }
+                                       }
+                                       else {
+                                               // THIS IS SPOT NUMBER 2
+                                               // You have to include CSS 
options in another place as well
+                                               // see spot number 1
+                                               if (!useInlineStyles) {
+                                                       styles += "\n" + 
cssOutput;
+                                               }
+                                               
+                                               if (css) {
+                                                       styles += "\n" + css;
+                                               }
+                                               
+                                               if (useSVGButtonClass) {
+                                                       styles += "\n" + 
buttonCSS2;
+                                               }
+                                               
+                                               if (showBorders) {
+                                                       styles += "\n" + 
showBordersCSS;
+                                               }
+                                               
+                                               
+                                               if (addZoom) {
+                                                       //zoomOutput = 
zoomCSS.replace(/IFRAME_ID/g, "#" + application.name);
+                                                       zoomOutput = 
zoomCSS.replace(/IFRAME_ID/g, "#" + zoomInID);
+                                                       zoomOutput = 
zoomOutput.replace(/ZOOM_VALUE/g, iDocument.scale);
+                                                       styles += "\n" + 
zoomOutput;
+                                               }
+                                               
+                                               
+                                               
+                                               
+                                               // add styles in style tags and 
add to output
+                                               if (styles!="") {
+                                                       output += "\n" + 
wrapInStyleTags(styles);
+                                               }
+                                               
+                                               
+                                               
+                                               if (showFullHTMLPageSource) {
+                                                       output = 
template.replace(contentToken, output);
+                                               }
+                                       }
+                                       
+                                                       
+                                       isValid = XMLUtils.isValidXML(output);
+                                       
+                                       if (!isValid) {
+                                               error = 
XMLUtils.validationError;
+                                               errorMessage = 
XMLUtils.validationErrorMessage;
+                                       }
+                                       else {
+                                               error = null;
+                                               errorMessage = null;
+                                       }
+                       
+                                       var checkValidXML:Boolean = false;
+                                       if (checkValidXML) {
+                                               try {
+                                                       // don't use XML for 
HTML output because it converts this:
+                                                       // <div ></div>
+                                                       // to this:
+                                                       // <div />
+                                                       // and that breaks the 
html page
+                                                       
+                                                       // we can still try it 
to make sure it's valid
+                                                       // we could be saving 
CPU cycles here?
+                                                       var time:int = 
getTimer();
+                                                       
+                                                       // check if valid XML
+                                                       // we could also use 
XMLUtils.isValid but this is also for formatting
+                                                       xml = new XML(output);
+                                                       time = getTimer() -time;
+                                                       //trace("xml validation 
parsing time=" + time);
+                                                       sourceCode = output;
+                                               }
+                                               catch (error:Error) {
+                                                       // Error #1083: The 
prefix "s" for element "Group" is not bound.
+                                                       // <s:Group x="93" 
y="128">
+                                                       //      <s:Button 
x="66" y="17"/>
+                                                       //</s:Group>
+                                                       time = getTimer() -time;
+                                                       //trace("xml validation 
parsing time with error=" + time);
+                                                       sourceCode = output;
+                                               }
+                                       }
+                                       else {
+                                               sourceCode = output;
+                                       }
+                               }
+                               else {// this should not be here - it should be 
in DocumentData
+                                       XML1 = <document />;
+                                       XML1.@host = iDocument.host;
+                                       XML1.@id = iDocument.id;
+                                       XML1.@name = iDocument.name;
+                                       XML1.@uid = iDocument.uid;
+                                       XML1.@uri = iDocument.uri;
+                                       output = XML1.toXMLString();
+                               }
+                       }
+                       
+                       return output;
+               }
+               
+       
+               
+               /**
+                * Gets the formatted output from a component.
+                * Yes, this is a mess. It needs refactoring.  
+                * I wanted to see if I could quickly generate valid HTML 
+                * from the component tree. 
+                * 
+                * There is partial work with CSS properties objects but those 
are not implemented yet. 
+                * */
+               public function getHTMLOutputString(iDocument:IDocument, 
component:ComponentDescription, addLineBreak:Boolean = false, tabs:String = "", 
includePreview:Boolean = false):String {
+                       var property:Object = component.properties;
+                       var componentName:String = component.name ? 
component.name.toLowerCase() : "";
+                       var htmlName:String = componentName ? componentName : 
"";
+                       var componentChild:ComponentDescription;
+                       var contentToken:String = "[child_content]";
+                       var styleValue:String = "position:absolute;";
+                       var styles:Styles = new Styles();
+                       var wrapperStyles:Styles = new Styles();
+                       var isHorizontalLayout:Boolean;
+                       var isVerticalLayout:Boolean;
+                       var isBasicLayout:Boolean;
+                       var isTileLayout:Boolean;
+                       var childContent:String = "";
+                       var wrapperTag:String = "";
+                       var centeredHorizontally:Boolean;
+                       var wrapperTagStyles:String = "";
+                       var properties:String = "";
+                       var outlineStyle:String;
+                       var output:String = "";
+                       var type:String = "";
+                       var instance:Object;
+                       var numElements:int;
+                       var index:int;
+                       var value:*;
+                       var gap:int;
+                       
+                       
+                       // we are setting the styles in a string now
+                       // the next refactor should use the object so we can 
output to CSS
+                       styles.position = Styles.ABSOLUTE;
+                       outlineStyle = "outline:1px solid red;"; // we should 
enable or disable outlines via code not markup on in the export
+                       
+                       // get layout positioning
+                       if (component.parent && component.parent.instance is 
IVisualElementContainer) {
+                               
+                               if (component.parent.instance.layout is 
HorizontalLayout) {
+                                       isHorizontalLayout = true;
+                                       styleValue = 
styleValue.replace("absolute", "relative");
+                                       //styleValue += 
"vertical-align:middle;";
+                                       styles.position = Styles.RELATIVE;
+                                       index = 
GroupBase(component.parent.instance).getElementIndex(component.instance as 
IVisualElement);
+                                       numElements = 
GroupBase(component.parent.instance).numElements;
+                                       wrapperTagStyles += 
hasExplicitSizeSet(component.instance as IVisualElement) ? 
"display:inline-block;" : "display:inline;";
+                                       wrapperStyles.display = 
hasExplicitSizeSet(component.instance as IVisualElement) ? Styles.INLINE_BLOCK 
: Styles.INLINE;
+                                       gap = 
HorizontalLayout(component.parent.instance.layout).gap - 4;
+                                       
+                                       
+                                       if (index<numElements-1 && 
numElements>1) {
+                                               //wrapperTagStyles += 
"padding-right:" + gap + "px;";
+                                               wrapperTagStyles += 
Styles.MARGIN_RIGHT+":" + gap + "px;";
+                                               wrapperStyles.marginRight =  
gap + "px";
+                                               
+                                       }
+                                       
+                                       wrapperTag = "div";
+                               }
+                               else if (component.parent.instance.layout is 
TileLayout) {
+                                       //isHorizontalLayout = true;
+                                       isTileLayout = true;
+                                       styleValue = 
styleValue.replace("absolute", "relative");
+                                       styles.position = Styles.RELATIVE;
+                                       index = 
GroupBase(component.parent.instance).getElementIndex(component.instance as 
IVisualElement);
+                                       numElements = 
GroupBase(component.parent.instance).numElements;
+                                       wrapperTagStyles += 
hasExplicitSizeSet(component.instance as IVisualElement) ? 
"display:inline-block;" : "display:inline;";
+                                       wrapperStyles.display = 
hasExplicitSizeSet(component.instance as IVisualElement) ? Styles.INLINE_BLOCK 
: Styles.INLINE;
+                                       gap = 
TileLayout(component.parent.instance.layout).horizontalGap - 4;
+                                       
+                                       if (index<numElements-1 && 
numElements>1) {
+                                               //wrapperTagStyles += 
"padding-right:" + gap + "px;";
+                                               // using "margin-right" because 
if you set a fixed width padding was not doing anything
+                                               wrapperTagStyles += 
Styles.MARGIN_RIGHT+":" + gap + "px;";
+                                               //wrapperStyles.paddingRight =  
gap + "px";
+                                               wrapperStyles.marginRight =  
gap + "px";
+                                       }
+                                       
+                                       wrapperTag = "div";
+                               }
+                               
+                               else if (component.parent.instance.layout is 
VerticalLayout) {
+                                       isVerticalLayout = true;
+                                       styleValue = 
styleValue.replace("absolute", "relative");
+                                       styles.position = Styles.RELATIVE;
+                                       index = 
GroupBase(component.parent.instance).getElementIndex(component.instance as 
IVisualElement);
+                                       numElements = 
GroupBase(component.parent.instance).numElements;
+                                       gap = 
VerticalLayout(component.parent.instance.layout).gap;
+                                       
+                                       
+                                       if (index<numElements-1 && 
numElements>1) {
+                                               //wrapperTagStyles += 
"padding-bottom:" + gap + "px;";
+                                               wrapperTagStyles += 
Styles.MARGIN_BOTTOM+":" + gap + "px;";
+                                               //wrapperStyles.paddingBottom = 
 gap + "px";
+                                               wrapperStyles.marginBottom =  
gap + "px";
+                                       }
+                                       
+                                       wrapperTag = "div";
+                               }
+                               
+                               else if (component.parent.instance.layout is 
BasicLayout) {
+                                       isBasicLayout = true;
+                                       
+                                       
+                                       
+                                       //styleValue = 
styleValue.replace("absolute", "relative");
+                                       //styles.position = Styles.RELATIVE;
+                                       /*index = 
GroupBase(component.parent.instance).getElementIndex(component.instance as 
IVisualElement);
+                                       numElements = 
GroupBase(component.parent.instance).numElements;
+                                       gap = 
BasicLayout(component.parent.instance.layout).gap;*/
+                                       
+                                       /*if (index<numElements-1 && 
numElements>1) {
+                                               wrapperTagStyles += 
"padding-bottom:" + gap + "px";
+                                       }
+                                       
+                                       wrapperTag = "div";*/
+                               }
+                       }
+                       
+                       // constraints take higher authority
+                       var isHorizontalSet:Boolean;
+                       var isVerticalSet:Boolean;
+                       
+                       // loop through assigned properties
+                       for (var propertyName:String in property) {
+                               value = property[propertyName];
+                               
+                               if (value===undefined || value==null) {
+                                       continue;
+                               }
+                               
+                               
+                               if (verticalPositions.indexOf(propertyName)!=-1 
&& !isVerticalSet) {
+                                       styleValue = 
getVerticalPositionHTML(component.instance as IVisualElement, styles, 
styleValue, isBasicLayout);
+                                       isVerticalSet = true;
+                               }
+                               else if 
(horizontalPositions.indexOf(propertyName)!=-1 && !isHorizontalSet) {
+                                       styleValue = 
getHorizontalPositionHTML(component.instance as IVisualElement, styles, 
styleValue, isBasicLayout);
+                                       isHorizontalSet = true;
+                               }
+                               
+                       }
+                       
+                       
+                       if (htmlName) {
+                               
+                               // create code for element type
+                               if (htmlName=="application") {
+                                       htmlName = "div";
+                                       
+                                       // container div
+                                       if (includePreview) {
+                                               /*output = "<div 
style=\"position:absolute;";
+                                               //output += "width:" + 
(component.instance.width + 40) + "px;";
+                                               output += "width:100%;";
+                                               output += "height:" + 
(component.instance.height + 40) + "px;";
+                                               output += 
"background-color:#666666;\">";*/
+                                               output += "<div";
+                                               //output = 
getNameString(component.instance, output);
+                                               output += properties ? " " + 
properties : " ";
+                                               output = 
getIdentifierAttribute(component.instance, output);
+                                               styleValue = 
styleValue.replace("absolute", "relative");
+                                               styles.position = 
Styles.ABSOLUTE;
+                                               styleValue += "width:" + 
component.instance.width+ "px;";
+                                               styleValue += "height:" + 
component.instance.height+ "px;";
+                                               styleValue += "font-family:" + 
component.instance.getStyle("fontFamily") + ";";
+                                               styleValue += "font-size:" + 
component.instance.getStyle("fontSize") + "px;";
+                                               styleValue += "margin:0 auto;";
+                                               styleValue += 
"left:8px;top:14px;";
+                                               styleValue += "overflow:auto;";
+                                               styleValue += 
"background-color:" + 
DisplayObjectUtils.getColorInHex(component.instance.getStyle("backgroundColor"),
 true) + ";";
+                                               //output += properties ? " " : 
"";
+                                               output += 
setStyles(component.instance, styleValue);
+
+                                               
+                                               if (showScreenshotBackground) {
+                                                       var 
backgroundImageID:String = "backgroundComparisonImage";
+                                                       var 
imageDataFormat:String = "png";//"jpeg";
+                                                       var imageData:String = 
getDataURI(component.instance, imageDataFormat);
+                                                       var 
backgroundSnapshot:String = "\n" + tabs + "\t" + "<img ";
+                                                       backgroundSnapshot += 
"id=\"" + backgroundImageID +"\""; 
+                                                       backgroundSnapshot += " 
src=\"" + imageData + "\" ";
+                                                       
+                                                       output += 
backgroundSnapshot;
+                                                       output += 
setStyles("#"+backgroundImageID, 
"position:absolute;opacity:"+backgroundImageAlpha+";top:0px;left:0px;", true);
+                                                       /* background-image 
didn't work in FF on mac. didn't test on other browsers
+                                                       //trace(imageData);
+                                                       var 
imageDataStyle:String = "#" + getIdentifierOrName(target) + "  {\n";
+                                                       //imageDataStyle = 
"\tbackground-image: url(data:image/jpeg;base64,"+imageData+");";
+                                                       imageDataStyle += 
"\tbackground-repeat: no-repeat;\n";
+                                                       imageDataStyle += 
"\tbackground-image: 
url(data:image/"+imageDataFormat+";base64,"+imageData+");\n}";
+                                                       styles += "\n" + 
imageDataStyle;*/
+                                               }
+                                               
+                                               output += contentToken;
+                                               //output += "\n </div>\n</div>";
+                                               output += "\n</div>";
+                                               
+                                       }
+                                       else {
+                                               //output = "<div 
style=\"position: absolute;width:100%;height:100%;background-color:#666666;\">";
+                                               output = "<div";
+                                               output += properties ? " " + 
properties : " ";
+                                               output = 
getIdentifierAttribute(component.instance, output);
+                                               //output = 
getNameString(component.instance, output);
+                                               output += properties ? " " + 
properties : "";
+                                               styleValue += "width:" + 
component.instance.width+ "px;";
+                                               styleValue += "height:" + 
component.instance.height+ "px;";
+                                               styleValue += "border:1px solid 
black";
+                                               styleValue += 
"background-color:" + 
DisplayObjectUtils.getColorInHex(component.instance.getStyle("backgroundColor"),
 true) + ";";
+                                               //output += properties ? " " : 
"";
+                                               output += 
setStyles(component.instance, styleValue);
+                                               output += contentToken;
+                                               output += "\n</div>";
+                                       }
+                               }
+                               
+                               else if (htmlName=="group" || 
htmlName=="vgroup") {
+                                       htmlName = "div";
+                                       output = tabs + 
getWrapperTag(wrapperTag, false, wrapperTagStyles);
+                                       output += "<div " + properties;
+                                       output = 
getIdentifierAttribute(component.instance, output);
+                                       output += properties ? " " : "";
+                                       styleValue = 
getSizeString(component.instance as IVisualElement, styleValue, 
isHorizontalSet);
+                                       
+                                       //styleValue += "width:" + 
component.instance.width+ "px;";
+                                       //styleValue += "height:" + 
component.instance.height+ "px;";
+                                       output += setStyles(component.instance, 
styleValue);
+                                       output += contentToken;
+                                       output += "\n" + tabs + "</div>";
+                                       output += getWrapperTag(wrapperTag, 
true);
+                               }
+                               
+                               else if (htmlName=="bordercontainer") {
+                                       htmlName = "div";
+                                       output = tabs + 
getWrapperTag(wrapperTag, false, wrapperTagStyles);
+                                       output += "<div " + properties;
+                                       output = 
getIdentifierAttribute(component.instance, output);
+                                       output += properties ? " " : "";
+                                       styleValue = 
getSizeString(component.instance as IVisualElement, styleValue, 
isHorizontalSet);
+                                       styleValue += 
getBorderString(component.instance as BorderContainer);
+                                       //styleValue += 
getColorString(component.instance as BorderContainer);
+                                       //styles += component.instance as 
BorderContainer);
+                                       
+                                       output += setStyles(component.instance, 
styleValue);
+                                       output += contentToken;
+                                       output += "\n" + tabs + "</div>";
+                                       output += getWrapperTag(wrapperTag, 
true);
+                                       
+                               }
+                               
+                               else if (htmlName=="hgroup" || 
htmlName=="tilegroup") {
+                                       htmlName = "div";
+                                       output = tabs + 
getWrapperTag(wrapperTag, false, wrapperTagStyles);
+                                       output += "<div " + properties;
+                                       output = 
getIdentifierAttribute(component.instance, output);
+                                       
+                                       //styleValue = 
getSizeString(component.instance as IVisualElement, styleValue);
+                                       if (component.name=="HGroup") {
+                                               styleValue += "width:" + 
Math.max(HGroup(component.instance).contentWidth, component.instance.width)+ 
"px;";
+                                       }
+                                       else {
+                                               styleValue += "width:" + 
component.instance.width+ "px;";
+                                       }
+                                       
+                                       styleValue += "height:" + 
component.instance.height+ "px;";
+                                       //var verical:String = 
component.instance.getStyle("verticalAlign");
+                                       var vericalAlign:String = 
component.instance.verticalAlign;
+                                       if 
(componentName.toLowerCase()=="hgroup" && vericalAlign=="middle") {
+                                               styleValue += "line-height:" + 
component.instance.height + "px;";
+                                       }
+                                       
+                                       output += properties ? " " : "";
+                                       output += setStyles(component.instance, 
styleValue);
+                                       output += contentToken;
+                                       output += "\n" + tabs + "</div>";
+                                       output += getWrapperTag(wrapperTag, 
true);
+                               }
+                               else if (htmlName=="button" || 
htmlName=="togglebutton") {
+                                       htmlName = "button";
+                                       output = tabs + 
getWrapperTag(wrapperTag, false, wrapperTagStyles);
+                                       output += "<input " + properties;
+                                       output = 
getIdentifierAttribute(component.instance, output);
+                                       output += " type=\"" + 
htmlName.toLowerCase() + "\"" ;
+                                       output += properties ? " " + properties 
: "";
+                                       styleValue = 
getSizeString(component.instance as IVisualElement, styleValue, 
isHorizontalSet);
+                                       styleValue += "font-family:" + 
component.instance.getStyle("fontFamily") + ";";
+                                       styleValue += "font-size:" + 
component.instance.getStyle("fontSize") + "px;";
+                                       output += " value=\"" + 
component.instance.label + "\"";
+                                       output += " class=\"buttonSkin\"";
+                                       output += setStyles(component.instance, 
styleValue);
+                                       
+                                       output += getWrapperTag(wrapperTag, 
true);
+                               }
+                               else if (htmlName=="checkbox") {
+                                       if (component.instance.label!="") {
+                                               output = tabs + 
getWrapperTag(wrapperTag, false, wrapperTagStyles);
+                                               output += "<label ";
+                                               output = 
getIdentifierAttribute(component.instance, output, "_Label");
+                                               styleValue = 
getSizeString(component.instance as IVisualElement, styleValue, 
isHorizontalSet);
+                                               //styleValue += "width:" + 
(component.instance.width + 6)+ "px;";
+                                               //styleValue += "height:" + 
component.instance.height+ "px;";
+                                               styleValue += "font-family:" + 
component.instance.getStyle("fontFamily") + ";";
+                                               styleValue += "font-size:" + 
component.instance.getStyle("fontSize") + "px;";
+                                               output += 
setStyles("#"+getIdentifierOrName(component.instance, true, "_Label"), 
styleValue);
+                                               output += "<input ";
+                                               output = 
getIdentifierAttribute(component.instance, output);
+                                               output += " type=\"" + 
htmlName.toLowerCase() + "\" ";
+                                               output += "/>" ;
+                                       }
+                                       else {
+                                               output = tabs + 
getWrapperTag(wrapperTag, false, wrapperTagStyles);
+                                               output += "<input " + 
properties;
+                                               output = 
getIdentifierAttribute(component.instance, output);
+                                               output += " type=\"" + 
htmlName.toLowerCase() + "\" " + properties;
+                                               //styleValue = 
getSizeString(component.instance as IVisualElement, styleValue);
+                                               output += 
setStyles(component.instance, styleValue);
+                                       }
+                                       
+                                       if (component.instance.label!="") {
+                                               output += " " + 
component.instance.label + "</label>";
+                                       }
+                                       
+                                       output += getWrapperTag(wrapperTag, 
true);
+                               }
+                               else if (htmlName=="radiobutton") {
+                                       htmlName = "radio";
+                                       if (component.instance.label!="") {
+                                               output = tabs + 
getWrapperTag(wrapperTag, false, wrapperTagStyles);
+                                               output += "<label ";
+                                               output = 
getIdentifierAttribute(component.instance, output, "_Label");
+                                               //styleValue += "width:" + 
(component.instance.width + 8)+ "px;";
+                                               //styleValue += "height:" + 
component.instance.height+ "px;";
+                                               styleValue = 
getSizeString(component.instance as IVisualElement, styleValue, 
isHorizontalSet);
+                                               styleValue += "font-family:" + 
component.instance.getStyle("fontFamily") + ";";
+                                               styleValue += "font-size:" + 
component.instance.getStyle("fontSize") + "px;";
+                                               output += 
setStyles("#"+getIdentifierOrName(component.instance, true, "_Label"), 
styleValue);
+                                               output += "<input 
type=\"radio\" " ;
+                                               output = 
getIdentifierAttribute(component.instance, output);
+                                               //styleValue = 
getSizeString(component.instance as IVisualElement, styleValue);
+                                               output += "/>" ;
+                                       }
+                                       else {
+                                               output = tabs + 
getWrapperTag(wrapperTag, false, wrapperTagStyles);
+                                               output += "<input type=\"" + 
htmlName.toLowerCase() + "\" " + properties;
+                                               output = 
getIdentifierAttribute(component.instance, output);
+                                               styleValue = 
getSizeString(component.instance as IVisualElement, styleValue, 
isHorizontalSet);
+                                               //styleValue = 
getSizeString(component.instance as IVisualElement, styleValue);
+                                               output += 
setStyles(component.instance, styleValue);
+                                       }
+                                       
+                                       if (component.instance.label!="") {
+                                               output += " " + 
component.instance.label + "</label>";
+                                       }
+                                       
+                                       output += getWrapperTag(wrapperTag, 
true);
+                               }
+                               else if (htmlName=="textinput" || 
htmlName=="combobox") {
+                                       htmlName = "input";
+                                       output = tabs + 
getWrapperTag(wrapperTag, false, wrapperTagStyles);
+                                       output += "<input ";
+                                       output = 
getIdentifierAttribute(component.instance, output);
+                                       output += " type=\"input\" "  + 
properties;
+                                       //styleValue += "width:" + 
component.instance.width+ "px;";
+                                       //styleValue += "height:" + 
component.instance.height+ "px;";
+                                       styleValue = 
getSizeString(component.instance as IVisualElement, styleValue, 
isHorizontalSet);
+                                       styleValue += "font-family:" + 
component.instance.getStyle("fontFamily") + ";";
+                                       styleValue += "font-size:" + 
component.instance.getStyle("fontSize") + "px;";
+                                       styleValue += "padding:0;border:1px 
solid " + 
DisplayObjectUtils.getColorInHex(component.instance.getStyle("borderColor"), 
true) + ";";
+                                       
+                                       if (htmlName=="combobox") {
+                                               output += " list=\"listdata\"";
+                                               //<datalist id="listData">
+                                                         //<option 
value="value 1">
+                                                         //<option 
value="value 2">
+                                                         //<option 
value="value 3">
+                                                       //</datalist> 
+                                       }
+                                       output += setStyles(component.instance, 
styleValue);
+                                       output += getWrapperTag(wrapperTag, 
true);
+                               }
+                               else if (htmlName=="dropdownlist") {
+                                       htmlName = "select";
+                                       output = tabs + 
getWrapperTag(wrapperTag, false, wrapperTagStyles);
+                                       output += "<select ";
+                                       output = 
getIdentifierAttribute(component.instance, output);
+                                       output += " type=\"input\" "  + 
properties;
+                                       //styleValue += "width:" + 
component.instance.width+ "px;";
+                                       //styleValue += "height:" + 
component.instance.height+ "px;";
+                                       styleValue = 
getSizeString(component.instance as IVisualElement, styleValue, 
isHorizontalSet);
+                                       styleValue += "font-family:" + 
component.instance.getStyle("fontFamily") + ";";
+                                       styleValue += "font-size:" + 
component.instance.getStyle("fontSize") + "px;";
+                                       styleValue += "padding:0;border:1px 
solid " + 
DisplayObjectUtils.getColorInHex(component.instance.getStyle("borderColor"), 
true) + ";";
+                                       
+                                       output += setStyles(component.instance, 
styleValue);
+                                       output += "</select>";
+                                       output += getWrapperTag(wrapperTag, 
true);
+                               }
+                               else if (htmlName=="linkbutton") {
+                                       htmlName = "a";
+                                       output = tabs + 
getWrapperTag(wrapperTag, false, wrapperTagStyles);
+                                       output += "<a "  + properties;
+                                       output = 
getIdentifierAttribute(component.instance, output);
+                                       //styleValue += "width:" + 
component.instance.width+ "px;";
+                                       //styleValue += "height:" + 
component.instance.height+ "px;";
+                                       styleValue = 
getSizeString(component.instance as IVisualElement, styleValue, 
isHorizontalSet);
+                                       styleValue += "font-family:" + 
component.instance.getStyle("fontFamily") + ";";
+                                       styleValue += "font-size:" + 
component.instance.getStyle("fontSize") + "px;";
+                                       //styles += 
getBorderString(component.instance as IStyleClient);
+                                       
+                                       output += properties ? " " : "";
+                                       output += setStyles(component.instance, 
styleValue);
+                                       output += component.instance.label;
+                                       output += "</a>";
+                                       output += getWrapperTag(wrapperTag, 
true);
+                               }
+                               else if (htmlName=="label") {
+                                       htmlName = "label";
+                                       if (useWrapperDivs) {
+                                               output = tabs + 
getWrapperTag(wrapperTag, false, wrapperTagStyles);
+                                       }
+                                       else {
+                                               output = tabs;
+                                       }
+                                       output += "<label "  + properties;
+                                       output = 
getIdentifierAttribute(component.instance, output);
+                                       //styleValue += "width:" + 
component.instance.width+ "px;";
+                                       //styleValue += "height:" + 
component.instance.height+ "px;";
+                                       styleValue = 
getSizeString(component.instance as IVisualElement, styleValue, 
isHorizontalSet, isVerticalSet);
+                                       //styleValue += wrapperTagStyles;
+                                       styleValue += "color:" + 
DisplayObjectUtils.getColorInHex(component.instance.getStyle("color"), true) + 
";";
+                                       styleValue += "font-weight:" + 
component.instance.getStyle("fontWeight") + ";";
+                                       styleValue += "font-family:" + 
component.instance.getStyle("fontFamily") + ";";
+                                       styleValue += "font-size:" + 
component.instance.getStyle("fontSize") + "px;";
+                                       styleValue += "line-height:" + "1;";
+                                       //styles += 
getBorderString(component.instance as IStyleClient);
+                                       
+                                       output += properties ? " " : "";
+                                       // remove wrapperTagStyles since we are 
trying to not use wrapper tags
+                                       //output += 
setStyles(component.instance, styleValue+wrapperTagStyles);
+                                       output += setStyles(component.instance, 
wrapperTagStyles+styleValue);
+                                       output += component.instance.text;
+                                       output += "</label>";
+                                       if (useWrapperDivs) {
+                                               output += 
getWrapperTag(wrapperTag, true);
+                                       }
+                               }
+                               else if (htmlName=="image") {
+                                       htmlName = "img";
+                                       output = tabs + 
getWrapperTag(wrapperTag, false, wrapperTagStyles);
+                                       output += "<img " + properties;
+                                       output = 
getIdentifierAttribute(component.instance, output);
+                                       //styleValue += "width:" + 
component.instance.width+ "px;";
+                                       //styleValue += "height:" + 
component.instance.height+ "px;";
+                                       styleValue = 
getSizeString(component.instance as IVisualElement, styleValue, 
isHorizontalSet);
+                                       output += properties ? " " : "";
+                                       
+                                       if (component.instance.source is 
BitmapData) {
+                                               output += " src=\"" + 
getDataURI(component.instance.source, "jpeg") + "\"";
+                                       }
+                                       else if (component.instance.source is 
String) {
+                                               output += " src=\"" + 
component.instance.source + "\"";
+                                       }
+                                       output += setStyles(component.instance, 
styleValue);
+                                       output += getWrapperTag(wrapperTag, 
true);
+                               }
+                               
+                               else {
+                                       // show placeholder NOT actual component
+                                       htmlName = "label";
+                                       if (useWrapperDivs) {
+                                               output = tabs + 
getWrapperTag(wrapperTag, false, wrapperTagStyles);
+                                       }
+                                       else {
+                                               output = tabs;
+                                       }
+                                       output += "<label "  + properties;
+                                       output = 
getIdentifierAttribute(component.instance, output);
+                                       //styleValue += "width:" + 
component.instance.width+ "px;";
+                                       //styleValue += "height:" + 
component.instance.height+ "px;";
+                                       styleValue = 
getSizeString(component.instance as IVisualElement, styleValue, 
isHorizontalSet, isVerticalSet);
+                                       //styleValue += wrapperTagStyles;
+                                       styleValue += "color:" + 
DisplayObjectUtils.getColorInHex(component.instance.getStyle("color"), true) + 
";";
+                                       styleValue += "font-weight:" + 
component.instance.getStyle("fontWeight") + ";";
+                                       styleValue += "font-family:" + 
component.instance.getStyle("fontFamily") + ";";
+                                       styleValue += "font-size:" + 
component.instance.getStyle("fontSize") + "px;";
+                                       styleValue += "line-height:" + "1;";
+                                       //styles += 
getBorderString(component.instance as IStyleClient);
+                                       
+                                       output += properties ? " " : "";
+                                       // remove wrapperTagStyles since we are 
trying to not use wrapper tags
+                                       //output += 
setStyles(component.instance, styleValue+wrapperTagStyles);
+                                       output += setStyles(component.instance, 
wrapperTagStyles+styleValue);
+                                       output += 
getIdentifierOrName(component.instance);
+                                       output += "</label>";
+                                       if (useWrapperDivs) {
+                                               output += 
getWrapperTag(wrapperTag, true);
+                                       }
+                                       /*
+                                       output = tabs + 
getWrapperTag(wrapperTag, false, wrapperTagStyles);
+                                       output += "<" + htmlName.toLowerCase()  
+ " " + properties;
+                                       output = 
getIdentifierAttribute(component.instance, output);
+                                       styleValue = 
getSizeString(component.instance as IVisualElement, styleValue, 
isHorizontalSet);
+                                       output += properties ? " " : "";
+                                       output += setStyles(component.instance, 
styleValue);
+                                       output += getWrapperTag(wrapperTag, 
true);*/
+                               }
+                               
+                               
+                               // add children
+                               if (component.children && 
component.children.length>0) {
+                                       //output += ">\n";
+                                       
+                                       for (var 
i:int;i<component.children.length;i++) {
+                                               componentChild = 
component.children[i];
+                                               
getAppliedPropertiesFromHistory(iDocument, componentChild);
+                                               if (i>0) {
+                                                       childContent += "\n";
+                                               }
+                                               childContent += 
getHTMLOutputString(iDocument, componentChild, false, tabs + "\t");
+                                       }
+                                       
+                                       output = output.replace(contentToken, 
"\n" + childContent);
+
+                               }
+                               else {
+                                       output = output.replace(contentToken, 
"\n");
+                               }
+                       }
+                       else {
+                               output = "";
+                       }
+                       
+                       return output;
+               }
+               
+               /**
+                * Get a tag with less than or greater than wrapped around it. 
+                * */
+               private function getWrapperTag(wrapperTag:String = "", 
end:Boolean = false, styles:String = ""):String {
+                       var output:String = "";
+                       
+                       if (wrapperTag=="") return "";
+                       
+                       if (end) {
+                               output = "</" + wrapperTag + ">";
+                               return output;
+                       }
+                       
+                       output += "<" + wrapperTag;
+                       
+                       if (styles) {
+                               output += " style=\"" + styles + "\"" ;
+                       }
+                       
+                       output += ">";
+                       
+                       return output;
+               }
+               
+               /**
+                * Get width and height styles
+                * If explicit width is set then we should use inline-block 
+                * because inline does not respect width and height
+                * */
+               public function getSizeString(instance:IVisualElement, 
styleValue:String = "", isHorizontalAlignSet:Boolean = false, 
isVerticalSet:Boolean = false):String {
+                       var hasExplicitSize:Boolean;
+                       var hasBorder:Boolean;
+                       var border:int;
+                       
+                       if (instance is IStyleClient && 
IStyleClient(instance).getStyle("borderWeight")) {
+                               
+                       }
+                       
+                       if (!isNaN(instance.percentWidth)) {
+                               styleValue += "width:" + instance.percentWidth 
+ "%;";
+                       }
+                       else if ("explicitWidth" in instance) {
+                               if (Object(instance).explicitWidth!=null && 
!isNaN(Object(instance).explicitWidth)
+                                       || setExplicitSize) {
+                                       styleValue += "width:" + instance.width 
+ "px;";
+                                       hasExplicitSize = true;
+                               }
+                       }
+                       else {
+                               //styleValue += "width:" + instance.width + 
"px;";
+                       }
+                       
+                       if (!isNaN(instance.percentHeight)) {
+                               styleValue += "height:" + 
instance.percentHeight + "%;";
+                       }
+                       else if ("explicitHeight" in instance) {
+                               if (Object(instance).explicitHeight!=null && 
!isNaN(Object(instance).explicitHeight)
+                                       || setExplicitSize) {
+                                       styleValue += "height:" + 
instance.height + "px;";
+                                       hasExplicitSize = true;
+                               }
+                       }
+                       else {
+                               //styleValue += "height:" + instance.height + 
"px;";
+                       }
+                       
+                       
+                       // If explicit width is set then we should use 
inline-block 
+                       // because inline does not respect width and height
+                       if (!isHorizontalAlignSet && hasExplicitSize) {
+                               styleValue += "display:" + Styles.INLINE_BLOCK 
+ ";";
+                       }
+                       
+                       return styleValue;
+                       
+               }
+               
+               /**
+                * Checks if size is explicitly set
+                * If explicit width is set then we should use inline-block 
+                * because inline does not respect width and height
+                * */
+               public function 
hasExplicitSizeSet(instance:IVisualElement):Boolean {
+                       
+                       if ("explicitWidth" in instance && 
Object(instance).explicitWidth!=null) {
+                               return true;
+                       }
+                       else if ("explicitHeight" in instance && 
Object(instance).explicitHeight!=null) {
+                               return true;
+                       }
+                       
+                       return false;
+               }
+                       
+               /**
+                * Get the horizontal position string for HTML
+                * */
+               public function 
getHorizontalPositionHTML(instance:IVisualElement, propertyModel:Styles, 
stylesValue:String = "", isBasicLayout:Boolean = true):String {
+                       
+                       if (!isBasicLayout) return stylesValue;
+                       // horizontal center trumps left and x properties
+                       if (instance.horizontalCenter!=null) {
+                               stylesValue += "display:block;margin:" + 
instance.horizontalCenter + " auto;left:0;right:0;";
+                               //stylesValue = stylesValue.replace("absolute", 
"relative");
+                               
+                               propertyModel.display = Styles.BLOCK;
+                               //propertyModel.position = Styles.RELATIVE;
+                               propertyModel.position = Styles.ABSOLUTE;
+                               propertyModel.margin = 
instance.horizontalCenter + " auto;left:0;right:0;";
+                               
+                               return stylesValue;
+                       }
+                       else if (instance.left!=null || instance.right!=null) {
+                               stylesValue += instance.left!=null ? "left:" + 
instance.left + "px;" : "";
+                               stylesValue += instance.right!=null ? "right:" 
+ instance.right + "px;" : "";
+                               if (instance.left!=null) propertyModel.left = 
instance.left + "px";
+                               if (instance.right!=null) propertyModel.right = 
instance.right + "px";
+                               return stylesValue;
+                       }
+                       else {
+                               stylesValue += "left:" + instance.x + "px;";
+                               propertyModel.left = instance.x + "px;";
+                       }
+                       
+                       return stylesValue;
+               }
+               
+                       
+               /**
+                * Get the vertical position string for HTML
+                * */
+               public function 
getVerticalPositionHTML(instance:IVisualElement, propertyModel:Styles, 
stylesValue:String = "", isBasicLayout:Boolean = true):String {
+                       
+                       if (!isBasicLayout) return stylesValue;
+                       
+                       if (instance.verticalCenter!=null) {
+                               stylesValue += "display:block;margin:" + 
instance.verticalCenter + " auto;";
+                               stylesValue = stylesValue.replace("absolute", 
"relative");
+                               
+                               propertyModel.display = Styles.BLOCK;
+                               propertyModel.position = Styles.RELATIVE;
+                               propertyModel.margin = instance.verticalCenter 
+ " auto;";
+                               
+                               return stylesValue;
+                       }
+                       else if (instance.top!=null || instance.bottom!=null) {
+                               stylesValue += instance.top!=null ? "top:" + 
instance.top + "px;" : "";
+                               stylesValue += instance.bottom!=null ? 
"bottom:" + instance.bottom + "px;" : "";
+                               if (instance.top!=null) propertyModel.top = 
instance.top + "px";
+                               if (instance.bottom!=null) propertyModel.bottom 
= instance.bottom + "px";
+                               return stylesValue;
+                       }
+                       else {
+                               stylesValue += "top:" + instance.y + "px;";
+                               propertyModel.top = instance.y + "px;";
+                       }
+                       
+                       return stylesValue;
+               }
+               
+               /**
+                * Get border and background styles of a border container
+                * */
+               public function getBorderString(element:IStyleClient):String {
+                       var value:String = "";
+                       
+                       if (element.getStyle("backgroundAlpha")!=0) {
+                               value += "background-color:" + 
DisplayObjectUtils.getColorInHex(element.getStyle("backgroundColor"), true) + 
";";
+                               value += "background-alpha:" + 
element.getStyle("backgroundAlpha") + ";";
+                       }
+                       
+                       if (element.getStyle("borderVisible")) {
+                               value += "border-width:" + 
element.getStyle("borderWeight") + "px;";
+                               value += "border-style:solid;";
+                               
+                               if 
(element.getStyle("borderColor")!==undefined) {
+                                       value += "border-color:" + 
DisplayObjectUtils.getColorInHex(element.getStyle("borderColor"), true) + ";";
+                               }
+                       }
+                       
+                       if (element.getStyle("color")!==undefined) {
+                               value += "color:" + 
DisplayObjectUtils.getColorInHex(element.getStyle("color"), true) + ";";
+                       }
+                       
+                       return value;
+               }
+               
+               /**
+                * Set styles
+                * */
+               public function setStyles(component:Object, styles:String = "", 
singleton:Boolean = false):String {
+                       var out:String = ">";
+                       
+                       if (useInlineStyles) {
+                               return " style=\"" + styles + "\"" + 
(singleton?"\>":">");
+                       }
+                       else {
+                               var formatted:String= "\t" + 
styles.replace(/;/g, ";\n\t");
+                               
+                               //styles += ";";
+                               //cssOutput += "#" + 
getIdentifierOrName(component) + "  {\n\n";
+                               //cssOutput += "" + styles.replace(/;/g, ";\n") 
+ "\n\n}  ";
+                               
+                               if (component is String) {
+                                       out = component + " {\n";
+                               }
+                               else {
+                                       out = "#" + 
getIdentifierOrName(component) + "  {\n";
+                               }
+                               out += formatted;
+                               out += "}\n\n";
+                               
+                               out = out.replace(/\t}/g, "}");
+                               
+                               cssOutput += out;
+                       }
+                       
+                       return (singleton?"\>":">");
+               }
+               
+               
+               /**
+                * Wrap in style tags
+                * */
+               public function wrapInStyleTags(value:String):String {
+                       var out:String = "<style>\n" + value + "\n</style>";
+                       return out;
+               }
+               
+               /**
+                * Gets the ID of the target object
+                * 
+                * @param name if id is not available then if the name 
parameter is true then use name
+                * 
+                * returns id or name
+                * */
+               public function getIdentifierOrName(element:Object, 
name:Boolean = true, appendID:String = ""):String {
+
+                       if (element && "id" in element && element.id) {
+                               return element.id + appendID;
+                       }
+                       else if (element && name && "name" in element && 
element.name) {
+                               return element.name + appendID;
+                       }
+                       
+                       return "";
+               }
+               
+               /**
+                * Get ID from ID or else name attribute
+                * */
+               public function getIdentifierAttribute(instance:Object, 
value:String = "", appendID:String = ""):String {
+                       
+                       if (instance && "id" in instance && instance.id) {
+                               value += "id=\"" + instance.id + appendID + 
"\"";
+                       }
+                       
+                       else if (instance && "name" in instance && 
instance.name) {
+                               value += "id=\"" + instance.name + appendID + 
"\"";
+                       }
+                       
+                       return value;
+               }
+               
+               /**
+                * Get name and ID attribute
+                * */
+               public function getIdentifierOrNameAttribute(instance:Object, 
propertyValue:String = ""):String {
+                       
+                       if (instance && "id" in instance && instance.id) {
+                               propertyValue += "id=\"" + instance.id + "\"";
+                       }
+                       
+                       if (instance && "name" in instance && instance.name) {
+                               propertyValue += "name=\"" + instance.name + 
"\"";
+                       }
+                       
+                       return propertyValue;
+               }
+               
+               /**
+                * @inheritDoc
+                * */
+               public function exportXML(document:IDocument, reference:Boolean 
= false):XML {
+                       return null;
+               }
+               
+               /**
+                * @inheritDoc
+                * */
+               public function exportJSON(document:IDocument, 
reference:Boolean = false):JSON {
+                       return null;
+               }
+               
+               /**
+                * Get data URI from object. 
+                * 
+                * Encoding to JPG took 2000ms in some cases where PNG took 
200ms.
+                * I have not extensively tested this but it seems to be 10x 
faster
+                * than JPG. 
+                * */
+               public function getDataURI(target:Object, type:String = 
"png"):String {
+                       var output:String;
+                       
+                       if (type.toLowerCase()=="jpg") {
+                               type = "jpeg";
+                       }
+                       
+                       output = "data:image/" + type + ";base64," + 
getBase64ImageData(target, type);
+                       
+                       return output;
+               }
+               
+               /**
+                * Returns base64 image string.
+                * 
+                * Encoding to JPG took 2000ms in some cases where PNG took 
200ms.
+                * I have not extensively tested this but it seems to be 10x 
faster
+                * than JPG. 
+                * 
+                * Performance: 
+                * get snapshot. time=14
+                * encode to png. time=336 // encode to jpg. time=2000
+                * encode to base 64. time=35
+                * 
+                * Don't trust these numbers. Test it yourself. First runs are 
always longer than previous. 
+                * 
+                * This function gets called multiple times sometimes. We may 
be encoding more than we have too.
+                * But is probably a bug somewhere.  
+                * */
+               public function getBase64ImageData(target:Object, type:String = 
"png", checkCache:Boolean = false):String {
+                       var component:IUIComponent = target as IUIComponent;
+                       var bitmapData:BitmapData;
+                   var byteArray:ByteArray;
+                   var base64Encoder:Base64Encoder;
+                   var base64Encoder2:Base64;
+                       var useEncoder:Boolean;
+                       var rectangle:Rectangle;
+                       var jpegEncoderOptions:JPEGEncoderOptions;
+                       var pngEncoderOptions:PNGEncoderOptions;
+                       var quality:int = 80;
+                       var fastCompression:Boolean = true;
+                       var timeEvents:Boolean = false;
+                       var altBase64:Boolean = true;
+                       var results:String;
+                       
+                       
+                       if (base64BitmapCache[target] && checkCache) {
+                               return base64BitmapCache[target];
+                       }
+                       
+                       if (timeEvents) {
+                               var time:int = getTimer();
+                       }
+                       
+                       if (component) {
+                               bitmapData = BitmapUtil.getSnapshot(component);
+                       }
+                       else if (target is DisplayObject) {
+                               bitmapData = 
DisplayObjectUtils.getBitmapDataSnapshot2(target as DisplayObject);
+                       }
+                       else if (target is BitmapData) {
+                               bitmapData = target as BitmapData;
+                       }
+                       else {
+                               return null;
+                       }
+                       
+                       rectangle = new Rectangle(0, 0, bitmapData.width, 
bitmapData.height);
+                       
+                       if (timeEvents) {
+                               trace ("get snapshot. time=" + 
(getTimer()-time));
+                               time = getTimer();
+                       }
+                       
+                       if (type=="png") {
+                               
+                               if (useEncoder) {
+                                       if (!pngEncoder) {
+                                               pngEncoder = new PNGEncoder();
+                                       }
+                                       
+                                       byteArray = 
pngEncoder.encode(bitmapData);
+                               }
+                               else {
+                                       if (!pngEncoderOptions) {
+                                               pngEncoderOptions = new 
PNGEncoderOptions(fastCompression);
+                                       }
+                                       
+                                       byteArray = 
bitmapData.encode(rectangle, pngEncoderOptions);
+                               }
+                       }
+                       else if (type=="jpg" || type=="jpeg") {
+                               
+                               if (useEncoder) {
+                                       if (!jpegEncoder) {
+                                               jpegEncoder = new JPEGEncoder();
+                                       }
+                                       
+                                       byteArray = 
jpegEncoder.encode(bitmapData);
+                               }
+                               else {
+                                       if (!jpegEncoderOptions) {
+                                               jpegEncoderOptions = new 
JPEGEncoderOptions(quality);
+                                       }
+                                       
+                                       byteArray = 
bitmapData.encode(rectangle, jpegEncoderOptions);
+                               }
+                       }
+                       else {
+                               // raw bitmap image data
+                               byteArray = bitmapData.getPixels(new 
Rectangle(0, 0, bitmapData.width, bitmapData.height));
+                       }
+                       
+                       if (timeEvents) {
+                               trace ("encode to " + type + ". time=" + 
(getTimer()-time));
+                               time = getTimer();
+                       }
+                       
+                       if (!altBase64) {
+                               if (!base64Encoder) {
+                                       base64Encoder = new Base64Encoder();
+                               }
+                               
+                           base64Encoder.encodeBytes(byteArray);
+                       
+                               results = base64Encoder.toString();
+                       }
+                       else {
+                               results = Base64.encode(byteArray);
+                       }
+                       
+                   //trace(base64.toString());
+                       
+                       if (timeEvents) {
+                               trace ("encode to base 64. time=" + 
(getTimer()-time));
+                       }
+                       
+                       base64BitmapCache[target] = results;
+                       
+                       return results;
+               }
+               
+               public var base64BitmapCache:Dictionary = new Dictionary(true)
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/utils/InspectorUtils.as
----------------------------------------------------------------------
diff --git a/Radii8Library/src/com/flexcapacitor/utils/InspectorUtils.as 
b/Radii8Library/src/com/flexcapacitor/utils/InspectorUtils.as
new file mode 100644
index 0000000..ae388ec
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/utils/InspectorUtils.as
@@ -0,0 +1,500 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 com.flexcapacitor.utils {
+       import com.flexcapacitor.controller.Radiate;
+       import com.flexcapacitor.events.InspectorEvent;
+       import com.flexcapacitor.graphics.LayoutLines;
+       import com.flexcapacitor.model.VisualElementVO;
+       
+       import flash.desktop.Clipboard;
+       import flash.desktop.ClipboardFormats;
+       import flash.display.DisplayObject;
+       import flash.display.DisplayObjectContainer;
+       import flash.events.IEventDispatcher;
+       import flash.utils.describeType;
+       import flash.utils.getQualifiedClassName;
+       import flash.utils.getQualifiedSuperclassName;
+       
+       import mx.collections.ArrayCollection;
+       import mx.core.IVisualElement;
+       import mx.core.IVisualElementContainer;
+       import mx.core.UIComponent;
+       import mx.managers.ISystemManager;
+       import mx.utils.NameUtil;
+       import mx.utils.ObjectUtil;
+
+       public class InspectorUtils {
+
+
+               public function InspectorUtils() {
+
+
+               }
+               
+               /**
+                * Get unqualified class name of the target object
+                * */
+               public static function getClassName(element:Object):String {
+                       var name:String = 
NameUtil.getUnqualifiedClassName(element);
+                       return name;
+               }
+               
+               /**
+                * Get unqualified class name of the document of the target 
object
+                * returns null if element is not a UIComponent
+                * */
+               public static function getDocumentName(element:Object):String {
+                       var name:String;
+                       if (element is UIComponent) {
+                               name = 
NameUtil.getUnqualifiedClassName(UIComponent(element).document);
+                       }
+                       return name;
+               }
+               
+               /**
+                * Get the type of the value passed in
+                * */
+               public static function getValueType(value:*):String {
+                       var type:String = getQualifiedClassName(value);
+                       
+                       if (type=="int") {
+                               if (typeof value=="number") {
+                                       type = "Number";
+                               }
+                       }
+                       
+                       return type;
+               }
+               
+               /**
+                * Get package of the target object
+                * */
+               public static function getPackageName(element:Object):String {
+                       var name:String = 
flash.utils.getQualifiedClassName(element);
+                       if (name && name.indexOf("::")) {
+                               name = name.split("::")[0];
+                       }
+                       
+                       return name;
+               }
+
+               /**
+                * Get super class name of the target object
+                * */
+               public static function getSuperClassName(element:Object):String 
{
+                       var name:String = 
flash.utils.getQualifiedSuperclassName(element);
+                       if (name && name.indexOf("::")) {
+                               name = 
name.split("::")[name.split("::").length-1]; // i'm sure theres a better way to 
do this
+                       }
+                       
+                       return name;
+               }
+
+               /**
+                * Get the package of the super class name of the target
+                * */
+               public static function 
getSuperClassPackage(element:Object):String {
+                       var name:String = 
flash.utils.getQualifiedSuperclassName(element);
+                       if (name && name.indexOf("::")) {
+                               name = name.split("::")[0];
+                       }
+                       
+                       return name;
+               }
+               
+               /**
+                * Clears outline drawn around target display object
+                * */
+               public static function clearSelection(target:Object, 
systemManager:ISystemManager, remove:Boolean = false):void {
+                       LayoutLines.getInstance().clear(target, systemManager, 
remove);
+               }
+               
+               /**
+                * Draws outline around target display object
+                * */
+               public static function drawSelection(target:Object, 
systemManager:ISystemManager):void {
+                       throw new Error("CANNOT USE DRAW SELECTION");
+                       //Radiate.drawSelection(target);
+                       /*if (target is DisplayObject) {
+                               LayoutLines.getInstance().drawLines(target, 
systemManager);
+                       }
+                       else if (target!=null) {
+                               trace("Is not displayObject", 
NameUtil.getUnqualifiedClassName(target));
+                       }*/
+               }
+
+               /**
+                * Copy text to clipboard
+                * */
+               public static function copyToClipboard(text:String, 
format:String=ClipboardFormats.TEXT_FORMAT):void {
+                       
Clipboard.generalClipboard.setData(ClipboardFormats.TEXT_FORMAT, text);
+               }
+
+               /**
+                * Returns an array of display objects of type VisualElementVO
+                * Optionally returns elements
+                * */
+               public static function 
getElementChildrenArray(displayObject:DisplayObject, getElements:Boolean = 
false, getSkins:Boolean = true):ArrayCollection {
+                       var displayObject:DisplayObject = 
DisplayObject(displayObject);
+                       var displayObjectContainer:DisplayObjectContainer;
+
+                       var visualElementContainer:IVisualElementContainer;
+                       var visualElement:IVisualElement;
+
+                       var visualElementVO:VisualElementVO = new 
VisualElementVO();
+
+                       var children:ArrayCollection = new ArrayCollection();
+
+
+                       // attempt to cast to a specific type and assign in the 
process
+                       displayObjectContainer = displayObject as 
DisplayObjectContainer;
+                       visualElementContainer = displayObject as 
IVisualElementContainer;
+                       visualElement = displayObject as IVisualElement;
+
+
+                       // gather all the display objects on the current 
display object
+                       if (displayObjectContainer) {
+
+                               for (var bb:int = 0; bb < 
displayObjectContainer.numChildren; bb++) {
+                                       
+                                               // visualElementVO = 
createDisplayObjectVO(displayObjectContainer.getChildAt(bb));
+                                       visualElementVO = 
VisualElementVO.unmarshall(displayObjectContainer.getChildAt(bb));
+                                       children.addItem(visualElementVO);
+                               }
+                       }
+
+                       if (visualElementContainer && getElements) {
+
+                               for (var cc:int = 0; cc < 
visualElementContainer.numElements; cc++) {
+                                               //visualElementVO = 
createDisplayObjectVO(displayObjectContainer.getChildAt(cc));
+                                       visualElementVO = 
VisualElementVO.unmarshall(DisplayObject(visualElementContainer.getElementAt(cc)));
+                                       children.addItem(visualElementVO);
+                               }
+                       }
+
+                       return children;
+               }
+
+
+               /**
+                * Gets the ID of the target object
+                * returns null if no ID is specified or target is not a 
UIComponent
+                * */
+               public static function getIdentifier(element:Object):String {
+                       var id:String;
+
+                       if (element is UIComponent && UIComponent(element).id) {
+                               id = UIComponent(element).id;
+                       }
+                       return id;
+               }
+
+               /**
+                * Get name of target object or null if not available
+                * */
+               public static function getName(element:Object):String {
+                       var name:String;
+
+                       if (element.hasOwnProperty("name") && element.name) {
+                               name = element.name;
+                       }
+
+                       return name;
+               }
+
+               /**
+                * Get qualified class name of the target object
+                * */
+               public static function 
getQualifiedClassName(element:Object):String {
+                       var name:String = 
flash.utils.getQualifiedClassName(element);
+                       return name;
+               }
+
+               /**
+                * With the given target it returns a regexp pattern to find 
the exact instance in MXML
+                * If isScript is true it attempts to returns a pattern to find 
the exact instance in AS3
+                * The MXML pattern will find the instance with that ID. If the 
instance doesn't have an ID it no worky.
+                * NOTE: Press CMD+SHIFT+F to and check regular expression in 
the Find in Files dialog
+                * */
+               public static function 
getRegExpSearchPattern(target:DisplayObject, isScript:Boolean = false):String {
+                       var id:String = getIdentifier(target);
+                       var className:String = 
NameUtil.getUnqualifiedClassName(target);
+                       var pattern:String;
+                       var scriptPattern:String;
+
+                       if (id == null) {
+                               pattern = className + "(.*)";
+                       }
+                       else {
+                               pattern = className + "(.*)id\\s?=\\s?[\"|']" + 
id + "[\"|']";
+                               scriptPattern = id + ".addEventListener";
+                       }
+
+
+                       if (isScript) {
+                               return scriptPattern;
+                       }
+
+                       return pattern;
+               }
+
+
+               /**
+                * Get ancestors of element 
+                * 
+                * @param target
+                * @param collection
+                * @param ancestors
+                * @return
+                */
+               public static function getVisualElementsArray(element:*, 
items:Array, ancestors:int = 0, topMostDisplayObject:Object = null):Array {
+                       var vo:VisualElementVO;
+
+                       // do the worm up the display list
+                       while (element!= null && ancestors>-1)
+                       {
+                               // store display element information
+                               vo = VisualElementVO.unmarshall(element);
+                               
+                               // save reference to display element VO's for 
tree
+                               if (!items) items = new Array();
+                               items.push(vo);
+                               
+                               if ("owner" in element) {
+                                       element = element.owner as 
IVisualElement;
+                               }
+                               
+                               ancestors--;
+                               
+                               if (element==topMostDisplayObject) {
+                                       ancestors = 0; //bail after the next 
run through
+                               }
+                       }
+                       
+                       return items;
+
+               }
+               
+               /**
+                * Get the parent of the target that is also a UIComponent
+                * 
+                * @return
+                */
+               public static function 
getParentUIComponent(target:DisplayObject):UIComponent {
+                       var found:Boolean;
+                       
+                       // run up the display list
+                       while (target) {
+                               target = target.parent;
+                               
+                               // check if next parent exists
+                               if (!target) {
+                                       break;
+                               }
+                               
+                               if (target is UIComponent) {
+                                       found = true;
+                                       break;
+                               }
+                               
+                       }
+                       
+                       if (found) return UIComponent(target);
+                       return null;
+               }
+               
+               /**
+                * Get the name of the target parent that is also a UIComponent
+                * 
+                * @return
+                */
+               public static function 
getParentUIComponentName(target:DisplayObject):String {
+                       var parent:DisplayObject = getParentUIComponent(target);
+                       var className:String = getClassName(parent);
+                       return className;
+               }
+               
+               
+               /**
+                * Get parent document name
+                * 
+                * @return null if target is not a UIComponent
+                */
+               public static function 
getParentDocumentName(target:Object):String {
+                       var className:String;
+                       if (target is UIComponent) {
+                               className = getClassName(target.parentDocument);
+                       }
+                       return className;
+               }
+               
+               
+               /**
+                * Get parent document name
+                * 
+                * @return
+                */
+               public static function 
getClassNameAndPackage(target:Object):Array {
+                       var className:String;
+                       var classPath:String;
+                       
+                       className = getClassName(target);
+                       classPath = getPackageName(target);
+                       
+                       return [className, classPath];
+               }
+               
+               
+               /**
+                * Dispatch target change event
+                * 
+                * @return
+                */
+               public static function dispatchTargetChangeEvent(target:Object, 
source:IEventDispatcher):void {
+                       
+                       // let other inspectors know there is a new target 
selected
+                       var selectionChangeEvent:InspectorEvent = new 
InspectorEvent(InspectorEvent.CHANGE);
+                       selectionChangeEvent.targetItem = target;
+                       
+                       // store previous targets in a dictionary
+                       
+                       if (source) {
+                               source.dispatchEvent(selectionChangeEvent);
+                       }                       
+               }
+               
+               
+               /**
+                * Change target. Use this instead of 
dispatchTargetChangeEvent()
+                * 
+                * TODO: Add a weak reference to the old target in a static 
array for history type navigation
+                * 
+                * @return
+                */
+               public static function updateTarget(target:Object, 
source:IEventDispatcher):void {
+                       // TODO: Add a weak reference to the old target in a 
static array for history type navigation
+                       
+                       // let other inspectors know there is a new target 
selected
+                       var selectionChangeEvent:InspectorEvent = new 
InspectorEvent(InspectorEvent.CHANGE);
+                       selectionChangeEvent.targetItem = target;
+                       
+                       if (source) {
+                               source.dispatchEvent(selectionChangeEvent);
+                       }                       
+               }
+               
+               /**
+                * Converts an integer to hexidecimal. 
+                * For example, 16117809 returns "#EEEEEE" or something
+                * @return
+                */
+               public static function convertIntToHex(item:Object):String {
+                       var hex:String = Number(item).toString(16);
+                       return ("00000" + hex.toUpperCase()).substr(-6);
+               }
+               
+               
+               /**
+                * Sets the property on the target. Supports styles. 
+                * We should probably switch to the set property method 
+                * @return
+                */
+               public static function setTargetProperty(target:Object, 
property:String, value:*, type:String = "String", 
isPropertyStyle:Object=null):void {
+                       var newAssignedValue:* = TypeUtils.getTypedValue(value, 
type);
+                       TypeUtils.applyProperty(target, property, 
newAssignedValue, type, isPropertyStyle);
+               }
+               
+                       
+               /**
+                * @copy spark.components.gridClasses.GridItemEditor#save();
+                */
+               public static function setProperty(target:Object, field:String, 
value:*):Boolean {
+                       
+                       var newData:Object = value;
+                       var property:String = field;
+                       var data:Object = target;
+                       var typeInfo:String = "";
+                       
+                       for each(var variable:XML in 
describeType((data).variable)) {
+                               if (property == variable.@name.toString()) {
+                                       typeInfo = variable.@type.toString();
+                                       break;
+                               }
+                       }
+                       
+                       if (typeInfo == "String") {
+                               if (!(newData is String))
+                                       newData = newData.toString();
+                       }
+                       else if (typeInfo == "uint") {
+                               if (!(newData is uint))
+                                       newData = uint(newData);
+                       }
+                       else if (typeInfo == "int") {
+                               if (!(newData is int))
+                                       newData = int(newData);
+                       }
+                       else if (typeInfo == "Number") {
+                               if (!(newData is Number))
+                                       newData = Number(newData);
+                       }
+                       else if (typeInfo == "Boolean") {
+                               if (!(newData is Boolean)) {
+                                       var strNewData:String = 
newData.toString();
+                                       
+                                       if (strNewData) {
+                                               newData = 
(strNewData.toLowerCase() == "true") ? true : false;
+                                       }
+                               }
+                       }
+                       
+                       if (property && data[property] !== newData) {
+                               data[property] = newData;
+                       }
+                       
+                       return true;
+               }
+               
+               /**
+                *  Returns <code>true</code> if the object reference specified
+                *  is a simple data type. The simple data types include the 
following:
+                *  <ul>
+                *    <li><code>String</code></li>
+                *    <li><code>Number</code></li>
+                *    <li><code>uint</code></li>
+                *    <li><code>int</code></li>
+                *    <li><code>Boolean</code></li>
+                *    <li><code>Date</code></li>
+                *    <li><code>Array</code></li>
+                *  </ul>
+                *
+                *  @param value Object inspected.
+                *
+                *  @return <code>true</code> if the object specified
+                *  is one of the types above; <code>false</code> otherwise.
+                *  */
+               public static function isSimple(value:*):Boolean {
+                       return ObjectUtil.isSimple(value);
+               }
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/utils/MXMLDocumentExporter.as
----------------------------------------------------------------------
diff --git a/Radii8Library/src/com/flexcapacitor/utils/MXMLDocumentExporter.as 
b/Radii8Library/src/com/flexcapacitor/utils/MXMLDocumentExporter.as
new file mode 100644
index 0000000..ff3db5f
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/utils/MXMLDocumentExporter.as
@@ -0,0 +1,170 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 com.flexcapacitor.utils {
+       import com.flexcapacitor.model.IDocument;
+       import com.flexcapacitor.model.IDocumentExporter;
+       import com.flexcapacitor.utils.supportClasses.ComponentDescription;
+       
+       import spark.components.Application;
+       
+       /**
+        * Exports a document to MXML
+        * */
+       public class MXMLDocumentExporter extends DocumentExporter implements 
IDocumentExporter {
+               
+               public function MXMLDocumentExporter() {
+               
+               }
+               
+               /**
+                * @inheritDoc
+                * */
+               public function export(iDocument:IDocument, 
target:ComponentDescription = null, reference:Boolean = false):* {
+                       var output:String;
+                       var XML1:XML;
+                       
+                       if (!target) {
+                               target = iDocument.componentDescription;
+                       }
+                       
+                       if (!reference) {
+                               output = getMXMLOutputString(iDocument, target);
+                       }
+                       else {
+                               XML1 = <document />;
+                               XML1.@host = iDocument.host;
+                               XML1.@id = iDocument.id;
+                               XML1.@name = iDocument.name;
+                               XML1.@uid = iDocument.uid;
+                               XML1.@uri = iDocument.uri;
+                               output = XML1.toXMLString();
+                       }
+                       
+                       return output;
+               }
+               
+               /**
+                * @inheritDoc
+                * */
+               public function exportXML(document:IDocument, reference:Boolean 
= false):XML {
+                       return null;
+               }
+               
+               /**
+                * @inheritDoc
+                * */
+               public function exportJSON(document:IDocument, 
reference:Boolean = false):JSON {
+                       return null;
+               }
+               
+       
+               /**
+                * Gets the formatted MXML output from a component. 
+                * TODO: This should be using XML and namespaces. 
+                * */
+               public function getMXMLOutputString(iDocument:IDocument, 
component:ComponentDescription, addLineBreak:Boolean = false, tabs:String = 
""):String {
+                       if (component.instance is Application) {
+                               getAppliedPropertiesFromHistory(iDocument, 
component);
+                       }
+                       var properties:Object = component.properties;
+                       var styles:Object = component.styles;
+                       var componentChild:ComponentDescription;
+                       var name:String = component.name;
+                       var output:String = "";
+                       var outputValue:String = "";
+                       var namespaces:String;
+                       var value:*;
+                       
+                       
+                       for (var propertyName:String in properties) {
+                               value = properties[propertyName];
+                               if (value===undefined || value==null) {
+                                       continue;
+                               }
+                               output += " ";
+                               
+                               // we should be converting objects into tags
+                               if (value is Object) {
+                                       outputValue = 
XMLUtils.getAttributeSafeString(Object(value).toString());
+                                       output += propertyName + "=\"" + 
outputValue + "\"";
+                                       
+                               }
+                               else {
+                                       output += propertyName + "=\"" + 
XMLUtils.getAttributeSafeString(Object(value).toString()) + "\"";
+                               }
+                       }
+                       
+                       for (var styleName:String in styles) {
+                               value = styles[styleName];
+                               if (value===undefined || value==null) {
+                                       continue;
+                               }
+                               output += " ";
+                               output += styleName + "=\"" + 
XMLUtils.getAttributeSafeString(Object(styles[styleName]).toString()) + "\"";
+                       }
+                       
+                       if (name) {
+                               if (component.instance is Application) {
+                                       name = "Application";
+                                       namespaces = " 
xmlns:fx=\"http://ns.adobe.com/mxml/2009\"";;
+                                       namespaces += " 
xmlns:s=\"library://ns.adobe.com/flex/spark\"";
+                                       output = namespaces + output;
+                               }
+                               // we are not handling namespaces here - we 
could use component descriptor
+                               output = tabs + "<s:" + name + output;
+                               
+                               if (component.children && 
component.children.length>0) {
+                                       output += ">\n";
+                                       
+                                       for (var 
i:int;i<component.children.length;i++) {
+                                               componentChild = 
component.children[i];
+                                               // we should get the properties 
and styles from the 
+                                               // the component description
+                                               
getAppliedPropertiesFromHistory(iDocument, componentChild);
+                                               output += 
getMXMLOutputString(iDocument, componentChild, false, tabs + "\t");
+                                       }
+                                       
+                                       output += tabs + "</s:" + name + ">\n";
+                               }
+                               else {
+                                        output += "/>\n";
+                               }
+                       }
+                       else {
+                               output = "";
+                       }
+                       
+                       isValid = XMLUtils.isValidXML(output);
+                       
+                       if (!isValid) {
+                               error = XMLUtils.validationError;
+                               errorMessage = XMLUtils.validationErrorMessage;
+                       }
+                       else {
+                               error = null;
+                               errorMessage = null;
+                       }
+                       
+                       return output;
+               }
+               
+       
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/utils/MXMLDocumentImporter.as
----------------------------------------------------------------------
diff --git a/Radii8Library/src/com/flexcapacitor/utils/MXMLDocumentImporter.as 
b/Radii8Library/src/com/flexcapacitor/utils/MXMLDocumentImporter.as
new file mode 100644
index 0000000..c48992c
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/utils/MXMLDocumentImporter.as
@@ -0,0 +1,143 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 com.flexcapacitor.utils {
+       
+       import com.flexcapacitor.controller.Radiate;
+       import com.flexcapacitor.model.IDocument;
+       import com.flexcapacitor.utils.supportClasses.ComponentDefinition;
+       
+       import flash.events.EventDispatcher;
+       import flash.system.ApplicationDomain;
+       import flash.utils.getTimer;
+       
+       import mx.core.IVisualElement;
+
+       
+       /**
+        * Import MXML into a IDocument. Basic support of creating components 
and apply properties and styles. 
+        * */
+       public class MXMLDocumentImporter extends EventDispatcher {
+       
+               public var document:IDocument;
+
+               /**
+                * Import the MXML document into the IDocument. 
+                * */
+               public function MXMLDocumentImporter(iDocument:IDocument, 
id:String, mxml:XML, container:IVisualElement) {
+                       document = iDocument;
+                       
+                       var elName:String = mxml.localName();
+                       var timer:int = getTimer(); 
+                       
+                       Radiate.importingDocument = true;
+                       
+                       // TODO this is a special case we check for since 
+                       // we should have already created the application by now
+                       // we should handle this case before we get here (pass 
in the children of the application xml not application itself)
+                       if (elName=="Application") {
+                               
Radiate.setAttributesOnComponent(document.instance, mxml);
+                       }
+                       else {
+                               createChildFromNode(mxml, container);
+                       }
+                       
+                       
+                       for each (var childNode:XML in mxml.children()) {
+                               createChildFromNode(childNode, container);
+                       }
+                       
+                       Radiate.importingDocument = false;
+                       
+                       // using importing document flag it goes down from 5 
seconds to 1 second
+                       //Radiate.log.info("Time to import: " + 
(getTimer()-timer));
+                       
+               }
+
+               /**
+                * Create child from node
+                * */
+               private function createChildFromNode(node:XML, 
parent:Object):IVisualElement {
+                       var elementName:String = node.localName();
+                       var domain:ApplicationDomain = 
ApplicationDomain.currentDomain;
+                       var componentDefinition:ComponentDefinition = 
Radiate.getDynamicComponentType(elementName);
+                       var className:String;
+                       var classType:Class;
+                       var includeChildren:Boolean = true;
+                       var instance:Object;
+                       
+                       if (componentDefinition==null) {
+                               
+                       }
+                       
+                       className =componentDefinition ? 
componentDefinition.className :null;
+                       classType = componentDefinition ? 
componentDefinition.classType as Class :null;
+                       
+                       
+                       if (componentDefinition==null && 
elementName!="RootWrapperNode") {
+                               //message += " Add this class to 
Radii8LibrarySparkAssets.sparkManifestDefaults or add the library to the 
project that contains it.";
+                               var message:String = "Could not find definition 
for " + elementName + ". The document will be missing elements.";
+                               Radiate.log.error(message);
+                               return null;
+                       }
+                       
+                       // classes to look into for decoding XML
+                       // XMLDecoder, SchemaTypeRegistry, SchemaManager, 
SchemaProcesser
+                       
+                       
+                       // special case for radio button group
+                       /*var object:* = 
SchemaTypeRegistry.getInstance().getClass(classType);
+                       var object2:* = 
SchemaTypeRegistry.getInstance().getClass(elementName);
+                       var object3:* = 
SchemaTypeRegistry.getInstance().getClass(node);
+                       var sm:mx.rpc.xml.SchemaManager = new 
mx.rpc.xml.SchemaManager();
+                       
+                       sm.addNamespaces({s:new Namespace("s", 
"library://ns.adobe.com/flex/spark")});
+                       var o:Object = sm.unmarshall(node);
+                       
+                       var q:QName = new QName(null, elementName);*/
+                       //var object2:* = 
SchemaTypeRegistry.getInstance().registerClass(;
+                       
+       
+                       if (componentDefinition!=null) {
+                               instance = 
Radiate.createComponentForAdd(document, componentDefinition, true);
+                               //Radiate.log.info("MXML Importer adding: " + 
elementName);
+                               
+                               // calling add before setting properties 
because some 
+                               // properties such as borderVisible need to be 
set after 
+                               // the component is added (maybe)
+                               Radiate.addElement(instance, parent);
+                               
+                               Radiate.setAttributesOnComponent(instance, 
node);
+                               
+                       }
+                       
+                       
+                       if (includeChildren) {
+                               
+                               for each (var childNode:XML in node.children()) 
{
+                                       createChildFromNode(childNode, 
instance);
+                               }
+                       }
+                       
+                       return instance as IVisualElement;
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/utils/MXMLImporterEvent.as
----------------------------------------------------------------------
diff --git a/Radii8Library/src/com/flexcapacitor/utils/MXMLImporterEvent.as 
b/Radii8Library/src/com/flexcapacitor/utils/MXMLImporterEvent.as
new file mode 100644
index 0000000..e4cdc02
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/utils/MXMLImporterEvent.as
@@ -0,0 +1,37 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 com.flexcapacitor.utils
+{
+       import flash.events.Event;
+       
+
+       public class MXMLImporterEvent extends Event 
+       {
+               
+               public static var INITIALIZE:String = "onInitialize";
+               public var idString : String;
+
+               public function MXMLImporterEvent(type : String, indata:String, 
bubbles : Boolean = false, cancelable : Boolean = false)
+               {
+                       super( type, bubbles, cancelable );
+                       idString = indata;
+               }
+       }       
+
+}
\ No newline at end of file

Reply via email to