/*
 *
 *  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 org.apache.royale.compiler.internal.codegen.mxml.royale;


import java.io.File;
import java.io.FilterWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Stack;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.royale.abc.ABCConstants;
import org.apache.royale.abc.instructionlist.InstructionList;
import org.apache.royale.abc.semantics.Instruction;
import org.apache.royale.abc.semantics.Name;
import org.apache.royale.abc.semantics.Namespace;
import org.apache.royale.abc.semantics.OneOperandInstruction;
import org.apache.royale.compiler.codegen.ISubEmitter;
import org.apache.royale.compiler.codegen.as.IASEmitter;
import org.apache.royale.compiler.codegen.js.IJSEmitter;
import org.apache.royale.compiler.codegen.mxml.js.IMXMLJSEmitter;
import org.apache.royale.compiler.codegen.mxml.royale.IMXMLRoyaleEmitter;
import org.apache.royale.compiler.common.ASModifier;
import org.apache.royale.compiler.common.DependencyType;
import org.apache.royale.compiler.common.ISourceLocation;
import org.apache.royale.compiler.constants.IASKeywordConstants;
import org.apache.royale.compiler.constants.IASLanguageConstants;
import org.apache.royale.compiler.definitions.IClassDefinition;
import org.apache.royale.compiler.definitions.IDefinition;
import org.apache.royale.compiler.definitions.INamespaceDefinition;
import org.apache.royale.compiler.definitions.ITypeDefinition;
import org.apache.royale.compiler.internal.as.codegen.InstructionListNode;
import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
import org.apache.royale.compiler.internal.codegen.databinding.BindingDatabase;
import org.apache.royale.compiler.internal.codegen.databinding.BindingInfo;
import org.apache.royale.compiler.internal.codegen.databinding.FunctionWatcherInfo;
import org.apache.royale.compiler.internal.codegen.databinding.PropertyWatcherInfo;
import org.apache.royale.compiler.internal.codegen.databinding.StaticPropertyWatcherInfo;
import org.apache.royale.compiler.internal.codegen.databinding.WatcherInfoBase;
import org.apache.royale.compiler.internal.codegen.databinding.WatcherInfoBase.WatcherType;
import org.apache.royale.compiler.internal.codegen.databinding.XMLWatcherInfo;
import org.apache.royale.compiler.internal.codegen.js.JSEmitterTokens;
import org.apache.royale.compiler.internal.codegen.js.JSSessionModel.PropertyNodes;
import org.apache.royale.compiler.internal.codegen.js.JSSessionModel.BindableVarInfo;
import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitter;
import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitterTokens;
import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleBasicMXMLDescriptorEmitter;
import org.apache.royale.compiler.internal.codegen.js.goog.JSGoogDocEmitter;
import org.apache.royale.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
import org.apache.royale.compiler.internal.codegen.js.jx.BindableEmitter;
import org.apache.royale.compiler.internal.codegen.js.jx.PackageFooterEmitter;
import org.apache.royale.compiler.internal.codegen.js.utils.EmitterUtils;
import org.apache.royale.compiler.internal.codegen.mxml.MXMLEmitter;
import org.apache.royale.compiler.internal.driver.js.royale.JSCSSCompilationSession;
import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
import org.apache.royale.compiler.internal.projects.RoyaleProject;
import org.apache.royale.compiler.internal.scopes.ASProjectScope;
import org.apache.royale.compiler.internal.targets.ITargetAttributes;
import org.apache.royale.compiler.internal.tree.as.FunctionCallNode;
import org.apache.royale.compiler.internal.tree.as.IdentifierNode;
import org.apache.royale.compiler.internal.tree.as.MemberAccessExpressionNode;
import org.apache.royale.compiler.internal.tree.as.VariableNode;
import org.apache.royale.compiler.internal.tree.mxml.MXMLDocumentNode;
import org.apache.royale.compiler.internal.tree.mxml.MXMLFileNode;
import org.apache.royale.compiler.internal.tree.mxml.MXMLFunctionNode;
import org.apache.royale.compiler.internal.tree.mxml.MXMLBindingNode;
import org.apache.royale.compiler.mxml.IMXMLLanguageConstants;
import org.apache.royale.compiler.problems.FileNotFoundProblem;
import org.apache.royale.compiler.projects.ICompilerProject;
import org.apache.royale.compiler.projects.IRoyaleProject;
import org.apache.royale.compiler.scopes.IDefinitionSet;
import org.apache.royale.compiler.tree.ASTNodeID;
import org.apache.royale.compiler.tree.as.*;
import org.apache.royale.compiler.tree.metadata.IMetaTagNode;
import org.apache.royale.compiler.tree.metadata.IMetaTagsNode;
import org.apache.royale.compiler.tree.mxml.*;
import org.apache.royale.compiler.units.ICompilationUnit;
import org.apache.royale.compiler.utils.NativeUtils;
import org.apache.royale.compiler.visitor.mxml.IMXMLBlockWalker;
import org.apache.royale.swc.ISWC;

import com.google.common.base.Joiner;
import com.google.common.io.Files;
import com.google.debugging.sourcemap.FilePosition;

/**
 * @author Erik de Bruin
 */
public class MXMLRoyaleEmitter extends MXMLEmitter implements
        IMXMLRoyaleEmitter, IMXMLJSEmitter
{

	// the instances in a container
    private ArrayList<MXMLDescriptorSpecifier> currentInstances;
    private ArrayList<MXMLDescriptorSpecifier> currentPropertySpecifiers;
    private ArrayList<MXMLDescriptorSpecifier> descriptorTree;
    private MXMLDescriptorSpecifier propertiesTree;
    private MXMLDescriptorSpecifier currentStateOverrides;
    private ArrayList<MXMLEventSpecifier> events;
    // all instances in the current document or subdocument
    private ArrayList<MXMLDescriptorSpecifier> instances;
    // all instances in the document AND its subdocuments
    private ArrayList<MXMLDescriptorSpecifier> allInstances = new ArrayList<MXMLDescriptorSpecifier>();
    private ArrayList<IMXMLScriptNode> scripts;
    //private ArrayList<MXMLStyleSpecifier> styles;
    private IClassDefinition classDefinition;
    private IClassDefinition documentDefinition;
    private ArrayList<String> usedNames = new ArrayList<String>();
    private ArrayList<String> staticUsedNames = new ArrayList<String>();
    private ArrayList<IMXMLMetadataNode> metadataNodes = new ArrayList<IMXMLMetadataNode>();
    // separately track all fx:Declarations that are primitive types (fx:String, fx:Array)
    private ArrayList<IMXMLInstanceNode> primitiveDeclarationNodes = new ArrayList<IMXMLInstanceNode>();

    private int eventCounter;
    private int idCounter;
    private int bindingCounter;

    private boolean inMXMLContent;
    private IMXMLInstanceNode overrideInstanceToEmit;
    private Stack<IMXMLStateNode> inStatesOverride = new Stack<IMXMLStateNode>();
    private boolean makingSimpleArray;
    private boolean inStaticInitializer;

    private StringBuilder subDocuments = new StringBuilder();
    private ArrayList<String> subDocumentNames = new ArrayList<String>();
    private String interfaceList;
    private boolean emitExports = true;

    private ISubEmitter<MXMLDescriptorSpecifier> mxmlDescriptorEmitter;

    /**
     * This keeps track of the entries in our temporary array of
     * DeferredInstanceFromFunction objects that we CG to help with
     * State override CG.
     *
     * Keys are Instance nodes,
     * values are the array index where the deferred instance is:
     *
     *  deferred instance = local3[ nodeToIndexMap.get(an instance) ]
     */
    protected Map<IMXMLNode, Integer> nodeToIndexMap;

    private SourceMapMapping lastMapping;

    private List<SourceMapMapping> sourceMapMappings;

    public List<SourceMapMapping> getSourceMapMappings()
    {
        return sourceMapMappings;
    }

    public MXMLRoyaleEmitter(FilterWriter out)
    {
        super(out);
        sourceMapMappings = new ArrayList<SourceMapMapping>();

        mxmlDescriptorEmitter = new JSRoyaleBasicMXMLDescriptorEmitter(this);
    }

    @Override
    public String postProcess(String output)
    {
        IASEmitter asEmitter = ((IMXMLBlockWalker) getMXMLWalker()).getASEmitter();
        ArrayList<String> asEmitterUsedNames = ((JSRoyaleEmitter)asEmitter).usedNames;
        JSRoyaleEmitter fjs = (JSRoyaleEmitter)asEmitter;

        String currentClassName = fjs.getModel().getCurrentClass().getQualifiedName();
        ArrayList<String> removals = new ArrayList<String>();
        for (String usedName : asEmitterUsedNames) {
            //remove any internal component that has been registered with the other emitter's usedNames
            if (usedName.startsWith(currentClassName+".") && subDocumentNames.contains(usedName.substring(currentClassName.length()+1))) {
                removals.add(usedName);
            }
        }
        for (String usedName : removals)
        {
        	asEmitterUsedNames.remove(usedName);
        }
        RoyaleJSProject fjp = (RoyaleJSProject) getMXMLWalker().getProject();
        if (fjp.config == null || fjp.config.isVerbose())
        {
            System.out.println(currentClassName + " as: " + asEmitterUsedNames.toString());
            System.out.println(currentClassName + " mxml: " + usedNames.toString());
        }
        usedNames.addAll(asEmitterUsedNames);
        
        ArrayList<String> asStaticEmitterUsedNames = ((JSRoyaleEmitter)asEmitter).staticUsedNames;
        removals = new ArrayList<String>();
        for (String usedName : asStaticEmitterUsedNames) {
            //remove any internal component that has been registered with the other emitter's usedNames
            if (usedName.startsWith(currentClassName+".") && subDocumentNames.contains(usedName.substring(currentClassName.length()+1))) {
                removals.add(usedName);
            }
        }
        for (String usedName : removals)
        {
        	asStaticEmitterUsedNames.remove(usedName);
        }
        if (fjp.config == null || fjp.config.isVerbose())
        {
            System.out.println(currentClassName + " as: " + asStaticEmitterUsedNames.toString());
            System.out.println(currentClassName + " mxml: " + staticUsedNames.toString());
        }
        staticUsedNames.addAll(asStaticEmitterUsedNames);
        

        boolean foundXML = false;
    	String[] lines = output.split("\n");
    	ArrayList<String> finalLines = new ArrayList<String>();
    	int endRequires = -1;
    	boolean sawRequires = false;
    	boolean stillSearching = true;
        int provideIndex = -1;
        ArrayList<String> namesToAdd = new ArrayList<String>();
        ArrayList<String> foundRequires = new ArrayList<String>();
        int len = lines.length;
        for (int i = 0; i < len; i++)
        {
            String line = lines[i];
    		if (stillSearching)
    		{
                if (provideIndex == -1 || !sawRequires)
                {
                    int c = line.indexOf(JSGoogEmitterTokens.GOOG_PROVIDE.getToken());
                    if (c != -1)
                    {
                        // if zero requires are found, require Language after the
                        // call to goog.provide
                        provideIndex = i + 1;
                    }
                }
	            int c = line.indexOf(JSGoogEmitterTokens.GOOG_REQUIRE.getToken());
	            if (c > -1)
	            {
	                int c2 = line.indexOf(")");
	                String s = line.substring(c + 14, c2 - 1);
                    if (s.equals(IASLanguageConstants.XML))
                    {
                        foundXML = true;
                    }
	    			sawRequires = true;
                    foundRequires.add(s);
	    			if (!usedNames.contains(s))
                    {
                        removeLineFromMappings(i);
                        continue;
                    }
	    		}
	    		else if (sawRequires)
	    		{
	    	    	// append info() structure if main CU
	    	        ICompilerProject project = getMXMLWalker().getProject();
    	            RoyaleJSProject royaleProject = null;
	    	        if (project instanceof RoyaleJSProject)
	    	            royaleProject = (RoyaleJSProject) project;

	    			stillSearching = false;
                    for (String usedName :usedNames) {
                        if (!foundRequires.contains(usedName)) {
                            if (usedName.equals(classDefinition.getQualifiedName())) continue;
                            if (((JSRoyaleEmitter) asEmitter).getModel().isInternalClass(usedName)) continue;
                            if (subDocumentNames.contains(usedName)) continue;
                            if (royaleProject != null)
                            {
                                if (!isGoogProvided(usedName))
                                {
                                    continue;
                                }
                            	ICompilationUnit cu = royaleProject.resolveQNameToCompilationUnit(usedName);
                                if (cu == null)
                                {
                                    System.out.println("didn't find CompilationUnit for " + usedName);
                                }
                            }
                            namesToAdd.add(usedName);
                        }
                    }

                    for (String nameToAdd : namesToAdd) {
                        finalLines.add(createRequireLine(nameToAdd,false));
                        addLineToMappings(i);
                    }

	    			endRequires = finalLines.size();
	    		}
    		}
    		finalLines.add(line);
    	}
        boolean needXML = ((RoyaleJSProject)(((IMXMLBlockWalker) getMXMLWalker()).getProject())).needXML;
        if (needXML && !foundXML)
        {
            StringBuilder appendString = new StringBuilder();
            appendString.append(JSGoogEmitterTokens.GOOG_REQUIRE.getToken());
            appendString.append(ASEmitterTokens.PAREN_OPEN.getToken());
            appendString.append(ASEmitterTokens.SINGLE_QUOTE.getToken());
            appendString.append(IASLanguageConstants.XML);
            appendString.append(ASEmitterTokens.SINGLE_QUOTE.getToken());
            appendString.append(ASEmitterTokens.PAREN_CLOSE.getToken());
            appendString.append(ASEmitterTokens.SEMICOLON.getToken());
            finalLines.add(endRequires, appendString.toString());
            addLineToMappings(endRequires);
            endRequires++;
        }
    	// append info() structure if main CU
        ICompilerProject project = getMXMLWalker().getProject();
        if (project instanceof RoyaleJSProject)
        {
            RoyaleJSProject royaleProject = (RoyaleJSProject) project;
        	if (royaleProject.mainCU != null)
        	{
	            String mainDef = null;
				try {
					mainDef = royaleProject.mainCU.getQualifiedNames().get(0);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
	            String thisDef = documentDefinition.getQualifiedName();
	            if (mainDef != null && mainDef.equals(thisDef))
	            {
	            	String infoInject = "\n\n" + thisDef + ".prototype.info = function() {\n" +
					"  return { ";
	            	String sep = "";
	            	Set<String> mixins = royaleProject.mixinClassNames;
	            	if (mixins.size() > 0)
	            	{
		            	String mixinInject = "\"mixins\": [";
		            	boolean firstOne = true;
		            	for (String mixin : mixins)
		            	{
                            if (!isGoogProvided(mixin))
                            {
                                continue;
                            }
                            if (!firstOne)
                            {
                                mixinInject += ", ";
                            }
		            		mixinInject += mixin;
		            		firstOne = false;
		                    StringBuilder appendString = new StringBuilder();
		                    appendString.append(JSGoogEmitterTokens.GOOG_REQUIRE.getToken());
		                    appendString.append(ASEmitterTokens.PAREN_OPEN.getToken());
		                    appendString.append(ASEmitterTokens.SINGLE_QUOTE.getToken());
		                    appendString.append(mixin);
		                    appendString.append(ASEmitterTokens.SINGLE_QUOTE.getToken());
		                    appendString.append(ASEmitterTokens.PAREN_CLOSE.getToken());
		                    appendString.append(ASEmitterTokens.SEMICOLON.getToken());
	                        finalLines.add(endRequires, appendString.toString());
	                        addLineToMappings(endRequires);
                            endRequires++;
		            	}
		            	mixinInject += "]";
		            	infoInject += mixinInject;
		            	sep = ",\n";
	            	}
	            	Map<String, String> aliases = royaleProject.remoteClassAliasMap;
	            	if (aliases != null && aliases.size() > 0)
	            	{
		            	String aliasInject = sep + "\"remoteClassAliases\": {";
		            	boolean firstOne = true;
		            	for (String className : aliases.keySet())
		            	{
                            if (!isGoogProvided(className))
                            {
                                continue;
                            }
                            if (!firstOne)
                            {
                                aliasInject += ", ";
                            }
		            		aliasInject += "\"" + className + "\": ";
		            		String alias = aliases.get(className);
		            		aliasInject += "\"" + alias + "\"";
		            		firstOne = false;
		                    StringBuilder appendString = new StringBuilder();
		                    appendString.append(JSGoogEmitterTokens.GOOG_REQUIRE.getToken());
		                    appendString.append(ASEmitterTokens.PAREN_OPEN.getToken());
		                    appendString.append(ASEmitterTokens.SINGLE_QUOTE.getToken());
		                    appendString.append(className);
		                    appendString.append(ASEmitterTokens.SINGLE_QUOTE.getToken());
		                    appendString.append(ASEmitterTokens.PAREN_CLOSE.getToken());
		                    appendString.append(ASEmitterTokens.SEMICOLON.getToken());
	                        finalLines.add(endRequires, appendString.toString());
	                        addLineToMappings(endRequires);
                            endRequires++;
		            	}
		            	aliasInject += "}";
		            	infoInject += aliasInject;
		            	sep = ",\n";
	            	}
	                Collection<String> locales = royaleProject.getLocales();
	                if (locales.size() > 0)
	                {
		            	String localeInject = sep + "\"compiledLocales\": [";
		            	boolean firstOne = true;
		            	String[] localeNames = new String[locales.size()];
		            	locales.toArray(localeNames);
		            	for (String locale : localeNames)
		            	{
                            if (!firstOne)
                            {
                                localeInject += ", ";
                            }
		            		localeInject += "\"" + locale + "\"";
		            		firstOne = false;
		            	}
		            	localeInject += "]";
		            	infoInject += localeInject;
		            	sep = ",\n";

	                }
	                List<String> bundles = royaleProject.compiledResourceBundleNames;
	                if (bundles.size() > 0)
	                {
		            	String bundleInject = sep + "\"compiledResourceBundleNames\": [";
		            	boolean firstOne = true;
		            	for (String bundle : bundles)
		            	{
                            if (!firstOne)
                            {
                                bundleInject += ", ";
                            }
		            		bundleInject += "\"" + bundle + "\"";
		            		firstOne = false;
		            	}
		            	bundleInject += "]";
		            	infoInject += bundleInject;
		            	sep = ",\n";

	                }
	                List<String> bundleClasses = royaleProject.compiledResourceBundleClasses;
	                if (bundles.size() > 0)
	                {
		            	for (String bundleClass : bundleClasses)
		            	{
		                    StringBuilder appendString = new StringBuilder();
		                    appendString.append(JSGoogEmitterTokens.GOOG_REQUIRE.getToken());
		                    appendString.append(ASEmitterTokens.PAREN_OPEN.getToken());
		                    appendString.append(ASEmitterTokens.SINGLE_QUOTE.getToken());
		                    appendString.append(bundleClass);
		                    appendString.append(ASEmitterTokens.SINGLE_QUOTE.getToken());
		                    appendString.append(ASEmitterTokens.PAREN_CLOSE.getToken());
		                    appendString.append(ASEmitterTokens.SEMICOLON.getToken());
	                        finalLines.add(endRequires, appendString.toString());
	                        addLineToMappings(endRequires);
                            endRequires++;
		            	}
	                }
	            	boolean isMX = false;
	            	List<ISWC> swcs = royaleProject.getLibraries();
	            	for (ISWC swc : swcs)
	            	{
	            		if (swc.getSWCFile().getName().equalsIgnoreCase("MX.swc"))
	            		{
	            			isMX = true;
	            			break;
	            		}
	            	}
	            	if (isMX)
	            	{
	            		MXMLDocumentNode mxmlDoc = (MXMLDocumentNode)documentDefinition.getNode();
	            		if (mxmlDoc != null)
	            		{
	            			MXMLFileNode mxmlFile = (MXMLFileNode)mxmlDoc.getParent();
	            			if (mxmlFile != null)
	            			{
	            				ITargetAttributes attrs = mxmlFile.getTargetAttributes(royaleProject);
	            				if (attrs != null && attrs.getUsePreloader() != null)
	            				{
	            					String preloaderInject = sep + IMXMLLanguageConstants.ATTRIBUTE_USE_PRELOADER + ": ";
	            					preloaderInject += attrs.getUsePreloader() == Boolean.TRUE ? "true" : "false";
	        		            	sep = ",\n";
	        		            	infoInject += preloaderInject;
	            				}
	            			}
	            		}
	            	}
	            	String contextRoot = royaleProject.getServciesContextRoot();
	            	if (contextRoot != null)
	            	{
    					String contextInject = sep + "\"contextRoot\"" + ": ";
    					contextInject += "'" + contextRoot.trim() + "'";
		            	sep = ",\n";
		            	infoInject += contextInject;
	            	}
	            	String servicesPath = royaleProject.getServicesXMLPath();
	            	if (servicesPath != null)
	            	{
	            		File servicesFile = new File(servicesPath);
	            		if (!servicesFile.exists())
	            		{
	            			FileNotFoundProblem prob = new FileNotFoundProblem(servicesPath);
	            			royaleProject.getProblems().add(prob);
	            		}
	            		else
	            		{
	            			// should use XML parser to skip over comments
	            			// but this will work for now
	            	        List<String> fileLines = null;
	            			try {
	            				fileLines = Files.readLines(new File(servicesPath), Charset.forName("utf8"));
	            			} catch (IOException e) {
	            				// TODO Auto-generated catch block
	            				e.printStackTrace();
	            			}
	            			StringBuffer sb = new StringBuffer();
	            			boolean inComment = false;
	            			boolean inChannels = false;
	            			for (String s : fileLines)
	            			{
	            	    		s = s.trim();
	            	    		if (s.contains("<!--"))
	            	    		{
	            	    			if (!s.contains("-->"))
	            	    				inComment = true;
	            	    			continue;
	            	    		}
	            	    		if (inComment)
	            	    		{
	            	    			if (s.contains("-->"))
	            	    				inComment = false;
	            	    			continue;
	            	    		}
	            				if (s.contains("service-include"))
	            				{
	            					int c = s.indexOf("file-path");
	            					c = s.indexOf("\"", c);
	            					int c2 = s.indexOf("\"", c + 1);
	            					String filePath = s.substring(c + 1, c2);
	            					File subFile = new File(servicesFile.getParentFile(), filePath);
	    	            	        List<String> subfileLines;
	    	            			try {
	    	            				subfileLines = Files.readLines(subFile, Charset.forName("utf8"));
		    	            			s = getSubFileContent(subfileLines);
		    	            			sb.append(s);
	    	            			} catch (IOException e) {
	    	            				// TODO Auto-generated catch block
	    	            				e.printStackTrace();
	    	            			}
	            				}
	            				else 
	            				{
	            					sb.append(s + " ");
	            					if (s.contains("<channel-definition"))
	            						inChannels = true;
	            					if (s.contains("<endpoint"))
	            						inChannels = false;
	            					if (inChannels && s.contains("class"))
	            					{
		            					int c = s.indexOf("class");
		            					c = s.indexOf("\"", c);
		            					int c2 = s.indexOf("\"", c + 1);
		            					String className = s.substring(c + 1, c2);
		    		                    StringBuilder appendString = new StringBuilder();
		    		                    appendString.append(JSGoogEmitterTokens.GOOG_REQUIRE.getToken());
		    		                    appendString.append(ASEmitterTokens.PAREN_OPEN.getToken());
		    		                    appendString.append(ASEmitterTokens.SINGLE_QUOTE.getToken());
		    		                    appendString.append(className);
		    		                    appendString.append(ASEmitterTokens.SINGLE_QUOTE.getToken());
		    		                    appendString.append(ASEmitterTokens.PAREN_CLOSE.getToken());
		    		                    appendString.append(ASEmitterTokens.SEMICOLON.getToken());
		    	                        finalLines.add(endRequires, appendString.toString());
		    	                        addLineToMappings(endRequires);
		                                endRequires++;
	            					}
	            				}
	            			}
        					String servicesInject = sep + "\"servicesConfig\"" + ": ";
        					servicesInject += "'" + sb.toString().trim() + "'";
    		            	sep = ",\n";
    		            	infoInject += servicesInject;

	            		}
	            	}
	            	infoInject += "}};";
                    finalLines.add(infoInject);
                    int newLineIndex = 0;
                    while((newLineIndex = infoInject.indexOf('\n', newLineIndex)) != -1)
                    {
                        addLineToMappings(finalLines.size());
                        newLineIndex++;
                    }

                    String cssInject = "\n\n" + thisDef + ".prototype.cssData = [";
                    JSCSSCompilationSession cssSession = (JSCSSCompilationSession) royaleProject.getCSSCompilationSession();
                    String s = cssSession.getEncodedCSS();
                    if (s != null)
                    {
                        int reqidx = s.indexOf(JSGoogEmitterTokens.GOOG_REQUIRE.getToken());
                        if (reqidx != -1)
                        {
                            String cssRequires = s.substring(reqidx);
                            s = s.substring(0, reqidx - 1);
                            String[] cssRequireLines = cssRequires.split("\n");
                            for(String require : cssRequireLines)
                            {
                                finalLines.add(endRequires, require);
                                addLineToMappings(endRequires);
                                endRequires++;
                            }
                        }
                        cssInject += s;
                        finalLines.add(cssInject);
                        newLineIndex = 0;
                        while((newLineIndex = cssInject.indexOf('\n', newLineIndex)) != -1)
                        {
                            addLineToMappings(finalLines.size());
                            newLineIndex++;
                        }
                    }
	            }
            }
        }
		if (staticUsedNames.size() > 0)
		{
			if (staticUsedNames.size() > 1 ||
					!staticUsedNames.get(0).equals(currentClassName))
			{
				StringBuilder sb = new StringBuilder();
				sb.append(JSGoogEmitterTokens.ROYALE_STATIC_DEPENDENCY_LIST.getToken());
				boolean firstDependency = true;
				for (String staticName : staticUsedNames)
				{
					if (currentClassName.equals(staticName))
						continue;
					
					if (!firstDependency)
						sb.append(",");
					firstDependency = false;
					sb.append(staticName);
				}
				sb.append("*/");
				finalLines.add(provideIndex, sb.toString());
	            addLineToMappings(provideIndex);
			}
		}

    	return Joiner.on("\n").join(finalLines);
    }

    private String getSubFileContent(List<String> subfileLines) {
    	StringBuffer sb = new StringBuffer();
    	for (String s : subfileLines)
    	{
    		s = s.trim();
    		if (s.startsWith("<?xml"))
    			continue;
    		else
    		{
    			sb.append(s + " ");
    		}
    	}
    	return sb.toString();
	}

	public void startMapping(ISourceLocation node)
    {
        startMapping(node, node.getLine(), node.getColumn());
    }

    public void startMapping(ISourceLocation node, int line, int column)
    {
        if (isBufferWrite())
        {
            return;
        }
        if (lastMapping != null)
        {
            FilePosition sourceStartPosition = lastMapping.sourceStartPosition;
            throw new IllegalStateException("Cannot start new mapping when another mapping is already started. "
                    + "Previous mapping at Line " + sourceStartPosition.getLine()
                    + " and Column " + sourceStartPosition.getColumn()
                    + " in file " + lastMapping.sourcePath);
        }

        String sourcePath = node.getSourcePath();
        if (sourcePath == null)
        {
            //if the source path is null, this node may have been generated by
            //the compiler automatically. for example, an untyped variable will
            //have a node for the * type.
            if (node instanceof IASNode)
            {
                IASNode parentNode = ((IASNode) node).getParent();
                if (parentNode != null)
                {
                    //try the parent node
                    startMapping(parentNode, line, column);
                    return;
                }
            }
        }

        SourceMapMapping mapping = new SourceMapMapping();
        mapping.sourcePath = sourcePath;
        mapping.sourceStartPosition = new FilePosition(line, column);
        mapping.destStartPosition = new FilePosition(getCurrentLine(), getCurrentColumn());
        lastMapping = mapping;
    }

    public void startMapping(ISourceLocation node, ISourceLocation afterNode)
    {
        startMapping(node, afterNode.getEndLine(), afterNode.getEndColumn());
    }

    public void endMapping(ISourceLocation node)
    {
        if (isBufferWrite())
        {
            return;
        }
        if (lastMapping == null)
        {
            throw new IllegalStateException("Cannot end mapping when a mapping has not been started");
        }

        lastMapping.destEndPosition = new FilePosition(getCurrentLine(), getCurrentColumn());
        sourceMapMappings.add(lastMapping);
        lastMapping = null;
    }

    /**
     * Adjusts the line numbers saved in the source map when a line should be
     * added during post processing.
     *
     * @param lineIndex
     */
    protected void addLineToMappings(int lineIndex)
    {
        for (SourceMapMapping mapping : sourceMapMappings)
        {
            FilePosition destStartPosition = mapping.destStartPosition;
            int startLine = destStartPosition.getLine();
            if(startLine > lineIndex)
            {
                mapping.destStartPosition = new FilePosition(startLine + 1, destStartPosition.getColumn());
                FilePosition destEndPosition = mapping.destEndPosition;
                mapping.destEndPosition = new FilePosition(destEndPosition.getLine() + 1, destEndPosition.getColumn());
            }
        }
    }

    /**
     * Adjusts the line numbers saved in the source map when a line should be
     * removed during post processing.
     *
     * @param lineIndex
     */
    protected void removeLineFromMappings(int lineIndex)
    {
        for (SourceMapMapping mapping : sourceMapMappings)
        {
            FilePosition destStartPosition = mapping.destStartPosition;
            int startLine = destStartPosition.getLine();
            if(startLine > lineIndex)
            {
                mapping.destStartPosition = new FilePosition(startLine - 1, destStartPosition.getColumn());
                FilePosition destEndPosition = mapping.destEndPosition;
                mapping.destEndPosition = new FilePosition(destEndPosition.getLine() - 1, destEndPosition.getColumn());
            }
        }
    }

    @Override
    protected String getIndent(int numIndent)
    {
        final StringBuilder sb = new StringBuilder();
        for (int i = 0; i < numIndent; i++)
            sb.append(JSRoyaleEmitterTokens.INDENT.getToken());
        return sb.toString();
    }

    //--------------------------------------------------------------------------

    @Override
    public void emitDeclarations(IMXMLDeclarationsNode node)
    {
    	inMXMLContent = true;
        boolean reusingDescriptor = false;

        MXMLDescriptorSpecifier currentInstance = getCurrentDescriptor("i");

        MXMLDescriptorSpecifier currentPropertySpecifier = new MXMLDescriptorSpecifier();
        currentPropertySpecifier.isProperty = true;
        currentPropertySpecifier.name = "mxmlContent";
        currentPropertySpecifier.parent = currentInstance;
        if (currentInstance == null)
        {
        	ArrayList<MXMLDescriptorSpecifier> specList =
            	(currentInstance == null) ? descriptorTree : currentInstance.propertySpecifiers;
            for (MXMLDescriptorSpecifier ds : specList)
            {
            	if (ds.name.equals("mxmlContent"))
            	{
            		currentPropertySpecifier = ds;
            		reusingDescriptor = true;
            		break;
            	}
            }
        }
        if (!reusingDescriptor)
        	descriptorTree.add(currentPropertySpecifier);
        moveDown(false, currentInstance, currentPropertySpecifier);
    	super.emitDeclarations(node);
        moveUp(false, false);
    	inMXMLContent = false;
    }

    @Override
    public void emitDocument(IMXMLDocumentNode node)
    {
        RoyaleJSProject fjp = (RoyaleJSProject) getMXMLWalker().getProject();
    	if (fjp.config != null)
    		emitExports = fjp.config.getExportPublicSymbols();

        descriptorTree = new ArrayList<MXMLDescriptorSpecifier>();
        propertiesTree = new MXMLDescriptorSpecifier();
        propertiesTree.name = node.getQualifiedName();

        events = new ArrayList<MXMLEventSpecifier>();
        instances = new ArrayList<MXMLDescriptorSpecifier>();
        scripts = new ArrayList<IMXMLScriptNode>();
        //styles = new ArrayList<MXMLStyleSpecifier>();

        currentInstances = new ArrayList<MXMLDescriptorSpecifier>();
        currentStateOverrides = new MXMLDescriptorSpecifier();
        currentPropertySpecifiers = new ArrayList<MXMLDescriptorSpecifier>();

        eventCounter = 0;
        idCounter = 0;
        bindingCounter = 0;

        // visit MXML
        IClassDefinition cdef = node.getClassDefinition();
        classDefinition = cdef;
        documentDefinition = cdef;

        // TODO (mschmalle) will remove this cast as more things get abstracted
        JSRoyaleEmitter fjs = (JSRoyaleEmitter) ((IMXMLBlockWalker) getMXMLWalker())
                .getASEmitter();

        fjs.setBuilder(getBuilder());
        fjs.getModel().setCurrentClass(cdef);

        // visit tags
        final int len = node.getChildCount();
        for (int i = 0; i < len; i++)
        {
            getMXMLWalker().walk(node.getChild(i));
        }

        String cname = node.getFileNode().getName();

        emitHeader(node);

        emitClassDeclStart(cname, node.getBaseClassName(), false);

        emitComplexInitializers(node);

        emitPropertyDecls();

        emitClassDeclEnd(cname, node.getBaseClassName());

        emitDeclarationVariables();

     //   emitMetaData(cdef);

        write(subDocuments.toString());
        writeNewline();

        emitScripts();

        fjs.getBindableEmitter().emit(cdef);
        fjs.getAccessorEmitter().emit(cdef);

        emitEvents(cname);
        emitComplexStaticInitializers(node);
        emitPropertyGetterSetters(cname);

        emitMXMLDescriptorFuncs(cname);

        emitBindingData(cname, cdef);

        emitMetaData(cdef);

        emitSourceMapDirective(node);
    }

    public void emitDeclarationVariables()
    {
    	for (IMXMLInstanceNode node : primitiveDeclarationNodes)
    	{
    		String id = node.getEffectiveID();
            writeNewline();
            writeNewline("/**");
            writeNewline(" * @export");
            writeNewline(" * @type {" + JSGoogDocEmitter.convertASTypeToJSType(formatQualifiedName(node.getName()), "") + "}");
            writeNewline(" */");
            String cname = node.getFileNode().getName();
            write(cname);
            write(ASEmitterTokens.MEMBER_ACCESS);
            write(JSEmitterTokens.PROTOTYPE);
            write(ASEmitterTokens.MEMBER_ACCESS);
            write(id);
            writeNewline(ASEmitterTokens.SEMICOLON);

    	}
    }

    public void emitSubDocument(IMXMLComponentNode node)
    {
        ArrayList<MXMLDescriptorSpecifier> oldDescriptorTree;
        MXMLDescriptorSpecifier oldPropertiesTree;
        MXMLDescriptorSpecifier oldStateOverrides;
        ArrayList<MXMLEventSpecifier> oldEvents;
        ArrayList<IMXMLScriptNode> oldScripts;
        ArrayList<MXMLDescriptorSpecifier> oldCurrentInstances;
        ArrayList<MXMLDescriptorSpecifier> oldInstances;
        ArrayList<MXMLDescriptorSpecifier> oldCurrentPropertySpecifiers;
        int oldEventCounter;
        int oldIdCounter;
        boolean oldInMXMLContent;
        String oldInterfaceList;

        oldInterfaceList = interfaceList;
        interfaceList = null;
        oldDescriptorTree = descriptorTree;
        descriptorTree = new ArrayList<MXMLDescriptorSpecifier>();
        oldPropertiesTree = propertiesTree;
        propertiesTree = new MXMLDescriptorSpecifier();

        oldInMXMLContent = inMXMLContent;
        inMXMLContent = false;
        oldEvents = events;
        events = new ArrayList<MXMLEventSpecifier>();
        oldInstances = instances;
        instances = new ArrayList<MXMLDescriptorSpecifier>();
        oldScripts = scripts;
        scripts = new ArrayList<IMXMLScriptNode>();
        //styles = new ArrayList<MXMLStyleSpecifier>();

        oldCurrentInstances = currentInstances;
        currentInstances = new ArrayList<MXMLDescriptorSpecifier>();
        oldCurrentPropertySpecifiers = currentPropertySpecifiers;
        currentPropertySpecifiers = new ArrayList<MXMLDescriptorSpecifier>();
        oldStateOverrides = currentStateOverrides;
        currentStateOverrides = new MXMLDescriptorSpecifier();
        
        oldEventCounter = eventCounter;
        eventCounter = 0;
        oldIdCounter = idCounter;
        idCounter = 0;

        // visit MXML
        IClassDefinition oldClassDef = classDefinition;
        IClassDefinition cdef = node.getContainedClassDefinition();
        classDefinition = cdef;
        IASEmitter asEmitter = ((IMXMLBlockWalker) getMXMLWalker())
                .getASEmitter();
        ((JSRoyaleEmitter) asEmitter).getModel().pushClass(cdef);

        IASNode classNode = node.getContainedClassDefinitionNode();
        String cname = cdef.getQualifiedName();
        String baseClassName = cdef.getBaseClassAsDisplayString();
        subDocumentNames.add(cname);

        // visit tags
        final int len = classNode.getChildCount();
        for (int i = 0; i < len; i++)
        {
            getMXMLWalker().walk(classNode.getChild(i));
        }

        ((JSRoyaleEmitter) asEmitter).mxmlEmitter = this;

        emitClassDeclStart(cname, baseClassName, false);

        emitComplexInitializers(classNode);

        emitPropertyDecls();

        emitClassDeclEnd(cname, baseClassName);

        emitMetaData(cdef);

        emitScripts();

        emitEvents(cname);

        emitPropertyGetterSetters(cname);

        emitMXMLDescriptorFuncs(cname);

        emitBindingData(cname, cdef);

        write(((JSRoyaleEmitter) asEmitter).stringifyDefineProperties(cdef));


        descriptorTree = oldDescriptorTree;
        propertiesTree = oldPropertiesTree;
        currentStateOverrides = oldStateOverrides;
        events = oldEvents;
        scripts = oldScripts;
        currentInstances = oldCurrentInstances;
        allInstances.addAll(instances);
        instances = oldInstances;
        currentPropertySpecifiers = oldCurrentPropertySpecifiers;
        eventCounter = oldEventCounter;
        idCounter = oldIdCounter;
        inMXMLContent = oldInMXMLContent;
        classDefinition = oldClassDef;
        interfaceList = oldInterfaceList;
        ((JSRoyaleEmitter) asEmitter).getModel().popClass();
        ((JSRoyaleEmitter) asEmitter).mxmlEmitter = null;

    }

    @Override
    public void emitMetadata(IMXMLMetadataNode node)
    {
        metadataNodes.add(node);
    }

    public void emitSourceMapDirective(ITypeNode node)
    {
        IMXMLBlockWalker walker = (IMXMLBlockWalker) getMXMLWalker();
        IJSEmitter jsEmitter = (IJSEmitter) walker.getASEmitter();
        jsEmitter.emitSourceMapDirective(node);
    }

    //--------------------------------------------------------------------------

    protected void emitClassDeclStart(String cname, String baseClassName,
            boolean indent)
    {
        writeNewline();
        writeNewline("/**");
        writeNewline(" * @constructor");
        writeNewline(" * @extends {" + formatQualifiedName(baseClassName) + "}");
        if (interfaceList != null && interfaceList.length() > 0)
        {
        	String[] interfaces = interfaceList.split(",");
        	for (String iface : interfaces)
        	{
        		writeNewline(" * @implements {" + formatQualifiedName(iface.trim()) + "}");
        	}
        }
        writeNewline(" */");
        writeToken(formatQualifiedName(cname));
        writeToken(ASEmitterTokens.EQUAL);
        write(ASEmitterTokens.FUNCTION);
        write(ASEmitterTokens.PAREN_OPEN);
        writeToken(ASEmitterTokens.PAREN_CLOSE);
        if (indent)
            indentPush();
        writeNewline(ASEmitterTokens.BLOCK_OPEN, true);
        write(formatQualifiedName(cname));
        write(ASEmitterTokens.MEMBER_ACCESS);
        write(JSGoogEmitterTokens.GOOG_BASE);
        write(ASEmitterTokens.PAREN_OPEN);
        write(ASEmitterTokens.THIS);
        writeToken(ASEmitterTokens.COMMA);
        write(ASEmitterTokens.SINGLE_QUOTE);
        write(JSGoogEmitterTokens.GOOG_CONSTRUCTOR);
        write(ASEmitterTokens.SINGLE_QUOTE);
        write(ASEmitterTokens.PAREN_CLOSE);
        writeNewline(ASEmitterTokens.SEMICOLON);
    }

    //--------------------------------------------------------------------------

    protected void emitClassDeclEnd(String cname, String baseClassName)
    {
        writeNewline();
        writeNewline("/**");
        writeNewline(" * @private");
        writeNewline(" * @type {Array}");
        writeNewline(" */");
        writeNewline("this.mxmldd;");

        // top level is 'mxmlContent', skip it...
        if (currentStateOverrides.propertySpecifiers.size() > 0)
        {
            MXMLDescriptorSpecifier root = currentStateOverrides;
            root.isTopNode = true;

            collectExportedNames(root);

	        writeNewline("/**");
	        if (emitExports)
	        	writeNewline(" * @export");
	        writeNewline(" * @type {Array}");
	        writeNewline(" */");
	        writeNewline("this.mxmlsd = " + ASEmitterTokens.SQUARE_OPEN.getToken());
            indentPush();
            
            for (MXMLDescriptorSpecifier md : root.propertySpecifiers)
            {
                write(ASEmitterTokens.SQUARE_OPEN);
                mxmlDescriptorEmitter.emit(md);
                write(ASEmitterTokens.SQUARE_CLOSE);
                writeNewline(ASEmitterTokens.COMMA);
            }
	        write("null");
	        write(ASEmitterTokens.SQUARE_CLOSE);
	        indentPop();
	        writeNewline(ASEmitterTokens.SEMICOLON);
        }

        writeNewline();
        writeNewline("/**");
        writeNewline(" * @private");
        writeNewline(" * @type {Array}");
        writeNewline(" */");

        indentPop();
        writeNewline("this.mxmldp;");

        if (propertiesTree.propertySpecifiers.size() > 0 ||
                propertiesTree.eventSpecifiers.size() > 0)
        {
            indentPush();
            writeNewline();
            write("this.generateMXMLAttributes");
            write(ASEmitterTokens.PAREN_OPEN);
            indentPush();
            writeNewline(ASEmitterTokens.SQUARE_OPEN);

            MXMLDescriptorSpecifier root = propertiesTree;
            root.isTopNode = true;
            mxmlDescriptorEmitter.emit(root);
            indentPop();
            writeNewline();

            collectExportedNames(root);

            write(ASEmitterTokens.SQUARE_CLOSE);
            write(ASEmitterTokens.PAREN_CLOSE);
            writeNewline(ASEmitterTokens.SEMICOLON);
            indentPop();
            writeNewline();
        }

        write(ASEmitterTokens.BLOCK_CLOSE);
        writeNewline(ASEmitterTokens.SEMICOLON);
        write(JSGoogEmitterTokens.GOOG_INHERITS);
        write(ASEmitterTokens.PAREN_OPEN);
        write(formatQualifiedName(cname));
        writeToken(ASEmitterTokens.COMMA);
        write(formatQualifiedName(baseClassName));
        write(ASEmitterTokens.PAREN_CLOSE);
        writeNewline(ASEmitterTokens.SEMICOLON);

        writeNewline();
        writeNewline();
	    writeNewline();
    }

    //--------------------------------------------------------------------------

    protected void emitMetaData(IClassDefinition cdef)
    {
        String cname = cdef.getQualifiedName();

        writeNewline("/**");
        writeNewline(" * Metadata");
        writeNewline(" *");
        writeNewline(" * @type {Object.<string, Array.<Object>>}");
        writeNewline(" */");
        write(formatQualifiedName(cname) + ".prototype.ROYALE_CLASS_INFO = { names: [{ name: '");
        write(cdef.getBaseName());
        write("', qName: '");
        write(formatQualifiedName(cname));
        write("'");
        writeToken(ASEmitterTokens.COMMA);
        write(JSRoyaleEmitterTokens.ROYALE_CLASS_INFO_KIND);
        writeToken(ASEmitterTokens.COLON);
        write(ASEmitterTokens.SINGLE_QUOTE);
        write(JSRoyaleEmitterTokens.ROYALE_CLASS_INFO_CLASS_KIND);
        writeToken(ASEmitterTokens.SINGLE_QUOTE);
        write(" }]");
        if (interfaceList != null)
        {
        	write(", interfaces: [");
        	write(interfaceList);
        	write("]");
        }
        write(" };");

        emitReflectionData(cdef);
        writeNewline();
        writeNewline();

    }

    private void emitReflectionData(IClassDefinition cdef)
    {
        JSRoyaleEmitter asEmitter = (JSRoyaleEmitter)((IMXMLBlockWalker) getMXMLWalker()).getASEmitter();
        RoyaleJSProject fjs = (RoyaleJSProject) getMXMLWalker().getProject();
    	ArrayList<String> exportProperties = new ArrayList<String>();
    	ArrayList<String> exportSymbols = new ArrayList<String>();
    	Set<String> exportMetadata = Collections.<String> emptySet();
    	if (fjs.config != null)
    		exportMetadata = fjs.config.getCompilerKeepCodeWithMetadata();
        ArrayList<PackageFooterEmitter.VariableData> varData = new ArrayList<PackageFooterEmitter.VariableData>();
        // vars can only come from script blocks and decls?
        for (IMXMLInstanceNode declNode : primitiveDeclarationNodes)
        {
        	PackageFooterEmitter.VariableData data = asEmitter.packageFooterEmitter.new VariableData();
        	varData.add(data);
        	data.name = declNode.getEffectiveID();
            data.isStatic = false;
            String qualifiedTypeName = declNode.getName();
    	    data.type = (qualifiedTypeName);
        }
        List<IVariableNode> vars = asEmitter.getModel().getVars();
        for (IVariableNode varNode : vars)
        {
            String ns = varNode.getNamespace();
            if (ns == IASKeywordConstants.PUBLIC && !varNode.isConst())
            {
            	PackageFooterEmitter.VariableData data = asEmitter.packageFooterEmitter.new VariableData();
            	varData.add(data);
            	data.name = varNode.getName();
                data.isStatic = varNode.hasModifier(ASModifier.STATIC);
                String qualifiedTypeName = "*";
                IExpressionNode variableTypeNode = varNode.getVariableTypeNode();
                if (variableTypeNode != null)
                {
                    qualifiedTypeName = variableTypeNode.resolveType(getMXMLWalker().getProject()).getQualifiedName();
                }
        	    data.type = qualifiedTypeName;
        	    IMetaTagsNode metaData = varNode.getMetaTags();
        	    if (metaData != null)
        	    {
        	    	IMetaTagNode[] tags = metaData.getAllTags();
        	    	if (tags.length > 0)
        	    	{
        	    		data.metaData = tags;
        	    		for (IMetaTagNode tag : tags)
        	    		{
        	    			String tagName =  tag.getTagName();
        	    			if (exportMetadata.contains(tagName))
        	    			{
        	    				if (data.isStatic)
        	    					exportSymbols.add(data.name);
        	    				else
            	    				exportProperties.add(data.name);
        	    			}
        	    		}
        	    	}
        	    }
            }
        }

        ArrayList<PackageFooterEmitter.AccessorData> accessorData = new ArrayList<PackageFooterEmitter.AccessorData>();
        HashMap<String, PropertyNodes> accessors = asEmitter.getModel().getPropertyMap();
        //instance accessors
        collectAccessors(accessors,accessorData,cdef);
        accessors = asEmitter.getModel().getStaticPropertyMap();
        //static accessors
        collectAccessors(accessors,accessorData,cdef);

        //additional bindables
        HashMap<String, BindableVarInfo> bindableVars = asEmitter.getModel().getBindableVars();
        for (String varName : bindableVars.keySet())
        {
            BindableVarInfo bindableVarInfo = bindableVars.get(varName);

            String ns = bindableVarInfo.namespace;
            if (ns == IASKeywordConstants.PUBLIC)
            {
                PackageFooterEmitter.AccessorData data = asEmitter.packageFooterEmitter.new AccessorData();
                accessorData.add(data);
                data.name = varName;
                data.isStatic = bindableVarInfo.isStatic;
                data.type = bindableVarInfo.type;
                data.declaredBy = cdef.getQualifiedName();
                data.access = "readwrite";
                if (bindableVarInfo.metaTags != null) {
                    if (bindableVarInfo.metaTags.length > 0)
                        data.metaData = bindableVarInfo.metaTags;
                }
            }
        }


        for (MXMLDescriptorSpecifier instance : instances)
        {
			String instanceId = instance.id != null ? instance.id : (instance.hasLocalId ? instance.effectiveId : null);
            if (instanceId != null)
            {
	        	PackageFooterEmitter.AccessorData data = asEmitter.packageFooterEmitter.new AccessorData();
	        	accessorData.add(data);
	        	data.name = instanceId;
	        	data.type = instance.name;
                data.access = "readwrite";
	    	    data.declaredBy = cdef.getQualifiedName();
            }
        }
        ArrayList<PackageFooterEmitter.MethodData> methodData = new ArrayList<PackageFooterEmitter.MethodData>();
        List<IFunctionNode> methods = asEmitter.getModel().getMethods();




        for (IFunctionNode methodNode : methods)
        {
            String ns = methodNode.getNamespace();
            if (ns == IASKeywordConstants.PUBLIC)
            {
            	PackageFooterEmitter.MethodData data = asEmitter.packageFooterEmitter.new MethodData();
            	methodData.add(data);
            	data.name = methodNode.getName();
                String qualifiedTypeName =	methodNode.getReturnType();
                if (!(qualifiedTypeName.equals("") || qualifiedTypeName.equals("void"))) {
                    IExpressionNode returnTypeNode = methodNode.getReturnTypeNode();
                    if (returnTypeNode != null)
                    {
                        qualifiedTypeName = returnTypeNode.resolveType(fjs).getQualifiedName();;
                    }
                }
                data.type = qualifiedTypeName;
        	    data.declaredBy = cdef.getQualifiedName();
                data.isStatic = methodNode.hasModifier(ASModifier.STATIC);
                IParameterNode[] paramNodes = methodNode.getParameterNodes();
                if (paramNodes != null && paramNodes.length > 0) {
                    data.parameters = paramNodes;
                }
        	    IMetaTagsNode metaData = methodNode.getMetaTags();
        	    if (metaData != null)
        	    {
        	    	IMetaTagNode[] tags = metaData.getAllTags();
        	    	if (tags.length > 0)
        	    	{
        	    		data.metaData = tags;
        	    		for (IMetaTagNode tag : tags)
        	    		{
        	    			String tagName =  tag.getTagName();
        	    			if (exportMetadata.contains(tagName))
        	    			{
        	    				if (data.isStatic)
        	    					exportSymbols.add(data.name);
        	    				else
            	    				exportProperties.add(data.name);
        	    			}
        	    		}
        	    	}
        	    }
            }
        }

        if (cdef.getConstructor()==null) {
            //add a constructor description for the reflection data
            PackageFooterEmitter.MethodData data = asEmitter.packageFooterEmitter.new MethodData();
            methodData.add(data);
            data.name = cdef.getBaseName();
            data.type = "";
            data.isStatic = false;
            data.declaredBy = cdef.getQualifiedName();
        }
        
        ArrayList<IMetaTagNode> metadataTagNodes = new ArrayList<IMetaTagNode>();
        for (IMXMLMetadataNode metadataTag : metadataNodes)
        {
        	IMetaTagNode[] tags = metadataTag.getMetaTagNodes();
        	//tags (MetaTagNodes) can be null if the parent node is empty (or content is commented out)
        	if (tags != null) {
                for (IMetaTagNode tag : tags)
                {
                    metadataTagNodes.add(tag);
                }
            }
        }
        IMetaTagNode[] metaDataTags = new IMetaTagNode[metadataTagNodes.size()];

        asEmitter.packageFooterEmitter.emitReflectionData(
                formatQualifiedName(cdef.getQualifiedName()),
                PackageFooterEmitter.ReflectionKind.CLASS,
                varData,
        		accessorData,
                methodData,
                metadataTagNodes.toArray(metaDataTags));
	
		asEmitter.packageFooterEmitter.emitReflectionRegisterInitialStaticFields(
				formatQualifiedName(cdef.getQualifiedName()),
				cdef);
        
        asEmitter.packageFooterEmitter.emitExportProperties(
                formatQualifiedName(cdef.getQualifiedName()),
                exportProperties,
                exportSymbols);
    }

    private void collectAccessors(HashMap<String, PropertyNodes> accessors, ArrayList<PackageFooterEmitter.AccessorData> accessorData,IClassDefinition cdef ) {
        JSRoyaleEmitter asEmitter = (JSRoyaleEmitter)((IMXMLBlockWalker) getMXMLWalker()).getASEmitter();
        RoyaleJSProject fjs = (RoyaleJSProject) getMXMLWalker().getProject();

        for (String propName : accessors.keySet())
        {
            PropertyNodes p = accessors.get(propName);

            IFunctionNode accessorNode = p.getter;
            if (accessorNode == null)
                accessorNode = p.setter;
            String ns = accessorNode.getNamespace();
            if (ns == IASKeywordConstants.PUBLIC)
            {
                PackageFooterEmitter.AccessorData data = asEmitter.packageFooterEmitter.new AccessorData();
                accessorData.add(data);
                data.name = accessorNode.getName();

                data.isStatic = accessorNode.hasModifier(ASModifier.STATIC);
                if (p.getter != null)
                {
                    String returnType = "*";
                    IExpressionNode returnTypeNode = p.getter.getReturnTypeNode();
                    if (returnTypeNode != null)
                    {
                        returnType = returnTypeNode.resolveType(fjs).getQualifiedName();
                    }
                    data.type = returnType;
                    if (p.setter != null)
                    {
                        data.access = "readwrite";
                    }
                    else
                    {
                        data.access = "readonly";
                    }
                }
                else
                {
                    String returnType = "*";
                    IExpressionNode variableTypeNode = p.setter.getVariableTypeNode();
                    if (variableTypeNode != null)
                    {
                        returnType = variableTypeNode.resolveType(fjs).getQualifiedName();
                    }
                    data.type = returnType;
                    data.access = "writeonly";
                }

                data.declaredBy = (cdef.getQualifiedName());
                IMetaTagsNode metaData = accessorNode.getMetaTags();
                if (metaData != null)
                {
                    IMetaTagNode[] tags = metaData.getAllTags();
                    if (tags.length > 0)
                    {
                        data.metaData = tags;
    	    			/* accessors don't need exportProp since they are referenced via the defineProp data structure
        	    		for (IMetaTagNode tag : tags)
        	    		{
        	    			String tagName =  tag.getTagName();
        	    			if (exportMetadata.contains(tagName))
        	    			{
        	    				if (data.isStatic)
        	    					exportSymbols.add(data.name);
        	    				else
            	    				exportProperties.add(data.name);
        	    			}
        	    		}
        	    			*/
                    }
                }
            }
        }
    }

    //--------------------------------------------------------------------------

    protected void emitPropertyDecls()
    {
        for (MXMLDescriptorSpecifier instance : instances)
        {
			String id = instance.id != null ? instance.id : instance.effectiveId;
			if (id != null) { //it seems id can be null, for example with a generated Object for Operations via RemoteObject
				writeNewline();
				writeNewline("/**");
				writeNewline(" * @private");
				writeNewline(" * @type {" + instance.name + "}");
				writeNewline(" */");
				write(ASEmitterTokens.THIS);
				write(ASEmitterTokens.MEMBER_ACCESS);

				if (!id.startsWith(MXMLRoyaleEmitterTokens.ID_PREFIX.getToken())) id += "_";
				write(id);
				writeNewline(ASEmitterTokens.SEMICOLON);
			}
        }
    }

    //--------------------------------------------------------------------------

    protected void emitBindingData(String cname, IClassDefinition cdef)
    {
		IRoyaleProject project = (IRoyaleProject)(walker.getProject());
		BindingDatabase bd = project.getBindingMap().get(cdef);
        if (bd == null)
            return;
        if (bd.getBindingInfo().isEmpty())
            return;

        inStaticInitializer = true;
        outputBindingInfoAsData(cname, bd);
        inStaticInitializer = false;
    }

    private void outputBindingInfoAsData(String cname, BindingDatabase bindingDataBase)
    {
        RoyaleJSProject project = (RoyaleJSProject)getMXMLWalker().getProject();
        IASEmitter asEmitter = ((IMXMLBlockWalker) getMXMLWalker())
                .getASEmitter();
        boolean allowDynamicBindings = project.config != null && project.config.getAllowDynamicBindings();
        boolean useMxmlReflectObjectProperty = project.config != null && project.config.getMxmlReflectObjectProperty();
        
        writeNewline("/**");
        writeNewline(" * @export"); // must export or else GCC will remove it
        writeNewline(" */");
        writeNewline(formatQualifiedName(cname)
                + ".prototype._bindings = [");

		if (bindingDataBase.getHasAncestorBindings()) {
			//reference the ancestor binding data (which may in turn reference its owner's ancestor's bindings etc)
			writeNewline(formatQualifiedName(bindingDataBase.getNearestAncestorWithBindings()) +
					 ".prototype._bindings,");
		}

        Set<BindingInfo> bindingInfo = bindingDataBase.getBindingInfo();
        writeNewline(bindingInfo.size() + ","); // number of bindings
        boolean hadOutput = false;
        for (BindingInfo bi : bindingInfo)
        {
            if (hadOutput)
            {
                writeNewline(ASEmitterTokens.COMMA);
            }
            hadOutput = true;
            String s;
            IMXMLNode node = bi.node;
            if (node instanceof IMXMLSingleDataBindingNode)
            {
            	IMXMLSingleDataBindingNode sbdn = (IMXMLSingleDataBindingNode)node;
            	IDefinition bdef = sbdn.getExpressionNode().resolve(project);
            	if (bdef != null)
            	{
	            	//IDefinition cdef = bdef.getParent();
	            	project.addExportedName(/*cdef.getQualifiedName() + "." + */bdef.getBaseName());
            	}
            }
            s = bi.getSourceString();
            if (s == null && bi.isSourceSimplePublicProperty())
                s = getSourceStringFromGetter(bi.getExpressionNodesForGetter());
            if (!allowDynamicBindings || s == null || s.length() == 0)
            {
                List<IExpressionNode> getterNodes = bi.getExpressionNodesForGetter();
                StringBuilder sb = new StringBuilder();
                sb.append("/** @this {");
                sb.append(formatQualifiedName(cname));
                sb.append("} */\n");
                sb.append("function() { return ");
                int n = getterNodes.size();
                for (int i = 0; i < n; i++)
                {
                	IExpressionNode getterNode = getterNodes.get(i);
                    sb.append(asEmitter.stringifyNode(getterNode));
                    if (i < n - 1)
                    {
                        sb.append(ASEmitterTokens.SPACE.getToken());
                        sb.append(ASEmitterTokens.PLUS.getToken());
                        sb.append(ASEmitterTokens.SPACE.getToken());
                    }
                }
                sb.append("; },");
                writeNewline(sb.toString());
            }
            else if (s.contains("."))
            {
            	if (bi.classDef != null)
            	{
                    String[] parts = s.split("\\.");
	                String qname = bi.classDef.getQualifiedName();
                    write(ASEmitterTokens.SQUARE_OPEN);
                    write(ASEmitterTokens.DOUBLE_QUOTE);
                    write(qname);
                    write(ASEmitterTokens.DOUBLE_QUOTE);
	                if (!usedNames.contains(qname))
	                	usedNames.add(qname);
	                if (!staticUsedNames.contains(qname))
	                	staticUsedNames.add(qname);
                    StringBuilder objString = null;
                    if (useMxmlReflectObjectProperty)
                    {
                        objString = new StringBuilder();
                        objString.append(qname);
                    }
	                int n = parts.length;
	                for (int i = 1; i < n; i++)
	                {
	                    String part = parts[i];
                        write(", ");
                        if(useMxmlReflectObjectProperty)
                        {
                            write(JSGoogEmitterTokens.GOOG_REFLECT_OBJECTPROPERTY);
                            write(ASEmitterTokens.PAREN_OPEN);
                        }
                        write(ASEmitterTokens.DOUBLE_QUOTE);
                        write(part);
                        write(ASEmitterTokens.DOUBLE_QUOTE);
                        if(useMxmlReflectObjectProperty)
                        {
                            write(ASEmitterTokens.COMMA);
                            write(ASEmitterTokens.SPACE);
                            write(objString.toString());
                            write(ASEmitterTokens.PAREN_CLOSE);
                            objString.append(".");
                            objString.append(part);
                        }
	                }
                    write(ASEmitterTokens.SQUARE_CLOSE);
                    writeNewline(ASEmitterTokens.COMMA);
            	}
            	else
            	{
	                String[] parts = s.split("\\.");
                    write(ASEmitterTokens.SQUARE_OPEN);
                    StringBuilder objString = null;
                    if (useMxmlReflectObjectProperty)
                    {
                        objString = new StringBuilder();
                        objString.append("this");
                    }
                    int n = parts.length;
	                for (int i = 0; i < n; i++)
	                {
                        String part = parts[i];
                        if (i > 0)
                        {
                            write(", ");
                        }
                        if(useMxmlReflectObjectProperty)
                        {
                            write(JSGoogEmitterTokens.GOOG_REFLECT_OBJECTPROPERTY);
                            write(ASEmitterTokens.PAREN_OPEN);
                        }
                        write(ASEmitterTokens.DOUBLE_QUOTE);
                        write(part);
                        write(ASEmitterTokens.DOUBLE_QUOTE);
                        if(useMxmlReflectObjectProperty)
                        {
                            write(ASEmitterTokens.COMMA);
                            write(ASEmitterTokens.SPACE);
                            write(objString.toString());
                            write(ASEmitterTokens.PAREN_CLOSE);
                            objString.append(".");
                            objString.append(part);
                        }
                    }
                    write(ASEmitterTokens.SQUARE_CLOSE);
	                writeNewline(ASEmitterTokens.COMMA);
            	}
            }
            else
            {
                if(useMxmlReflectObjectProperty)
                {
                    write(JSGoogEmitterTokens.GOOG_REFLECT_OBJECTPROPERTY);
                    write(ASEmitterTokens.PAREN_OPEN);
                }
                write(ASEmitterTokens.DOUBLE_QUOTE);
                write(s);
                write(ASEmitterTokens.DOUBLE_QUOTE);
                if(useMxmlReflectObjectProperty)
                {
                    write(ASEmitterTokens.COMMA);
                    write(ASEmitterTokens.SPACE);
                    write(ASEmitterTokens.THIS);
                    write(ASEmitterTokens.PAREN_CLOSE);
                }
                writeNewline(ASEmitterTokens.COMMA);
            }

            IExpressionNode destNode = bi.getExpressionNodeForDestination();
            s = bi.getDestinationString();
            if (!allowDynamicBindings && destNode == null && s != null)
            {
                StringBuilder sb = new StringBuilder();
                sb.append("/** @this {");
                sb.append(formatQualifiedName(cname));
                sb.append("} */\n");
                sb.append("function(value) { ");
                sb.append("this.");
                sb.append(s);
                sb.append(" = value; },");
                writeNewline(sb.toString());
                s = null;
            }
            else if (destNode != null && s == null)
            {
                StringBuilder sb = new StringBuilder();
                sb.append(generateSetterFunction(bi, destNode));
                write(sb.toString());
                writeNewline(ASEmitterTokens.COMMA);
            }
            else
            {
                write(ASEmitterTokens.NULL);
                writeNewline(ASEmitterTokens.COMMA);
            }

            if (s == null)
            {
                write(ASEmitterTokens.NULL);
            }
            else if (s.contains("."))
            {
                String[] parts = s.split("\\.");
                write(ASEmitterTokens.SQUARE_OPEN);
                StringBuilder objString = null;
                if (useMxmlReflectObjectProperty)
                {
                    objString = new StringBuilder();
                    objString.append("this");
                }
                int n = parts.length;
                for (int i = 0; i < n; i++)
                {
                    String part = parts[i];
                    if (i > 0)
                    {
                        write(", ");
                    }
                    if(useMxmlReflectObjectProperty)
                    {
                        write(JSGoogEmitterTokens.GOOG_REFLECT_OBJECTPROPERTY);
                        write(ASEmitterTokens.PAREN_OPEN);
                    }
                    write(ASEmitterTokens.DOUBLE_QUOTE);
                    write(part);
                    write(ASEmitterTokens.DOUBLE_QUOTE);
                    if(useMxmlReflectObjectProperty)
                    {
                        write(ASEmitterTokens.COMMA);
                        write(ASEmitterTokens.SPACE);
                        write(objString.toString());
                        write(ASEmitterTokens.PAREN_CLOSE);
                        objString.append(".");
                        objString.append(part);
                    }
                }
                write(ASEmitterTokens.SQUARE_CLOSE);
            }
            else
            {
                if(useMxmlReflectObjectProperty)
                {
                    write(JSGoogEmitterTokens.GOOG_REFLECT_OBJECTPROPERTY);
                    write(ASEmitterTokens.PAREN_OPEN);
                }
                write(ASEmitterTokens.DOUBLE_QUOTE);
                write(s);
                write(ASEmitterTokens.DOUBLE_QUOTE);
                if(useMxmlReflectObjectProperty)
                {
                    write(ASEmitterTokens.COMMA);
                    write(ASEmitterTokens.SPACE);
                    write(ASEmitterTokens.THIS);
                    write(ASEmitterTokens.PAREN_CLOSE);
                }
                writeNewline(ASEmitterTokens.COMMA);
            }
            
        }
        Set<Entry<Object, WatcherInfoBase>> watcherChains = bindingDataBase.getWatcherChains();
        
        if (watcherChains != null)
        {
            int count = watcherChains.size();
            if (hadOutput) {
                if (count > 0) writeNewline(ASEmitterTokens.COMMA);
                else writeNewline();
            }
            for (Entry<Object, WatcherInfoBase> entry : watcherChains)
            {
                count--;
                WatcherInfoBase watcherInfoBase = entry.getValue();
                encodeWatcher(watcherInfoBase);
                if (count > 0) writeNewline(ASEmitterTokens.COMMA);
            }
        } else {
            if (hadOutput) writeNewline();
        }

        write(ASEmitterTokens.SQUARE_CLOSE);
        writeNewline(ASEmitterTokens.SEMICOLON);
    }

    private String generateSetterFunction(BindingInfo bi, IExpressionNode destNode) {
        IASEmitter asEmitter = ((IMXMLBlockWalker) getMXMLWalker())
        	.getASEmitter();
		StringBuilder sb = new StringBuilder();
		sb.append("function (value) { ");
		if (destNode instanceof InstructionListNode)
		{
			sb.append(generateDestExpression(bi));
		}
		else
		{
			String body = asEmitter.stringifyNode(destNode);
			sb.append(body);
			sb.append(" = value;");
		}
		sb.append("}");
		return sb.toString();
	}
    
    String generateDestExpression(BindingInfo bi)
    {
    	StringBuilder sb = new StringBuilder();
    	MXMLBindingNode node = (MXMLBindingNode)bi.node;
    	IMXMLBindingAttributeNode destNode = node.getDestinationAttributeNode();
    	Stack<IASNode> nodeStack = new Stack<IASNode>();
    	nodeStack.push(node);
    	IASNode parentNode = node.getParent();
    	while (!(parentNode instanceof IMXMLInstanceNode))
    	{
    		nodeStack.push(parentNode);
    		parentNode = parentNode.getParent();
    	}
    	boolean isXML = parentNode instanceof IMXMLXMLNode;
    	boolean isXMLList = parentNode instanceof IMXMLXMLListNode;
    	String effectiveID = ((IMXMLInstanceNode)parentNode).getEffectiveID();
    	sb.append("this.");
    	sb.append(effectiveID);
    	// at least for one XMLList case, we could not trust
    	// the nodestack as children were only binding nodes
    	// and not preceding XML nodes
    	if (isXMLList)
    	{
    		// re-interpret the instruction list.
    		// it would not be a surprise of the non-XMLList cases will
    		// eventually require this code path
    		InstructionListNode ilNode = (InstructionListNode)destNode.getExpressionNode();
    		InstructionList il = ilNode.getInstructions();
    		ArrayList<Instruction> abcs = il.getInstructions();
    		// the first indexed access accesses an XMLList, the next ones
    		// access an XML object
    		boolean indexedAccess = false;
    		int n = abcs.size();
    		for (int i = 0; i < n; i++)
    		{
    			Instruction inst = abcs.get(i);
    			int opCode = inst.getOpcode();
    			if (opCode == ABCConstants.OP_getlocal0)
    			{
    				if (i > 0)
    					System.out.println("unexpected getLocal0 in binding expression");
    			}
    			else if (opCode == ABCConstants.OP_getproperty)
    			{
    				OneOperandInstruction getProp = (OneOperandInstruction)inst;
    				Name propName = (Name)getProp.getOperand(0);
    				if (i == 0)
    					System.out.println("unexpected opcode in binding expression");
    				else if (i == 1 && !propName.getBaseName().contentEquals(effectiveID))
    					System.out.println("unexpected effectiveID in binding expression");
    				else if (i > 1)
    				{
    					try
    				    {
    				        Integer.parseInt(propName.getBaseName());
    				        if (indexedAccess)
    				        	sb.append(".children()");
    			    		sb.append("[" + propName.getBaseName() + "]" );
    				        indexedAccess = true;
    				    } catch (NumberFormatException ex)
    				    {
    				    	sb.append(".elements(" + propName.getBaseName() + ")" );
    				    }
    				}
    			}
    			else if (opCode == ABCConstants.OP_getlocal1)
    			{
    				if (i != n - 3)
    					System.out.println("unexpected getLocal1 in binding expression");    				
    			}
    			else if (opCode == ABCConstants.OP_setproperty)
    			{
    				if (i != n - 2)
    					System.out.println("unexpected setProperty in binding expression");    				
    				OneOperandInstruction setProp = (OneOperandInstruction)inst;
    				Name propName = (Name)setProp.getOperand(0);
    				if (!propName.getBaseName().contentEquals(destNode.getName()))
    					System.out.println("unexpected setProperty name in binding expression");    				
    				break; // exit loop
    			}
    		}    		
	    	sb.append(".setAttribute('" + destNode.getName() + "', value);" );
    	}
    	else
    	{
	    	while (nodeStack.size() > 0)
	    	{
	    		IASNode childNode = nodeStack.pop();
	    		int n = parentNode.getChildCount();
	    		int i = 0;
	    		for (; i < n; i++)
	    		{
	    			if (childNode == parentNode.getChild(i))
	    				break;
	    		}
	    		assert i < n;
	    		sb.append("[" + new Integer(i).toString() + "]" );
	    		parentNode = childNode;
	    	}
	    	if (isXML)
		    	sb.append(".setAttribute('" + destNode.getName() + "', value);" );
	    	else
	    		sb.append("." + destNode.getName() + " = value;");
    	}
    	return sb.toString();
    }

	private void encodeWatcher(WatcherInfoBase watcherInfoBase)
    {
        IASEmitter asEmitter = ((IMXMLBlockWalker) getMXMLWalker())
        .getASEmitter();

        writeNewline(watcherInfoBase.getIndex() + ASEmitterTokens.COMMA.getToken());
        WatcherType type = watcherInfoBase.getType();
        if (type == WatcherType.FUNCTION)
        {
            writeNewline("0" + ASEmitterTokens.COMMA.getToken());

            FunctionWatcherInfo functionWatcherInfo = (FunctionWatcherInfo)watcherInfoBase;

            writeNewline(ASEmitterTokens.DOUBLE_QUOTE.getToken() + functionWatcherInfo.getFunctionName() +
                    ASEmitterTokens.DOUBLE_QUOTE.getToken() + ASEmitterTokens.COMMA.getToken());
            IExpressionNode params[] = functionWatcherInfo.params;
            StringBuilder sb = new StringBuilder();
            sb.append("function() { return [");
            boolean firstone = true;
            for (IExpressionNode param : params)
            {
                if (!firstone)
                {
                    sb.append(ASEmitterTokens.COMMA.getToken());
                }
                firstone = false;
                sb.append(asEmitter.stringifyNode(param));
            }
            sb.append("]; },");
            writeNewline(sb.toString());
            outputEventNames(functionWatcherInfo.getEventNames());
            outputBindings(functionWatcherInfo.getBindings());
        }
        else if ((type == WatcherType.STATIC_PROPERTY) || (type == WatcherType.PROPERTY))
        {
            writeNewline((type == WatcherType.STATIC_PROPERTY ? "1" : "2") +
                    ASEmitterTokens.COMMA.getToken());

            PropertyWatcherInfo propertyWatcherInfo = (PropertyWatcherInfo)watcherInfoBase;

            boolean makeStaticWatcher = (watcherInfoBase.getType() == WatcherType.STATIC_PROPERTY);

            // round up the getter function for the watcher, or null if we don't need one
            StringBuilder propertyGetterFunction = null;
            if (watcherInfoBase.isRoot && !makeStaticWatcher)
            {
                // TODO: figure out what this looks like
                // propertyGetterFunction = this.propertyGetter;
                // assert propertyGetterFunction != null;
                StringBuilder sb = new StringBuilder();
                sb.append("function() { return this.");
                RoyaleJSProject fjp = (RoyaleJSProject) getMXMLWalker().getProject();
                String propName = propertyWatcherInfo.getPropertyName();
                IDefinitionSet defSet = this.classDefinition.getContainedScope().getLocalDefinitionSetByName(propName);
                if (defSet != null)
                {
	                IDefinition rootDef = defSet.getDefinition(0);
	                if (rootDef != null)
	                {
	                	if (rootDef.isPrivate())
	                	{
	                		sb.append(((JSRoyaleEmitter)asEmitter).formatPrivateName(this.classDefinition.getQualifiedName(), 
	                				propName));
	                    	sb.append("; }");
	                    	propertyGetterFunction = sb;
	                	}
	                	// might need for public as well.
	                }
                }
            }
            else if (watcherInfoBase.isRoot && makeStaticWatcher)
            {
                 // TODO: implement getter func for static watcher.
            }
            writeNewline(ASEmitterTokens.DOUBLE_QUOTE.getToken() + propertyWatcherInfo.getPropertyName() +
                    ASEmitterTokens.DOUBLE_QUOTE.getToken() + ASEmitterTokens.COMMA.getToken());
            outputEventNames(propertyWatcherInfo.getEventNames());
            outputBindings(propertyWatcherInfo.getBindings());
            if (propertyGetterFunction == null)
                writeNewline("null" + ASEmitterTokens.COMMA.getToken()); // null is valid
            else
            	writeNewline(propertyGetterFunction.toString() + ASEmitterTokens.COMMA.getToken());
            if (type == WatcherType.STATIC_PROPERTY)
            {
                StaticPropertyWatcherInfo pwinfo = (StaticPropertyWatcherInfo)watcherInfoBase;
                Name classMName = pwinfo.getContainingClass(getMXMLWalker().getProject());
                writeNewline(nameToString(classMName)+ ASEmitterTokens.COMMA.getToken());
            }
        }
        else if (type == WatcherType.XML)
        {
            writeNewline("3" + ASEmitterTokens.COMMA.getToken());

            XMLWatcherInfo xmlWatcherInfo = (XMLWatcherInfo)watcherInfoBase;
            writeNewline(ASEmitterTokens.DOUBLE_QUOTE.getToken() + xmlWatcherInfo.getPropertyName() +
                    ASEmitterTokens.DOUBLE_QUOTE.getToken() + ASEmitterTokens.COMMA.getToken());
            outputBindings(xmlWatcherInfo.getBindings());
        }
        else assert false;

        // then recurse into children
        Set<Entry<Object, WatcherInfoBase>> children = watcherInfoBase.getChildren();
        if (children != null)
        {
            writeNewline(ASEmitterTokens.SQUARE_OPEN.getToken());
            for ( Entry<Object, WatcherInfoBase> ent : children)
            {
                encodeWatcher(ent.getValue());
                writeNewline(ASEmitterTokens.COMMA);
            }
            write("null" + ASEmitterTokens.SQUARE_CLOSE.getToken() );
        }
        else
        {
            write("null" );
        }
    }

    private String getSourceStringFromMemberAccessExpressionNode(MemberAccessExpressionNode node)
    {
        String s = "";

        IExpressionNode left = node.getLeftOperandNode();
        if (left instanceof FunctionCallNode) //  probably a cast
        {
            IASNode child = ((FunctionCallNode)left).getArgumentsNode().getChild(0);
            if (child instanceof IdentifierNode)
                s = getSourceStringFromIdentifierNode((IdentifierNode)child);
            else if (child instanceof MemberAccessExpressionNode)
                s = getSourceStringFromMemberAccessExpressionNode((MemberAccessExpressionNode)child);
        }
        else if (left instanceof MemberAccessExpressionNode)
            s = getSourceStringFromMemberAccessExpressionNode((MemberAccessExpressionNode)left);
        else if (left instanceof IdentifierNode)
            s = getSourceStringFromIdentifierNode((IdentifierNode)left);
        else
            System.out.println("expected binding member access left node" + node.toString());
        s += ".";

        IExpressionNode right = node.getRightOperandNode();
        if (right instanceof FunctionCallNode) //  probably a cast
        {
            IASNode child = ((FunctionCallNode)right).getArgumentsNode().getChild(0);
            if (child instanceof IdentifierNode)
                s += getSourceStringFromIdentifierNode((IdentifierNode)child);
            else if (child instanceof MemberAccessExpressionNode)
                s += getSourceStringFromMemberAccessExpressionNode((MemberAccessExpressionNode)child);
        }
        else if (right instanceof MemberAccessExpressionNode)
            s += getSourceStringFromMemberAccessExpressionNode((MemberAccessExpressionNode)right);
        else if (right instanceof IdentifierNode)
            s += getSourceStringFromIdentifierNode((IdentifierNode)right);
        else
            System.out.println("expected binding member access right node" + node.toString());

        return s;
    }

    private String getSourceStringFromIdentifierNode(IdentifierNode node)
    {
        return node.getName();
    }

    private String getSourceStringFromGetter(List<IExpressionNode> nodes)
    {
        String s = "";
        IExpressionNode node = nodes.get(0);
        if (node instanceof MemberAccessExpressionNode)
        {
            s = getSourceStringFromMemberAccessExpressionNode((MemberAccessExpressionNode)node);
        }
        else if (node instanceof IdentifierNode)
        {
            s = ((IdentifierNode)node).getName();
        }
        return s;
    }

    private void outputEventNames(List<String> events)
    {
        if (events.size() > 1)
        {
            int n = events.size();
            write(ASEmitterTokens.SQUARE_OPEN.getToken() + ASEmitterTokens.DOUBLE_QUOTE.getToken() +
                    events.get(0) + ASEmitterTokens.DOUBLE_QUOTE.getToken());
            for (int i = 1; i < n; i++)
            {
                String event = events.get(i);
                write(ASEmitterTokens.COMMA.getToken() + ASEmitterTokens.DOUBLE_QUOTE.getToken() +
                        event + ASEmitterTokens.DOUBLE_QUOTE.getToken());
            }
            writeNewline(ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.COMMA.getToken());
        }
        else if (events.size() == 1)
            writeNewline(ASEmitterTokens.DOUBLE_QUOTE.getToken() + events.get(0) +
                    ASEmitterTokens.DOUBLE_QUOTE.getToken() + ASEmitterTokens.COMMA.getToken());
        else
            writeNewline("null" + ASEmitterTokens.COMMA.getToken());
    }

    private void outputBindings(List<BindingInfo> bindings)
    {
        if (bindings.size() > 1)
        {
            int n = bindings.size();
            write(ASEmitterTokens.SQUARE_OPEN.getToken() + bindings.get(0).getIndex());
            for (int i = 1; i < n; i++)
            {
                BindingInfo binding = bindings.get(i);
                write(ASEmitterTokens.COMMA.getToken() + binding.getIndex());
            }
            writeNewline(ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.COMMA.getToken());
        }
        else if (bindings.size() == 1)
            writeNewline(bindings.get(0).getIndex() + ASEmitterTokens.COMMA.getToken());
        else
            writeNewline("null" + ASEmitterTokens.COMMA.getToken());

    }

    //--------------------------------------------------------------------------

    protected void emitScripts()
    {
        for (IMXMLScriptNode node : scripts)
        {
            IASEmitter asEmitter = ((IMXMLBlockWalker) getMXMLWalker())
                    .getASEmitter();

            int len = node.getChildCount();
            if (len > 0)
            {
                for (int i = 0; i < len; i++)
                {
                    IASNode cnode = node.getChild(i);
                    if (cnode.getNodeID() == ASTNodeID.VariableID) {
                        ((JSRoyaleEmitter) asEmitter).getModel().getVars().add((IVariableNode) cnode);
                    } else {
                        if (cnode.getNodeID() == ASTNodeID.BindableVariableID) {
                            IVariableNode variableNode = (IVariableNode) cnode;
                            BindableVarInfo bindableVarInfo = new BindableVarInfo();
                            bindableVarInfo.isStatic = variableNode.hasModifier(ASModifier.STATIC);;
                            bindableVarInfo.namespace = variableNode.getNamespace();
                            IMetaTagsNode metaTags = variableNode.getMetaTags();
                            if (metaTags != null) {
                                IMetaTagNode[] tags = metaTags.getAllTags();
                                if (tags.length > 0)
                                    bindableVarInfo.metaTags = tags;
                            }

                            String bindableVarType = "*";
                            IExpressionNode variableTypeNode = variableNode.getVariableTypeNode();
                            if (variableTypeNode != null)
                            {
                                bindableVarType = variableTypeNode.resolveType(getMXMLWalker().getProject()).getQualifiedName();
                            }
                            bindableVarInfo.type = bindableVarType;
                            ((JSRoyaleEmitter) asEmitter).getModel().getBindableVars().put(variableNode.getName(), bindableVarInfo);
                        }
                    }

                    if (!(cnode instanceof IImportNode))
                    {
                        asEmitter.getWalker().walk(cnode);
                        write(ASEmitterTokens.SEMICOLON.getToken());

                        if (i == len - 1)
                            indentPop();

                        writeNewline();
                        writeNewline();
                        writeNewline();
                    }
                }
            }
        }
    }

    //--------------------------------------------------------------------------

    protected void emitEvents(String cname)
    {
        for (MXMLEventSpecifier event : events)
        {
            writeNewline("/**");
	        if (emitExports)
	        	writeNewline(" * @export");
            writeNewline(" * @param {" + formatQualifiedName(event.type) + "} event");
            writeNewline(" */");
            writeNewline(formatQualifiedName(cname)
                    + ".prototype." + event.eventHandler + " = function(event)");
            writeNewline(ASEmitterTokens.BLOCK_OPEN, true);


            IASEmitter asEmitter = ((IMXMLBlockWalker) getMXMLWalker())
                    .getASEmitter();

            IMXMLEventSpecifierNode node = event.node;
            int len = node.getChildCount();
            for (int i = 0; i < len; i++)
            {
                if (i > 0)
                {
                    writeNewline();
                }
                IASNode cnode = node.getChild(i);
                asEmitter.getWalker().walk(cnode);
                write(ASEmitterTokens.SEMICOLON);
            }

            indentPop();
            writeNewline();
            write(ASEmitterTokens.BLOCK_CLOSE);
            writeNewline(ASEmitterTokens.SEMICOLON);
            writeNewline();
            writeNewline();
        }
    }

    //--------------------------------------------------------------------------
    private boolean skippedDefineProps;

    protected void emitPropertyGetterSetters(String cname)
    {
    	int n = 0;
        for (MXMLDescriptorSpecifier instance : instances)
        {
            if (instance.id != null || instance.hasLocalId)
            {
            	n++;
            }
        }
    	if (n == 0 && (descriptorTree.size() == 0 ||
    			       descriptorTree.size() == 1 && descriptorTree.get(0).propertySpecifiers.size() == 0))
    	{
    		skippedDefineProps = true;
    		return;
    	}

    	String formattedCName = formatQualifiedName(cname);

        write(JSGoogEmitterTokens.OBJECT);
        write(ASEmitterTokens.MEMBER_ACCESS);
        write(JSEmitterTokens.DEFINE_PROPERTIES);
        write(ASEmitterTokens.PAREN_OPEN);
    	write(formattedCName);
        write(ASEmitterTokens.MEMBER_ACCESS);
        write(JSEmitterTokens.PROTOTYPE);
        write(ASEmitterTokens.COMMA);
        write(ASEmitterTokens.SPACE);
        write("/** @lends {");
        write(formattedCName);
        write(ASEmitterTokens.MEMBER_ACCESS);
        write(JSEmitterTokens.PROTOTYPE);
    	write("} */ {");
        indentPush();
        writeNewline();
        int i = 0;
        for (MXMLDescriptorSpecifier instance : instances)
        {
        	String instanceId = instance.id;
        	if (instanceId == null && instance.hasLocalId ){
        		instanceId = instance.effectiveId;
			}
            if (instanceId != null)
            {
                indentPush();
                writeNewline(instanceId + ": {");
                writeNewline("/** @this {" + formattedCName + "} */");
                indentPush();
                writeNewline("get: function() {");
                indentPop();
                writeNewline("return this." + instanceId + "_;");
                writeNewline("},");
                writeNewline("/** @this {" + formattedCName + "} */");
                indentPush();
                writeNewline("set: function(value) {");
                indentPush();
                writeNewline("if (value != this." + instanceId + "_) {");
                writeNewline("this." + instanceId + "_ = value;");
                write("this.dispatchEvent(org.apache.royale.events.ValueChangeEvent.createUpdateEvent(this, '");
                indentPop();
                writeNewline(instanceId + "', null, value));");
                indentPop();
                writeNewline("}");
                indentPop();
                writeNewline("}");
                if (i < n - 1 || descriptorTree.size() > 0)
                	writeNewline("},");
                else
                {
                    indentPop();
                    writeNewline("}");
                }
                i++;
            }
        }
        if (descriptorTree.size() == 0)
        	writeNewline("});");
    }

    //--------------------------------------------------------------------------

    protected void emitMXMLDescriptorFuncs(String cname)
    {
        // top level is 'mxmlContent', skip it...
        if (descriptorTree.size() > 0)
        {
            RoyaleJSProject project = (RoyaleJSProject) getMXMLWalker().getProject();
            project.needLanguage = true;
            MXMLDescriptorSpecifier root = descriptorTree.get(0);
            if (root.propertySpecifiers.size() == 0 && skippedDefineProps)
            	return; // all declarations were primitives
            root.isTopNode = false;

            collectExportedNames(root);

            indentPush();
            writeNewline("'MXMLDescriptor': {");
            writeNewline("/** @this {" + formatQualifiedName(cname) + "} */");
            indentPush();
            writeNewline("get: function() {");
            writeNewline("if (this.mxmldd == undefined)");
            indentPush();
            writeNewline("{");
            writeNewline("/** @type {Array} */");
            writeNewline("var arr = " + formatQualifiedName(cname) + ".superClass_.get__MXMLDescriptor.apply(this);");
            writeNewline("/** @type {Array} */");
            indentPush();
            writeNewline("var mxmldd = [");

            mxmlDescriptorEmitter.emit(root);
            indentPop();
            writeNewline();

            writeNewline("];");
            indentPush();
            writeNewline("if (arr)");
            indentPop();
            writeNewline("this.mxmldd = arr.concat(mxmldd);");
            indentPush();
            writeNewline("else");
            indentPop();
            indentPop();
            writeNewline("this.mxmldd = mxmldd;");
            writeNewline("}");
            indentPop();
            writeNewline("return this.mxmldd;");
            indentPop();
            writeNewline("}");
            indentPop();
            writeNewline("}");
            indentPop();
        	writeNewline("});");
        }

    }

    private void collectExportedNames(MXMLDescriptorSpecifier descriptor)
    {
        ICompilerProject project = getMXMLWalker().getProject();
        RoyaleJSProject royaleProject = null;
        if (project instanceof RoyaleJSProject)
        {
            royaleProject = (RoyaleJSProject) project;
            String name = descriptor.name;
            if (name == null)
            	name = this.classDefinition.getQualifiedName();
            for (MXMLDescriptorSpecifier prop : descriptor.propertySpecifiers)
            {
            	String propName = prop.name;
            	royaleProject.addExportedName(/*name + "." + */propName);
            	if (prop.propertySpecifiers.size() > 0)
            	{
                    collectExportedNames(prop.propertySpecifiers.get(0));
            	}
            }
            if (descriptor.childrenSpecifier != null)
            {
                for (MXMLDescriptorSpecifier prop : descriptor.childrenSpecifier.propertySpecifiers)
                {
                	collectExportedNames(prop);
                }
            }
        }
    }

    //--------------------------------------------------------------------------

    private HashMap<IMXMLEventSpecifierNode, String> eventHandlerNameMap = new HashMap<IMXMLEventSpecifierNode, String>();

    @Override
    public void emitEventSpecifier(IMXMLEventSpecifierNode node)
    {
    	IMXMLStateNode currentState = null;
    	if (!inStatesOverride.empty())
    		currentState = inStatesOverride.peek();
        if (isStateDependent(node, currentState, true))
            return;
    		
        IDefinition cdef = node.getDefinition();

        MXMLDescriptorSpecifier currentDescriptor = getCurrentDescriptor("i");

        MXMLEventSpecifier eventSpecifier = new MXMLEventSpecifier();

		IASEmitter asEmitter = ((IMXMLBlockWalker) getMXMLWalker()).getASEmitter();
		JSRoyaleEmitter fjs = (JSRoyaleEmitter)asEmitter;

		IClassDefinition currentClass = fjs.getModel().getCurrentClass();
		//naming needs to avoid conflicts with ancestors - using delta from object which is
		//a) short and b)provides a 'unique' (not zero risk, but very low risk) option
        String nameBase = EmitterUtils.getClassDepthNameBase(MXMLRoyaleEmitterTokens.EVENT_PREFIX
				.getToken(), currentClass, getMXMLWalker().getProject());
        eventSpecifier.eventHandler = nameBase + eventCounter++;
        eventSpecifier.name = cdef.getBaseName();
        eventSpecifier.type = node.getEventParameterDefinition()
                .getTypeAsDisplayString();

        eventHandlerNameMap.put(node, eventSpecifier.eventHandler);

        //save the node for emitting later in emitEvents()
        //previously, we stringified the node and saved that instead of the
        //node, but source maps don't work when you stringify a node too early -JT
        eventSpecifier.node = node;

	    if (currentDescriptor != null)
	        currentDescriptor.eventSpecifiers.add(eventSpecifier);
	    else if (inStatesOverride.empty()) // in theory, if no currentdescriptor must be top tag event
	        propertiesTree.eventSpecifiers.add(eventSpecifier);
        events.add(eventSpecifier);
    }

    @Override
    public void emitInstance(IMXMLInstanceNode node)
    {
    	IMXMLStateNode currentState = null;
    	if (!inStatesOverride.empty())
    		currentState = inStatesOverride.peek();
        if (overrideInstanceToEmit != node && isStateDependent(node, currentState, false))
            return;

        ASTNodeID nodeID = node.getNodeID();
    	if ((nodeID == ASTNodeID.MXMLXMLID || nodeID == ASTNodeID.MXMLXMLListID) &&
    			node.getParent().getNodeID() == ASTNodeID.MXMLDeclarationsID)
    	{
    		primitiveDeclarationNodes.add(node);
    		return;
    	}

        IClassDefinition cdef = node
                .getClassReference((ICompilerProject) getMXMLWalker()
                        .getProject());

        MXMLDescriptorSpecifier currentPropertySpecifier = getCurrentDescriptor("ps");
    	if (nodeID == ASTNodeID.MXMLFunctionID)
    	{
            RoyaleJSProject project = (RoyaleJSProject) getMXMLWalker().getProject();
            project.needLanguage = true;
            MXMLFunctionNode fnode = ((MXMLFunctionNode)node);
            IExpressionNode fexpNode = (IExpressionNode)fnode.getExpressionNode();
            IASEmitter asEmitter = ((IMXMLBlockWalker) getMXMLWalker())
                    .getASEmitter();
            String fNodeString = ((JSRoyaleEmitter)asEmitter).stringifyNode(fexpNode);
    		currentPropertySpecifier.value = fNodeString; 
    		return;
    	}

        String effectiveId = null;
        String id = node.getID();
        if (id == null)
        {
        	effectiveId = node.getEffectiveID();
        	if (effectiveId == null)
        		effectiveId = node.getClassDefinitionNode().getGeneratedID(node);
        }

        MXMLDescriptorSpecifier currentInstance = new MXMLDescriptorSpecifier();
        currentInstance.isProperty = false;
        currentInstance.id = id;
        currentInstance.hasLocalId = node.getLocalID() != null;
        currentInstance.effectiveId = effectiveId;
        currentInstance.name = formatQualifiedName(cdef.getQualifiedName());
        currentInstance.parent = currentPropertySpecifier;

        if (currentPropertySpecifier != null)
            currentPropertySpecifier.propertySpecifiers.add(currentInstance);
        else if (inMXMLContent)
            descriptorTree.add(currentInstance);
        else
        {
        	// we get here if a instance is a child of a top-level tag
        	// and there is no default property.  If there are other
        	// ways to get here, then the code will need adjusting.
        	
        	// this code assumes that the children will have an id
        	// and will just create properties with the children's id
        	// on the class.
        	MXMLDescriptorSpecifier prop = new MXMLDescriptorSpecifier();
        	prop.isProperty = true;
        	prop.name = id;
        	prop.parent = propertiesTree;
        	propertiesTree.propertySpecifiers.add(prop);
            currentInstance.parent = prop;
            prop.propertySpecifiers.add(currentInstance);
        }

        addInstanceIfNeeded(instances, currentInstance);

        IMXMLPropertySpecifierNode[] pnodes = node.getPropertySpecifierNodes();
        if (pnodes != null)
        {
            moveDown(false, currentInstance, null);

            for (IMXMLPropertySpecifierNode pnode : pnodes)
            {
                getMXMLWalker().walk(pnode); // Property Specifier
            }

            moveUp(false, true);
        }
        else if (node instanceof IMXMLStateNode)
        {
            IMXMLStateNode stateNode = (IMXMLStateNode)node;
            String name = stateNode.getStateName();
            if (name != null)
            {
                MXMLDescriptorSpecifier stateName = new MXMLDescriptorSpecifier();
                stateName.isProperty = true;
                stateName.id = id;
                stateName.name = "name";
                stateName.value = ASEmitterTokens.SINGLE_QUOTE.getToken() + name + ASEmitterTokens.SINGLE_QUOTE.getToken();
                stateName.parent = currentInstance;
                currentInstance.propertySpecifiers.add(stateName);
            }
            MXMLDescriptorSpecifier overrides = new MXMLDescriptorSpecifier();
            overrides.isProperty = true;
            overrides.hasArray = true;
            overrides.id = id;
            overrides.name = "overrides";
            overrides.parent = currentInstance;
            currentInstance.propertySpecifiers.add(overrides);
            moveDown(false, null, overrides);

            IMXMLClassDefinitionNode classDefinitionNode = stateNode.getClassDefinitionNode();
            List<IMXMLNode> snodes = classDefinitionNode.getNodesDependentOnState(stateNode.getStateName());
            if (snodes != null)
            {
            	inStatesOverride.push(stateNode);
                for (int i=0; i<snodes.size(); i++)
                {
                    IMXMLNode inode = snodes.get(i);
                    if (inode.getNodeID() == ASTNodeID.MXMLInstanceID)
                    {
                        emitInstanceOverride((IMXMLInstanceNode)inode, stateNode);
                    }
                }
                // Next process the non-instance overrides dependent on this state.
                // Each one will generate code to push an IOverride instance.
                for (IMXMLNode anode : snodes)
                {
                    switch (anode.getNodeID())
                    {
                        case MXMLPropertySpecifierID:
                        {
                            emitPropertyOverride((IMXMLPropertySpecifierNode)anode);
                            break;
                        }
                        case MXMLStyleSpecifierID:
                        {
                            emitStyleOverride((IMXMLStyleSpecifierNode)anode);
                            break;
                        }
                        case MXMLEventSpecifierID:
                        {
                            emitEventOverride((IMXMLEventSpecifierNode)anode);
                            break;
                        }
                        default:
                        {
                            break;
                        }
                    }
                }
            	inStatesOverride.pop();
            }

            moveUp(false, false);
        }

        IMXMLEventSpecifierNode[] enodes = node.getEventSpecifierNodes();
        if (enodes != null)
        {
            moveDown(false, currentInstance, null);

            for (IMXMLEventSpecifierNode enode : enodes)
            {
                getMXMLWalker().walk(enode); // Event Specifier
            }

            moveUp(false, true);
        }
    }

    private void addInstanceIfNeeded(
			ArrayList<MXMLDescriptorSpecifier> instances2,
			MXMLDescriptorSpecifier currentInstance) {
    	for (MXMLDescriptorSpecifier instance : instances2)
    		if (instance.id != null && currentInstance.id != null && instance.id.equals(currentInstance.id))
    			return;
        instances.add(currentInstance);

	}

	public void emitPropertyOverride(IMXMLPropertySpecifierNode propertyNode)
    {
        RoyaleProject project = (RoyaleProject) getMXMLWalker().getProject();
        Name propertyOverride = project.getPropertyOverrideClassName();
        emitPropertyOrStyleOverride(propertyOverride, propertyNode);
    }

    /**
     * Generates instructions in the current context
     * to create an instance of mx.states.SetStyle
     * with its <code>target</code>, <code>name</code>,
     * and <code>value</code> properties set.
     */
    void emitStyleOverride(IMXMLStyleSpecifierNode styleNode)
    {
        RoyaleProject project = (RoyaleProject) getMXMLWalker().getProject();
        Name styleOverride = project.getStyleOverrideClassName();
        emitPropertyOrStyleOverride(styleOverride, styleNode);
    }

    void emitPropertyOrStyleOverride(Name overrideName, IMXMLPropertySpecifierNode propertyOrStyleNode)
    {
        MXMLDescriptorSpecifier currentInstance = getCurrentDescriptor("ps");
        IASNode parentNode = propertyOrStyleNode.getParent();
        String id = parentNode instanceof IMXMLInstanceNode ?
                    ((IMXMLInstanceNode)parentNode).getEffectiveID() :
                    null;

        String name = propertyOrStyleNode.getName();

        boolean valueIsDataBound = isDataBindingNode(propertyOrStyleNode.getChild(0));
        IMXMLInstanceNode propertyOrStyleValueNode = propertyOrStyleNode.getInstanceNode();

        MXMLDescriptorSpecifier setProp = new MXMLDescriptorSpecifier();
        setProp.isProperty = false;
        setProp.name = formatQualifiedName(nameToString(overrideName));
        setProp.parent = currentInstance;
        currentInstance.propertySpecifiers.add(setProp);

        if (id != null)
        {
	            // Set its 'target' property to the id of the object
	            // whose property or style this override will set.
	        MXMLDescriptorSpecifier target = new MXMLDescriptorSpecifier();
	        target.isProperty = true;
	        target.name = "target";
	        target.parent = setProp;
	        target.value = ASEmitterTokens.SINGLE_QUOTE.getToken() + id + ASEmitterTokens.SINGLE_QUOTE.getToken();
	        setProp.propertySpecifiers.add(target);
        }

            // Set its 'name' property to the name of the property or style.
        MXMLDescriptorSpecifier pname = new MXMLDescriptorSpecifier();
        pname.isProperty = true;
        pname.name = "name";
        pname.parent = setProp;
        pname.value = ASEmitterTokens.SINGLE_QUOTE.getToken() + name + ASEmitterTokens.SINGLE_QUOTE.getToken();
        setProp.propertySpecifiers.add(pname);

        if (!valueIsDataBound)
        {
	            // Set its 'value' property to the value of the property or style.
	        MXMLDescriptorSpecifier value = new MXMLDescriptorSpecifier();
	        value.isProperty = true;
	        value.name = "value";
	        value.parent = setProp;
	        setProp.propertySpecifiers.add(value);
	        moveDown(false, null, value);
	        getMXMLWalker().walk(propertyOrStyleValueNode); // instance node
	        moveUp(false, false);
        }
        else
        {
            String overrideID = MXMLRoyaleEmitterTokens.BINDING_PREFIX.getToken() + bindingCounter++;
	        setProp.id = overrideID;
	        instances.add(setProp);
			IRoyaleProject project = (IRoyaleProject)(walker.getProject());
			BindingDatabase bd = project.getBindingMap().get(classDefinition);
	        Set<BindingInfo> bindingInfo = bd.getBindingInfo();
	        IMXMLDataBindingNode bindingNode = (IMXMLDataBindingNode)propertyOrStyleNode.getChild(0);
	        for (BindingInfo bi : bindingInfo)
	        {
	        	if (bi.node == bindingNode)
	        	{
	                bi.setDestinationString(overrideID + ".value");
	                break;
	        	}
	        }
        }
    }

    /**
     * Generates instructions in the current context
     * to create an instance of mx.states.SetEventHandler
     * with its <code>target</code>, <code>name</code>,
     * and <code>handlerFunction</code> properties set.
     */
    void emitEventOverride(IMXMLEventSpecifierNode eventNode)
    {
        MXMLDescriptorSpecifier currentInstance = getCurrentDescriptor("ps");
        RoyaleProject project = (RoyaleProject) getMXMLWalker().getProject();
        Name eventOverride = project.getEventOverrideClassName();

        IASNode parentNode = eventNode.getParent();
        String id = parentNode instanceof IMXMLInstanceNode ?
                    ((IMXMLInstanceNode)parentNode).getEffectiveID() :
                    "";

        String name = MXMLEventSpecifier.getJSEventName(eventNode.getName());

        String eventHandler = eventHandlerNameMap.get(eventNode);
        if (eventHandler == null)
        {
        	emitEventSpecifier(eventNode);
        	eventHandler = eventHandlerNameMap.get(eventNode);
        }

        MXMLDescriptorSpecifier setEvent = new MXMLDescriptorSpecifier();
        setEvent.isProperty = false;
        setEvent.name = formatQualifiedName(nameToString(eventOverride));
        setEvent.parent = currentInstance;
        currentInstance.propertySpecifiers.add(setEvent);
        // Set its 'target' property to the id of the object
        // whose event this override will set.
        MXMLDescriptorSpecifier target = new MXMLDescriptorSpecifier();
        target.isProperty = true;
        target.name = "target";
        target.parent = setEvent;
        target.value = ASEmitterTokens.SINGLE_QUOTE.getToken() + id + ASEmitterTokens.SINGLE_QUOTE.getToken();
        setEvent.propertySpecifiers.add(target);

        // Set its 'name' property to the name of the event.
        MXMLDescriptorSpecifier pname = new MXMLDescriptorSpecifier();
        pname.isProperty = true;
        pname.name = "name";
        pname.parent = setEvent;
        pname.value = ASEmitterTokens.SINGLE_QUOTE.getToken() + name + ASEmitterTokens.SINGLE_QUOTE.getToken();
        setEvent.propertySpecifiers.add(pname);

        // Set its 'handlerFunction' property to the autogenerated event handler.
        MXMLDescriptorSpecifier handler = new MXMLDescriptorSpecifier();
        handler.isProperty = true;
        handler.name = "handlerFunction";
        handler.parent = setEvent;
        handler.value = JSRoyaleEmitterTokens.CLOSURE_FUNCTION_NAME.getToken() + ASEmitterTokens.PAREN_OPEN.getToken() +
        		ASEmitterTokens.THIS.getToken() + ASEmitterTokens.MEMBER_ACCESS.getToken() + eventHandler +
        		ASEmitterTokens.COMMA.getToken() + ASEmitterTokens.SPACE.getToken() + ASEmitterTokens.THIS.getToken() +
        		ASEmitterTokens.COMMA.getToken() + ASEmitterTokens.SPACE.getToken() + ASEmitterTokens.SINGLE_QUOTE.getToken() +
        			eventHandler + ASEmitterTokens.SINGLE_QUOTE.getToken() +
        		ASEmitterTokens.PAREN_CLOSE.getToken();
        setEvent.propertySpecifiers.add(handler);
    }

    public void emitInstanceOverride(IMXMLInstanceNode instanceNode, IMXMLStateNode state)
    {
        MXMLDescriptorSpecifier currentInstance = getCurrentDescriptor("ps");
        RoyaleProject project = (RoyaleProject) getMXMLWalker().getProject();
        Name instanceOverrideName = project.getInstanceOverrideClassName();

        MXMLDescriptorSpecifier overrideInstances = getCurrentDescriptor("so");
        int index = overrideInstances.propertySpecifiers.size();
        if (nodeToIndexMap == null)
        	nodeToIndexMap = new HashMap<IMXMLNode, Integer>();
        if (nodeToIndexMap.containsKey(instanceNode))
        {
        	index = nodeToIndexMap.get(instanceNode);
        }
        else
        {
        	nodeToIndexMap.put(instanceNode, index);
            MXMLDescriptorSpecifier itemsDesc = new MXMLDescriptorSpecifier();
            itemsDesc.isProperty = true;
            itemsDesc.hasArray = true;
            itemsDesc.name = "itemsDescriptor";
            itemsDesc.parent = overrideInstances;
            overrideInstances.propertySpecifiers.add(itemsDesc);
            boolean oldInMXMLContent = inMXMLContent;
            moveDown(false, null, itemsDesc);
            inMXMLContent = true;
            overrideInstanceToEmit = instanceNode;
            getMXMLWalker().walk(instanceNode); // instance node
            overrideInstanceToEmit = null;
            inMXMLContent = oldInMXMLContent;
            moveUp(false, false);
        }

        MXMLDescriptorSpecifier addItems = new MXMLDescriptorSpecifier();
        addItems.isProperty = false;
        addItems.name = formatQualifiedName(nameToString(instanceOverrideName));
        addItems.parent = currentInstance;
        currentInstance.propertySpecifiers.add(addItems);
        MXMLDescriptorSpecifier itemsDescIndex = new MXMLDescriptorSpecifier();
        itemsDescIndex.isProperty = true;
        itemsDescIndex.hasArray = true;
        itemsDescIndex.name = "itemsDescriptorIndex";
        itemsDescIndex.parent = addItems;
        itemsDescIndex.value = Integer.toString(index);
        addItems.propertySpecifiers.add(itemsDescIndex);

        //-----------------------------------------------------------------------------
        // Second property set: maybe set destination and propertyName

        // get the property specifier node for the property the instanceNode represents
        IMXMLPropertySpecifierNode propertySpecifier = (IMXMLPropertySpecifierNode)
            instanceNode.getAncestorOfType( IMXMLPropertySpecifierNode.class);

        if (propertySpecifier == null)
        {
           assert false;        // I think this indicates an invalid tree...
        }
        else
        {
            // Check the parent - if it's an instance then we want to use these
            // nodes to get our property values from. If not, then it's the root
            // and we don't need to specify destination

            IASNode parent = propertySpecifier.getParent();
            if (parent instanceof IMXMLInstanceNode)
            {
               IMXMLInstanceNode parentInstance = (IMXMLInstanceNode)parent;
               String parentId = parentInstance.getEffectiveID();
               assert parentId != null;
               String propName = propertySpecifier.getName();

               MXMLDescriptorSpecifier dest = new MXMLDescriptorSpecifier();
               dest.isProperty = true;
               dest.name = "destination";
               dest.parent = addItems;
               dest.value = ASEmitterTokens.SINGLE_QUOTE.getToken() + parentId + ASEmitterTokens.SINGLE_QUOTE.getToken();
               addItems.propertySpecifiers.add(dest);

               MXMLDescriptorSpecifier prop = new MXMLDescriptorSpecifier();
               prop.isProperty = true;
               prop.name = "propertyName";
               prop.parent = addItems;
               prop.value = ASEmitterTokens.SINGLE_QUOTE.getToken() + propName + ASEmitterTokens.SINGLE_QUOTE.getToken();
               addItems.propertySpecifiers.add(prop);
            }
        }

        //---------------------------------------------------------------
        // Third property set: position and relativeTo
        String positionPropertyValue = null;
        String relativeToPropertyValue = null;

        // look to see if we have any sibling nodes that are not state dependent
        // that come BEFORE us
        IASNode instanceParent = instanceNode.getParent();
        IASNode prevStatelessSibling=null;
        for (int i=0; i< instanceParent.getChildCount(); ++i)
        {
            IASNode sib = instanceParent.getChild(i);
            assert sib instanceof IMXMLInstanceNode;    // surely our siblings are also instances?

            // stop looking for previous nodes when we find ourself
            if (sib == instanceNode)
                break;

            if (sib instanceof IMXMLInstanceNode && !isStateDependent(sib, state, true))
            {
                prevStatelessSibling = sib;
            }
        }

        if (prevStatelessSibling == null) {
            positionPropertyValue = "first";        // TODO: these should be named constants
        }
        else {
            positionPropertyValue = "after";
            relativeToPropertyValue = ((IMXMLInstanceNode)prevStatelessSibling).getEffectiveID();
        }

        MXMLDescriptorSpecifier pos = new MXMLDescriptorSpecifier();
        pos.isProperty = true;
        pos.name = "position";
        pos.parent = addItems;
        pos.value = ASEmitterTokens.SINGLE_QUOTE.getToken() + positionPropertyValue + ASEmitterTokens.SINGLE_QUOTE.getToken();
        addItems.propertySpecifiers.add(pos);

        if (relativeToPropertyValue != null)
        {
            MXMLDescriptorSpecifier rel = new MXMLDescriptorSpecifier();
            rel.isProperty = true;
            rel.name = "relativeTo";
            rel.parent = addItems;
            rel.value = ASEmitterTokens.SINGLE_QUOTE.getToken() + relativeToPropertyValue + ASEmitterTokens.SINGLE_QUOTE.getToken();
            addItems.propertySpecifiers.add(rel);
        }
    }

    private String nameToString(Name name)
    {
        String s;
        Namespace ns = name.getSingleQualifier();
        s = ns.getName();
        if (s != "") s = s + ASEmitterTokens.MEMBER_ACCESS.getToken() + name.getBaseName();
        else s = name.getBaseName();
        return s;
    }
    
    /**
     * Determines whether a string matches a state's name or group name.
     */
    protected boolean inStateOrStateGroup(String name, IMXMLStateNode state)
    {
    	if (state == null) return false;
    	
    	if (name.contentEquals(state.getStateName()))
    		return true;
    	
    	String[] groups = state.getStateGroups();
    	if (groups != null)
    	{
        	for (String s : groups)
        	{
        		if (name.contentEquals(s))
        			return true;
        	}
    	}
    	return false;
    }
    
    /**
     * Determines whether a node is state-dependent.
     * TODO: we should move to IMXMLNode
     */
    protected boolean isStateDependent(IASNode node, IMXMLStateNode currentState, boolean includeGroups)
    {
        if (node instanceof IMXMLSpecifierNode)
        {
            String suffix = ((IMXMLSpecifierNode)node).getSuffix();
            return suffix != null && suffix.length() > 0 && !inStateOrStateGroup(suffix, currentState);
        }
        else if (isStateDependentInstance(node, currentState, includeGroups))
            return true;
        return false;
    }

    /**
     * Determines whether the geven node is an instance node, as is state dependent
     */
    protected boolean isStateDependentInstance(IASNode node, IMXMLStateNode currentState, boolean includeGroups)
    {
        if (node instanceof IMXMLInstanceNode)
        {
            String[] includeIn = ((IMXMLInstanceNode)node).getIncludeIn();
            String[] excludeFrom = ((IMXMLInstanceNode)node).getExcludeFrom();
            if (includeGroups)
            {
	            if (includeIn != null && currentState != null)
	               for (String s : includeIn)
	                   if (inStateOrStateGroup(s, currentState)) return false;
	            if (excludeFrom != null && currentState != null)
	            {
	               for (String s : excludeFrom)
	                   if (inStateOrStateGroup(s, currentState)) return true;
	               return false;
	            }
            }
            return includeIn != null || excludeFrom != null;
        }
        return false;
    }

    /**
     * Is a give node a "databinding node"?
     */
    public static boolean isDataBindingNode(IASNode node)
    {
        return node instanceof IMXMLDataBindingNode;
    }

    protected static boolean isDataboundProp(IMXMLPropertySpecifierNode propertyNode)
    {
        boolean ret = propertyNode.getChildCount() > 0 && isDataBindingNode(propertyNode.getInstanceNode());

        // Sanity check that we based our conclusion about databinding on the correct node.
        // (code assumes only one child if databinding)
        int n = propertyNode.getChildCount();
        for (int i = 0; i < n; i++)
        {
            boolean db = isDataBindingNode(propertyNode.getChild(i));
            assert db == ret;
        }

        return ret;
    }

    @Override
    public void emitPropertySpecifier(IMXMLPropertySpecifierNode node)
    {
        if (isDataboundProp(node))
            return;

        if (isStateDependent(node, null, true))
            return;

        IDefinition cdef = node.getDefinition();

        IASNode cnode = node.getChild(0);

        MXMLDescriptorSpecifier currentInstance = getCurrentDescriptor("i");

        MXMLDescriptorSpecifier currentPropertySpecifier = new MXMLDescriptorSpecifier();
        currentPropertySpecifier.isProperty = true;
        currentPropertySpecifier.name = cdef != null ? cdef.getQualifiedName() : node.getName();
        currentPropertySpecifier.parent = currentInstance;

        boolean oldInMXMLContent = inMXMLContent;
        boolean reusingDescriptor = false;
        if (currentPropertySpecifier.name.equals("mxmlContent"))
        {
            inMXMLContent = true;
            ArrayList<MXMLDescriptorSpecifier> specList =
            	(currentInstance == null) ? descriptorTree : currentInstance.propertySpecifiers;
            for (MXMLDescriptorSpecifier ds : specList)
            {
            	if (ds.name.equals("mxmlContent"))
            	{
            		currentPropertySpecifier = ds;
            		reusingDescriptor = true;
            		break;
            	}
            }
        }

        if (currentInstance != null)
        {
        	// we end up here for children of tags
        	if (!reusingDescriptor)
        		currentInstance.propertySpecifiers.add(currentPropertySpecifier);
        }
        else if (inMXMLContent)
        {
        	// we end up here for top tags?
        	if (!reusingDescriptor)
        		descriptorTree.add(currentPropertySpecifier);
        }
        else
        {
            currentPropertySpecifier.parent = propertiesTree;
            propertiesTree.propertySpecifiers.add(currentPropertySpecifier);
        }

        boolean valueIsArray = cnode != null && cnode instanceof IMXMLArrayNode;
        boolean valueIsObject = cnode != null && cnode instanceof IMXMLObjectNode;

        currentPropertySpecifier.hasArray = valueIsArray;
        currentPropertySpecifier.hasObject = valueIsObject;

        moveDown(false, null, currentPropertySpecifier);

        getMXMLWalker().walk(cnode); // Array or Instance

        moveUp(false, false);

        inMXMLContent = oldInMXMLContent;
    }

    @Override
    public void emitScript(IMXMLScriptNode node)
    {
        //save the script for emitting later in emitScripts()
        //previously, we stringified the node and saved that instead of the
        //node, but source maps don't work when you stringify a node too early -JT
        scripts.add(node);
    }

    @Override
    public void emitStyleSpecifier(IMXMLStyleSpecifierNode node)
    {
    }

    //--------------------------------------------------------------------------

    @Override
    public void emitObject(IMXMLObjectNode node)
    {
        final int len = node.getChildCount();
    	if (!makingSimpleArray)
    	{
            MXMLDescriptorSpecifier ps = getCurrentDescriptor("ps");
			//GD - hasArray below allows a dataProvider with <fx:Object's>
            if (ps.hasObject || ps.hasArray || ps.parent == null) //('ps.parent == null' was added to allow a top level fx:Object definition, they were not being output without that)
            {
            	emitInstance(node);
            	return;
            }
            for (int i = 0; i < len; i++)
            {
                getMXMLWalker().walk(node.getChild(i)); // props in object
            }
    	}
    	else
    	{
            MXMLDescriptorSpecifier ps = getCurrentDescriptor("ps");
            if (ps.value == null)
            	ps.value = "";
            ps.value += "{";
            for (int i = 0; i < len; i++)
            {
                IMXMLPropertySpecifierNode propName = (IMXMLPropertySpecifierNode)node.getChild(i);
                ps.value += propName.getName() + ": ";
                getMXMLWalker().walk(propName.getChild(0));
                if (i < len - 1)
                    ps.value += ", ";
            }
            ps.value += "}";
    	}
    }

    @Override
    public void emitArray(IMXMLArrayNode node)
    {
    	if (node.getParent().getNodeID() == ASTNodeID.MXMLDeclarationsID)
    	{
    		primitiveDeclarationNodes.add(node);
    		return;
    	}

        boolean isSimple = true;
        final int len = node.getChildCount();
        for (int i = 0; i < len; i++)
        {
            final IASNode child = node.getChild(i);
            ASTNodeID nodeID = child.getNodeID();
			//a single <fx:Object> inside an array also makes it non-simple (@todo test mixed simple and non-simple)
            if (nodeID == ASTNodeID.MXMLArrayID || nodeID == ASTNodeID.MXMLInstanceID || nodeID == ASTNodeID.MXMLObjectID || nodeID == ASTNodeID.MXMLStateID)
            {
                isSimple = false;
                break;
            }
        }
        boolean oldMakingSimpleArray = makingSimpleArray;
        MXMLDescriptorSpecifier ps = getCurrentDescriptor("ps");
        if (isSimple)
        {
        	makingSimpleArray = true;
        	ps.value = ASEmitterTokens.SQUARE_OPEN.getToken();
        }
        for (int i = 0; i < len; i++)
        {
            getMXMLWalker().walk(node.getChild(i)); // Instance
            if (isSimple && i < len - 1)
            	ps.value += ASEmitterTokens.COMMA.getToken();
        }
        if (isSimple)
        {
        	ps.value += ASEmitterTokens.SQUARE_CLOSE.getToken();
        }
        makingSimpleArray = oldMakingSimpleArray;

    }

    @Override
    public void emitBoolean(IMXMLBooleanNode node)
    {
    	if (node.getParent().getNodeID() == ASTNodeID.MXMLDeclarationsID)
    	{
    		primitiveDeclarationNodes.add(node);
    		return;
    	}
    	super.emitBoolean(node);
    }
    
    @Override
    public void emitNumber(IMXMLNumberNode node)
    {
    	if (node.getParent().getNodeID() == ASTNodeID.MXMLDeclarationsID)
    	{
    		primitiveDeclarationNodes.add(node);
    		return;
    	}
    	super.emitNumber(node);
    }
    
    @Override
    public void emitInt(IMXMLIntNode node)
    {
    	if (node.getParent().getNodeID() == ASTNodeID.MXMLDeclarationsID)
    	{
    		primitiveDeclarationNodes.add(node);
    		return;
    	}
    	super.emitInt(node);
    }
    
    @Override
    public void emitUint(IMXMLUintNode node)
    {
    	if (node.getParent().getNodeID() == ASTNodeID.MXMLDeclarationsID)
    	{
    		primitiveDeclarationNodes.add(node);
    		return;
    	}
    	super.emitUint(node);
    }
    
    @Override
    public void emitString(IMXMLStringNode node)
    {
    	if (node.getParent().getNodeID() == ASTNodeID.MXMLDeclarationsID)
    	{
    		primitiveDeclarationNodes.add(node);
    		return;
    	}
        getCurrentDescriptor("ps").valueNeedsQuotes = true;

        emitAttributeValue(node);
    }
    
    @Override
    public void emitMXMLClass(IMXMLClassNode node)
    {   
    	RoyaleJSProject project = (RoyaleJSProject)getMXMLWalker().getProject();
    	ITypeDefinition cdef = node.getValue(project);
    	String qname = formatQualifiedName(cdef.getQualifiedName());
    	ICompilationUnit classCU = project.resolveQNameToCompilationUnit(qname);
    	ICompilationUnit cu = project.resolveQNameToCompilationUnit(classDefinition.getQualifiedName());
    	project.addDependency(cu, classCU, DependencyType.EXPRESSION, qname);
        MXMLDescriptorSpecifier ps = getCurrentDescriptor("ps");
        ps.value = qname;
    }

    //--------------------------------------------------------------------------

    @Override
    public void emitLiteral(IMXMLLiteralNode node)
    {
        MXMLDescriptorSpecifier ps = getCurrentDescriptor("ps");
        if (ps.value == null) // might be non-null if makingSimpleArray
        	ps.value = "";

        if (ps.valueNeedsQuotes)
            ps.value += ASEmitterTokens.SINGLE_QUOTE.getToken();

        String s = node.getValue().toString();
        if (ps.valueNeedsQuotes)
        {
            // escape all single quotes found within the string
            s = s.replace(ASEmitterTokens.SINGLE_QUOTE.getToken(),
                    "\\" + ASEmitterTokens.SINGLE_QUOTE.getToken());
        }
        s = s.replace("\r\n", "\\n");
        s = s.replace("\n", "\\n");
        ps.value += s;

        if (ps.valueNeedsQuotes)
            ps.value += ASEmitterTokens.SINGLE_QUOTE.getToken();
    }

    //--------------------------------------------------------------------------

    @Override
    public void emitFactory(IMXMLFactoryNode node)
    {
        IASNode cnode = node.getChild(0);
    	ITypeDefinition type = ((IMXMLClassNode)cnode).getValue(getMXMLWalker().getProject());
    	if (type == null) return;

        MXMLDescriptorSpecifier ps = getCurrentDescriptor("ps");
        ps.value = "new " + formatQualifiedName("org.apache.royale.core.ClassFactory") + "(";

        if (cnode instanceof IMXMLClassNode)
        {
            ps.value += formatQualifiedName(type.getQualifiedName());
        }
        ps.value += ")";
    }

    //--------------------------------------------------------------------------

    @Override
    public void emitComponent(IMXMLComponentNode node)
    {
        MXMLDescriptorSpecifier ps = getCurrentDescriptor("ps");
        ps.value = "new " + formatQualifiedName("org.apache.royale.core.ClassFactory") + "(";

        ps.value += formatQualifiedName(documentDefinition.getQualifiedName()) + ".";
        ps.value += formatQualifiedName(node.getName());
        ps.value += ")";

        setBufferWrite(true);
        emitSubDocument(node);
        subDocuments.append(getBuilder().toString());
        getBuilder().setLength(0);
        setBufferWrite(false);
    }

    @Override
    protected void setBufferWrite(boolean value)
    {
    	super.setBufferWrite(value);
        IASEmitter asEmitter = ((IMXMLBlockWalker) getMXMLWalker()).getASEmitter();
        ((JSRoyaleEmitter)asEmitter).setBufferWrite(value);
    }

    //--------------------------------------------------------------------------
    //    JS output
    //--------------------------------------------------------------------------

    private void emitHeader(IMXMLDocumentNode node)
    {
        String cname = node.getFileNode().getName();
        String bcname = node.getBaseClassName();

        RoyaleJSProject project = (RoyaleJSProject) getMXMLWalker().getProject();
        List<File> sourcePaths = project.getSourcePath();
        String sourceName = node.getSourcePath();
        for (File sourcePath : sourcePaths)
        {
            if (sourceName.startsWith(sourcePath.getAbsolutePath()))
            {
            	sourceName = sourceName.substring(sourcePath.getAbsolutePath().length() + 1);
            }
        }
        writeNewline("/**");
        writeNewline(" * Generated by Apache Royale Compiler from " + sourceName.replace('\\', '/'));
        writeNewline(" * " + cname);
        writeNewline(" *");
        writeNewline(" * @fileoverview");
        writeNewline(" *");
        writeNewline(" * @suppress {checkTypes|accessControls}");
        writeNewline(" */");
        writeNewline();

        ArrayList<String> writtenInstances = new ArrayList<String>();
        emitHeaderLine(cname, true); // provide
        for (String subDocumentName : subDocumentNames)
        {
            emitHeaderLine(subDocumentName, true);
            writtenInstances.add(formatQualifiedName(subDocumentName));
        }
        writeNewline();
        emitHeaderLine(bcname);
        writtenInstances.add(formatQualifiedName(cname)); // make sure we don't add ourselves
        writtenInstances.add(formatQualifiedName(bcname)); // make sure we don't add the baseclass twice
        allInstances.addAll(0, instances);
        for (MXMLDescriptorSpecifier instance : allInstances)
        {
            String name = instance.name;
            if (writtenInstances.indexOf(name) == -1)
            {
                emitHeaderLine(name);
                writtenInstances.add(name);
            }
        }
        ASProjectScope projectScope = (ASProjectScope) project.getScope();
        IDefinition cdef = node.getDefinition();
        ICompilationUnit cu = projectScope
                .getCompilationUnitForDefinition(cdef);
        ArrayList<String> deps = project.getRequires(cu);

        // TODO (mschmalle) will remove this cast as more things get abstracted
        JSRoyaleEmitter fjs = (JSRoyaleEmitter) ((IMXMLBlockWalker) getMXMLWalker())
                .getASEmitter();
        if (fjs.getModel().hasStaticBindableVars()) {
            //we need to add EventDispatcher
            if (deps.indexOf(BindableEmitter.DISPATCHER_CLASS_QNAME) == -1)
                deps.add(BindableEmitter.DISPATCHER_CLASS_QNAME);
            if (usedNames.indexOf(BindableEmitter.DISPATCHER_CLASS_QNAME) == -1)
                usedNames.add(BindableEmitter.DISPATCHER_CLASS_QNAME);
        }

        if (interfaceList != null)
        {
        	String[] interfaces = interfaceList.split(", ");
        	for (String iface : interfaces)
        	{
        		deps.add(iface);
        		usedNames.add(iface);
        	}
        }
        if (deps != null)
        {
        	Collections.sort(deps);
            for (String imp : deps)
            {
                if (imp.indexOf(JSGoogEmitterTokens.AS3.getToken()) != -1)
                    continue;

                if (imp.equals(cname))
                    continue;

                if (imp.equals("mx.binding.Binding"))
                    continue;
                if (imp.equals("mx.binding.BindingManager"))
                    continue;
                if (imp.equals("mx.binding.FunctionReturnWatcher"))
                    continue;
                if (imp.equals("mx.binding.PropertyWatcher"))
                    continue;
                if (imp.equals("mx.binding.StaticPropertyWatcher"))
                    continue;
                if (imp.equals("mx.binding.XMLWatcher"))
                    continue;
                if (imp.equals("mx.events.PropertyChangeEvent"))
                    continue;
                if (imp.equals("mx.events.PropertyChangeEventKind"))
                    continue;
                if (imp.equals("mx.core.DeferredInstanceFromFunction"))
                    continue;

                if (NativeUtils.isNative(imp))
                    continue;

                String formatted = formatQualifiedName(imp, false);
                if (writtenInstances.indexOf(formatted) == -1)
                {
                    emitHeaderLine(imp);
                    writtenInstances.add(formatted);
                }
            }
        }

        // erikdebruin: Add missing language feature support, like the 'is' and
        //              'as' operators. We don't need to worry about requiring
        //              this in every project: ADVANCED_OPTIMISATIONS will NOT
        //              include any of the code if it is not used in the project.
        if (project.mainCU != null &&
                cu.getName().equals(project.mainCU.getName()))
        {
            if (project instanceof RoyaleJSProject)
            {
            	if (((RoyaleJSProject)project).needLanguage)
            		emitHeaderLine(JSRoyaleEmitterTokens.LANGUAGE_QNAME.getToken());
            }
        }

        writeNewline();
        writeNewline();
    }

    private void emitHeaderLine(String qname)
    {
        emitHeaderLine(qname, false);
    }

    private void emitHeaderLine(String qname, boolean isProvide)
    {
        write((isProvide) ? JSGoogEmitterTokens.GOOG_PROVIDE
                : JSGoogEmitterTokens.GOOG_REQUIRE);
        write(ASEmitterTokens.PAREN_OPEN);
        write(ASEmitterTokens.SINGLE_QUOTE);
        write(formatQualifiedName(qname, false));
        write(ASEmitterTokens.SINGLE_QUOTE);
        write(ASEmitterTokens.PAREN_CLOSE);
        writeNewline(ASEmitterTokens.SEMICOLON);
    }

    private String createRequireLine(String qname, boolean isProvide) {
        StringBuilder createHeader = new StringBuilder();
        createHeader.append(isProvide ? JSGoogEmitterTokens.GOOG_PROVIDE.getToken() : JSGoogEmitterTokens.GOOG_REQUIRE.getToken());
        createHeader.append(ASEmitterTokens.PAREN_OPEN.getToken());
        createHeader.append(ASEmitterTokens.SINGLE_QUOTE.getToken());
        createHeader.append(qname);
        createHeader.append(ASEmitterTokens.SINGLE_QUOTE.getToken());
        createHeader.append(ASEmitterTokens.PAREN_CLOSE.getToken());
        createHeader.append(ASEmitterTokens.SEMICOLON.getToken());
        return createHeader.toString();
    }

    //--------------------------------------------------------------------------
    //    Utils
    //--------------------------------------------------------------------------

    @Override
    protected void emitAttributeValue(IASNode node)
    {
        IMXMLLiteralNode cnode = (IMXMLLiteralNode) node.getChild(0);

        if (cnode.getValue() != null)
            getMXMLWalker().walk((IASNode) cnode); // Literal
    }

    private MXMLDescriptorSpecifier getCurrentDescriptor(String type)
    {
        MXMLDescriptorSpecifier currentDescriptor = null;

        int index;

        if (type.equals("i"))
        {
            index = currentInstances.size() - 1;
            if (index > -1)
                currentDescriptor = currentInstances.get(index);
        }
        else if (type.equals("so"))
        {
            return currentStateOverrides;
        }
        else
        {
            index = currentPropertySpecifiers.size() - 1;
            if (index > -1)
                currentDescriptor = currentPropertySpecifiers.get(index);
        }

        return currentDescriptor;
    }

    protected void moveDown(boolean byPass,
            MXMLDescriptorSpecifier currentInstance,
            MXMLDescriptorSpecifier currentPropertySpecifier)
    {
        if (!byPass)
        {
            if (currentInstance != null)
                currentInstances.add(currentInstance);
        }

        if (currentPropertySpecifier != null)
            currentPropertySpecifiers.add(currentPropertySpecifier);
    }

    protected void moveUp(boolean byPass, boolean isInstance)
    {
        if (!byPass)
        {
            int index;

            if (isInstance)
            {
                index = currentInstances.size() - 1;
                if (index > -1)
                    currentInstances.remove(index);
            }
            else
            {
                index = currentPropertySpecifiers.size() - 1;
                if (index > -1)
                    currentPropertySpecifiers.remove(index);
            }
        }
    }

    public String formatQualifiedName(String name)
    {
    	return formatQualifiedName(name, true);
    }

    protected String formatQualifiedName(String name, boolean useName)
    {
    	/*
    	if (name.contains("goog.") || name.startsWith("Vector."))
    		return name;
    	name = name.replaceAll("\\.", "_");
    	*/
    	if (subDocumentNames.contains(name))
    		return documentDefinition.getQualifiedName() + "." + name;
        if (NativeUtils.isJSNative(name)) return name;
        if (inStaticInitializer)
        {
            if (!staticUsedNames.contains(name) && !NativeUtils.isJSNative(name) && isGoogProvided(name))
            {
                staticUsedNames.add(name);
            }
        }

        if (useName && !usedNames.contains(name) && isGoogProvided(name))
        {
            usedNames.add(name);
        }
     	return name;
    }

    @SuppressWarnings("incomplete-switch")
	private void emitComplexInitializers(IASNode node)
    {
        boolean wroteSelf = false;
        int n = node.getChildCount();
    	for (int i = 0; i < n; i++)
    	{
    		IASNode child = node.getChild(i);
    		if (child.getNodeID() == ASTNodeID.MXMLScriptID)
    		{
    			int m = child.getChildCount();
    			for (int j = 0; j < m; j++)
    			{
    				IASNode schild = child.getChild(j);
    				ASTNodeID schildID = schild.getNodeID();
    				if (schildID == ASTNodeID.VariableID ||
    						schildID == ASTNodeID.BindableVariableID)
    				{
    					IVariableNode varnode = (IVariableNode)schild;
    			        IExpressionNode vnode = varnode.getAssignedValueNode();

                        if (vnode != null && (!EmitterUtils.isScalar(vnode)))
    			        {
    	                    IDefinition varDef = varnode.getDefinition();
    	                    if (varDef.isStatic())
                            {
    	                    	continue;
                            }
                            if(!wroteSelf && vnode instanceof IFunctionObjectNode)
                            {
                                writeNewline();
                                writeToken(ASEmitterTokens.VAR);
                                writeToken(JSGoogEmitterTokens.SELF);
                                writeToken(ASEmitterTokens.EQUAL);
                                write(ASEmitterTokens.THIS);
                                writeNewline(ASEmitterTokens.SEMICOLON);
                                wroteSelf = true;
                            }
    	                    writeNewline();
    	                    write(ASEmitterTokens.THIS);
    	                    write(ASEmitterTokens.MEMBER_ACCESS);
    	                    JSRoyaleEmitter fjs = (JSRoyaleEmitter) ((IMXMLBlockWalker) getMXMLWalker())
    	                    .getASEmitter();
    	                    
    	                    ICompilerProject project = getMXMLWalker().getProject();
    	                    String qname = varnode.getName();
	                		if (varDef != null && varDef.isPrivate() && project.getAllowPrivateNameConflicts())
	                			qname = fjs.formatPrivateName(varDef.getParent().getQualifiedName(), qname);
	                        if (EmitterUtils.isCustomNamespace(varnode.getNamespace())) {
	                            INamespaceDecorationNode ns = ((VariableNode) varnode).getNamespaceNode();
	                            INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
	                            fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names
	                            String s = nsDef.getURI();
	                            write(JSRoyaleEmitter.formatNamespacedProperty(s, qname, false));
	                        }
	                        else write(qname);
    	                    if (schildID == ASTNodeID.BindableVariableID && !varnode.isConst())
    	                    	write("_"); // use backing variable
    	                    write(ASEmitterTokens.SPACE);
    	                    writeToken(ASEmitterTokens.EQUAL);
                            IDefinition varTypeDef = null;
                            IExpressionNode variableTypeNode = varnode.getVariableTypeNode();
                            if (variableTypeNode != null)
                            {
                                varTypeDef = variableTypeNode.resolve(getMXMLWalker().getProject());
                            }
                            fjs.emitAssignmentCoercion(vnode, varTypeDef);
    	                    write(ASEmitterTokens.SEMICOLON);

    			        }
    				}
    			}
    		}
    	}
    	n = primitiveDeclarationNodes.size();
    	for (int i = 0; i < n; i++)
    	{
    		IMXMLInstanceNode declNode = primitiveDeclarationNodes.get(i);
    		ASTNodeID nodeId = declNode.getNodeID();
    		String varname;

    		switch (nodeId)
    		{
	    		case MXMLStringID:
	    		{
	    			IMXMLStringNode stringNode = (IMXMLStringNode)declNode;
                    IASNode expressionNode = stringNode.getExpressionNode();
                    // it might be a binding expression instead of a literal
                    if (expressionNode instanceof IMXMLLiteralNode)
                    {
                        varname = stringNode.getEffectiveID();
                        writeNewline();
                        write(ASEmitterTokens.THIS);
                        write(ASEmitterTokens.MEMBER_ACCESS);
                        write(varname);
                        write(ASEmitterTokens.SPACE);
                        writeToken(ASEmitterTokens.EQUAL);
                        IMXMLLiteralNode valueNode = (IMXMLLiteralNode) expressionNode;
                        Object value = valueNode.getValue();
                        write(objectToString(value));
                        write(ASEmitterTokens.SEMICOLON);
                    }
	                break;
	    		}
				case MXMLArrayID:
				{
					IMXMLArrayNode arrayNode = (IMXMLArrayNode)declNode;
                    int m = arrayNode.getChildCount();
                    boolean isDataBinding = false;
                    if(m == 1)
                    {
                        IASNode child = arrayNode.getChild(0);
                        isDataBinding = child instanceof IMXMLDataBindingNode;
                    }
                    if (!isDataBinding)
                    {
                        varname = arrayNode.getEffectiveID();
                        writeNewline();
                        write(ASEmitterTokens.THIS);
                        write(ASEmitterTokens.MEMBER_ACCESS);
                        write(varname);
                        write(ASEmitterTokens.SPACE);
                        writeToken(ASEmitterTokens.EQUAL);
                        write(ASEmitterTokens.SQUARE_OPEN);
                        boolean firstOne = true;
                        for (int j = 0; j < m; j++)
                        {
                            IMXMLInstanceNode valueNode = (IMXMLInstanceNode)(arrayNode.getChild(j));
                            if (firstOne)
                                firstOne = false;
                            else
                                writeToken(ASEmitterTokens.COMMA);
                            write(instanceToString(valueNode));
                        }
                        write(ASEmitterTokens.SQUARE_CLOSE);
                        write(ASEmitterTokens.SEMICOLON);
                    }
		            break;
				}
				case MXMLXMLID:
				{
					IMXMLXMLNode xmlNode = (IMXMLXMLNode)declNode;
					String valueString = xmlNode.getXMLString();
					if (valueString != null)
					{
						varname = xmlNode.getEffectiveID();
			            writeNewline();
			            write(ASEmitterTokens.THIS);
			            write(ASEmitterTokens.MEMBER_ACCESS);
			            write(varname);
			            write(ASEmitterTokens.SPACE);
			            writeToken(ASEmitterTokens.EQUAL);
			            write("new XML('");
				        write(StringEscapeUtils.escapeJavaScript(valueString));
			            write("')");
			            write(ASEmitterTokens.SEMICOLON);
					}
		            break;
				}
				case MXMLXMLListID:
				{
					IMXMLXMLListNode xmlNode = (IMXMLXMLListNode)declNode;
					String valueString = xmlNode.getXMLString();
					if (valueString != null)
					{
						varname = xmlNode.getEffectiveID();
			            writeNewline();
			            write(ASEmitterTokens.THIS);
			            write(ASEmitterTokens.MEMBER_ACCESS);
			            write(varname);
			            write(ASEmitterTokens.SPACE);
			            writeToken(ASEmitterTokens.EQUAL);
			            write("new XMLList('");
				        write(StringEscapeUtils.escapeJavaScript(valueString));
			            write("')");
			            write(ASEmitterTokens.SEMICOLON);
					}
		            break;
				}
	    		case MXMLBooleanID:
	    		case MXMLNumberID:
	    		case MXMLIntID:
	    		case MXMLUintID:
				{
	    			IMXMLExpressionNode scalarNode = (IMXMLExpressionNode)declNode;
                    IASNode expressionNode = scalarNode.getExpressionNode();
                    // it might be a binding expression instead of a literal
                    if (expressionNode instanceof IMXMLLiteralNode)
                    {
                        varname = scalarNode.getEffectiveID();
                        writeNewline();
                        write(ASEmitterTokens.THIS);
                        write(ASEmitterTokens.MEMBER_ACCESS);
                        write(varname);
                        write(ASEmitterTokens.SPACE);
                        writeToken(ASEmitterTokens.EQUAL);
                        IMXMLLiteralNode valueNode = (IMXMLLiteralNode) expressionNode;
                        Object value = valueNode.getValue();
                        write(value.toString());
                        write(ASEmitterTokens.SEMICOLON);
                    }
	                break;
				}

    		}
    	}
    }

    private String objectToString(Object value)
    {
    	if (value instanceof String)
    	{
    		String s = (String)value;
    		s = StringEscapeUtils.escapeJavaScript(s);
    		return "'" + s + "'";
    	}
    	return "";
    }

    private String instanceToString(IMXMLInstanceNode instanceNode)
    {
    	if (instanceNode instanceof IMXMLStringNode)
    	{
    		IMXMLStringNode stringNode = (IMXMLStringNode)instanceNode;
    		IASNode vNode = stringNode.getExpressionNode();
    		if (vNode instanceof IMXMLLiteralNode)
    		{
	            IMXMLLiteralNode valueNode = (IMXMLLiteralNode)vNode;
	            Object value = valueNode.getValue();
	            return objectToString(value);
    		}
    		else
            {
    			return "''";
            }
    	}
    	else if (instanceNode instanceof IMXMLObjectNode)
    	{
    		IMXMLObjectNode objectNode = (IMXMLObjectNode)instanceNode;
            StringBuilder sb = new StringBuilder();
            sb.append(ASEmitterTokens.BLOCK_OPEN.getToken());
            int m = objectNode.getChildCount();
        	boolean firstOne = true;
            for (int j = 0; j < m; j++)
            {
            	if (firstOne)
                {
            		firstOne = false;
                }
                else
                {
                    sb.append(ASEmitterTokens.COMMA.getToken());
                    sb.append(ASEmitterTokens.SPACE.getToken());
                }
                IMXMLPropertySpecifierNode propName = (IMXMLPropertySpecifierNode)objectNode.getChild(j);
                sb.append(propName.getName());
                sb.append(ASEmitterTokens.COLON.getToken());
                sb.append(ASEmitterTokens.SPACE.getToken());
                IMXMLInstanceNode valueNode = propName.getInstanceNode();
	            sb.append(instanceToString(valueNode));
            }
            sb.append(ASEmitterTokens.BLOCK_CLOSE.getToken());
            return sb.toString();
    	}
    	else if (instanceNode instanceof IMXMLArrayNode)
    	{
    		IMXMLArrayNode arrayNode = (IMXMLArrayNode)instanceNode;
            StringBuilder sb = new StringBuilder();
            sb.append(ASEmitterTokens.SQUARE_OPEN.getToken());
            int m = arrayNode.getChildCount();
        	boolean firstOne = true;
            for (int j = 0; j < m; j++)
            {
	            IMXMLInstanceNode valueNode = (IMXMLInstanceNode)(arrayNode.getChild(j));
            	if (firstOne)
                {
            		firstOne = false;
                }
            	else
                {
            		sb.append(ASEmitterTokens.COMMA.getToken());
            		sb.append(ASEmitterTokens.SPACE.getToken());
                }
	            sb.append(instanceToString(valueNode));
            }
            sb.append(ASEmitterTokens.SQUARE_CLOSE.getToken());
            return sb.toString();
    	}
    	else if ((instanceNode instanceof IMXMLIntNode) ||
    			(instanceNode instanceof IMXMLUintNode) ||
    			(instanceNode instanceof IMXMLNumberNode) ||
    			(instanceNode instanceof IMXMLBooleanNode))
    	{
    		IMXMLExpressionNode scalarNode = (IMXMLExpressionNode)instanceNode;
    		IASNode vNode = scalarNode.getExpressionNode();
    		if (vNode instanceof IMXMLLiteralNode)
    		{
	            IMXMLLiteralNode valueNode = (IMXMLLiteralNode)vNode;
	            Object value = valueNode.getValue();
	            return value.toString();
    		}
    	}
    	return "";
    }

    public void emitComplexStaticInitializers(IASNode node){
        JSRoyaleEmitter fjs = (JSRoyaleEmitter) ((IMXMLBlockWalker) getMXMLWalker())
                .getASEmitter();

        if (!fjs.getFieldEmitter().hasComplexStaticInitializers) return;
        int n = node.getChildCount();
        boolean sawOutput = false;
        for (int i = 0; i < n; i++)
        {
            IASNode child = node.getChild(i);
            if (child.getNodeID() == ASTNodeID.MXMLScriptID)
            {
                int m = child.getChildCount();
                for (int j = 0; j < m; j++)
                {
                    IASNode schild = child.getChild(j);
                    ASTNodeID schildID = schild.getNodeID();
                    if (schildID == ASTNodeID.VariableID ||
                            schildID == ASTNodeID.BindableVariableID)
                    {
                        sawOutput = fjs.getFieldEmitter().emitFieldInitializer((IVariableNode) schild) || sawOutput;
                    }
                }
            }
        }

        if (sawOutput) {
            writeNewline();
            writeNewline();
        }
    }

    @Override
    public void emitImplements(IMXMLImplementsNode node)
    {
    	StringBuilder list = new StringBuilder();
    	boolean needsComma = false;
        IIdentifierNode[] interfaces = node.getInterfaceNodes();
        for (IIdentifierNode iface : interfaces)
        {
        	if (needsComma)
        		list.append(", ");
        	list.append(iface.getName());
        	needsComma = true;
        }
        //System.out.println("mxml implements "+list);
        interfaceList = list.toString();
    }
    
	boolean isGoogProvided(String className)
	{
        ICompilerProject project = getMXMLWalker().getProject();
		return ((RoyaleJSProject)project).isGoogProvided(className);
	}

	@Override
	public void emitRemoteObjectMethod(IMXMLRemoteObjectMethodNode node) {
        MXMLDescriptorSpecifier currentInstance = getCurrentDescriptor("i");
        String propName = null;
        int l = node.getChildCount();
        for (int k = 0; k < l; k++)
        {
        	IASNode child = node.getChild(k);
        	if (child.getNodeID() == ASTNodeID.MXMLPropertySpecifierID)
        	{
        		IMXMLPropertySpecifierNode propNode = (IMXMLPropertySpecifierNode)child;
        		if (propNode.getName().equals("name"))
        		{
        			// assume StringNode with LiteralNode
        			IMXMLStringNode literalNode = (IMXMLStringNode)propNode.getChild(0);
        			propName = literalNode.getValue();
        			break;
        		}
        	}
        }
    	MXMLDescriptorSpecifier propertySpecifier = new MXMLDescriptorSpecifier();
    	propertySpecifier.isProperty = true;
    	propertySpecifier.name = propName;
    	propertySpecifier.parent = currentInstance;
    	currentInstance.propertySpecifiers.add(propertySpecifier);
        moveDown(false, null, propertySpecifier);

		emitInstance(node);

		moveUp(false, false);
    	// build out the argument list if any
    	int n = node.getChildCount();
    	for (int i = 0; i < n; i++)
    	{
    		IASNode childNode = node.getChild(i);
    		if (childNode.getNodeID() == ASTNodeID.MXMLPropertySpecifierID)
    		{
    			IMXMLPropertySpecifierNode propNode = (IMXMLPropertySpecifierNode)childNode;
    			if (propNode.getName().equals("arguments"))
    			{
    				ArrayList<String> argList = new ArrayList<String>();
    				childNode = propNode.getChild(0); // this is an MXMLObjectNode
    				n = childNode.getChildCount();
    				for (i = 0; i < n; i++)
    				{
    					IASNode argNode = childNode.getChild(i);
    					propNode = (IMXMLPropertySpecifierNode)argNode;
    					argList.add(propNode.getName());
    				}
    				if (argList.size() > 0)
    				{
    					StringBuilder list = new StringBuilder();
    					list.append("[");
    					int m = argList.size();
    					for (int j = 0; j < m; j++)
    					{
    						if (j > 0)
    							list.append(",");
    						list.append("'" + argList.get(j) + "'");
    					}
    					list.append("]");

    			        MXMLDescriptorSpecifier operationInstance = propertySpecifier.propertySpecifiers.get(0);

    			        MXMLDescriptorSpecifier argListSpecifier = new MXMLDescriptorSpecifier();
    			        argListSpecifier.isProperty = true;
    			        argListSpecifier.name = "argumentNames";
    			        argListSpecifier.parent = operationInstance;
    			        argListSpecifier.value = list.toString();
				        if (operationInstance != null)
				        	operationInstance.propertySpecifiers.add(argListSpecifier);
    				}
    				break;
    			}
    		}
    	}
	}

	@Override
	public void emitRemoteObject(IMXMLRemoteObjectNode node) {
		emitInstance(node);
		// now search for Operations, and add an Object that contains them
		int n = node.getChildCount();
		MXMLDescriptorSpecifier objectSpecifier = null;
		MXMLDescriptorSpecifier propertySpecifier = null;
		for (int i = 0; i < n; i++)
		{
			IASNode child = node.getChild(i);
			if (child.getNodeID() == ASTNodeID.MXMLRemoteObjectMethodID)
			{
		        MXMLDescriptorSpecifier currentPropertySpecifier = getCurrentDescriptor("ps");
		        MXMLDescriptorSpecifier currentInstance =
		        	currentPropertySpecifier.propertySpecifiers.get(currentPropertySpecifier.propertySpecifiers.size() - 1);

		        if (objectSpecifier == null)
		        {
		        	propertySpecifier = new MXMLDescriptorSpecifier();
		        	propertySpecifier.isProperty = true;
		        	propertySpecifier.name = "operations";
		        	propertySpecifier.parent = currentInstance;

			        if (currentInstance != null)
			        	currentInstance.propertySpecifiers.add(propertySpecifier);
			        objectSpecifier = new MXMLDescriptorSpecifier();
			        objectSpecifier.isProperty = false;
			        objectSpecifier.name = formatQualifiedName(IASLanguageConstants.Object);
			        objectSpecifier.parent = propertySpecifier;
			        propertySpecifier.propertySpecifiers.add(objectSpecifier);
			        instances.add(objectSpecifier);
		        }
	            moveDown(false, objectSpecifier, null);
                getMXMLWalker().walk(child); // RemoteObjectMethod
	            moveUp(false, true);
			}
		}
	}
	
	@Override
	public void emitWebServiceMethod(IMXMLWebServiceOperationNode node) {
        MXMLDescriptorSpecifier currentInstance = getCurrentDescriptor("i");
        String propName = null;
        int l = node.getChildCount();
        for (int k = 0; k < l; k++)
        {
        	IASNode child = node.getChild(k);
        	if (child.getNodeID() == ASTNodeID.MXMLPropertySpecifierID)
        	{
        		IMXMLPropertySpecifierNode propNode = (IMXMLPropertySpecifierNode)child;
        		if (propNode.getName().equals("name"))
        		{
        			// assume StringNode with LiteralNode
        			IMXMLStringNode literalNode = (IMXMLStringNode)propNode.getChild(0);
        			propName = literalNode.getValue();
        			break;
        		}
        	}
        }
    	MXMLDescriptorSpecifier propertySpecifier = new MXMLDescriptorSpecifier();
    	propertySpecifier.isProperty = true;
    	propertySpecifier.name = propName;
    	propertySpecifier.parent = currentInstance;
    	currentInstance.propertySpecifiers.add(propertySpecifier);
        moveDown(false, null, propertySpecifier);

		emitInstance(node);

		moveUp(false, false);
    	// build out the argument list if any
    	int n = node.getChildCount();
    	for (int i = 0; i < n; i++)
    	{
    		IASNode childNode = node.getChild(i);
    		if (childNode.getNodeID() == ASTNodeID.MXMLPropertySpecifierID)
    		{
    			IMXMLPropertySpecifierNode propNode = (IMXMLPropertySpecifierNode)childNode;
    			if (propNode.getName().equals("arguments"))
    			{
    				ArrayList<String> argList = new ArrayList<String>();
    				childNode = propNode.getChild(0); // this is an MXMLObjectNode
    				n = childNode.getChildCount();
    				for (i = 0; i < n; i++)
    				{
    					IASNode argNode = childNode.getChild(i);
    					propNode = (IMXMLPropertySpecifierNode)argNode;
    					argList.add(propNode.getName());
    				}
    				if (argList.size() > 0)
    				{
    					StringBuilder list = new StringBuilder();
    					list.append("[");
    					int m = argList.size();
    					for (int j = 0; j < m; j++)
    					{
    						if (j > 0)
    							list.append(",");
    						list.append("'" + argList.get(j) + "'");
    					}
    					list.append("]");

    			        MXMLDescriptorSpecifier operationInstance = propertySpecifier.propertySpecifiers.get(0);

    			        MXMLDescriptorSpecifier argListSpecifier = new MXMLDescriptorSpecifier();
    			        argListSpecifier.isProperty = true;
    			        argListSpecifier.name = "argumentNames";
    			        argListSpecifier.parent = operationInstance;
    			        argListSpecifier.value = list.toString();
				        if (operationInstance != null)
				        	operationInstance.propertySpecifiers.add(argListSpecifier);
    				}
    				break;
    			}
    		}
    	}
	}

	@Override
	public void emitWebService(IMXMLWebServiceNode node) {
		emitInstance(node);
		// now search for Operations, and add an Object that contains them
		int n = node.getChildCount();
		MXMLDescriptorSpecifier objectSpecifier = null;
		MXMLDescriptorSpecifier propertySpecifier = null;
		for (int i = 0; i < n; i++)
		{
			IASNode child = node.getChild(i);
			if (child.getNodeID() == ASTNodeID.MXMLWebServiceOperationID)
			{
		        MXMLDescriptorSpecifier currentPropertySpecifier = getCurrentDescriptor("ps");
		        MXMLDescriptorSpecifier currentInstance =
		        	currentPropertySpecifier.propertySpecifiers.get(currentPropertySpecifier.propertySpecifiers.size() - 1);

		        if (objectSpecifier == null)
		        {
		        	propertySpecifier = new MXMLDescriptorSpecifier();
		        	propertySpecifier.isProperty = true;
		        	propertySpecifier.name = "operations";
		        	propertySpecifier.parent = currentInstance;

			        if (currentInstance != null)
			        	currentInstance.propertySpecifiers.add(propertySpecifier);
			        objectSpecifier = new MXMLDescriptorSpecifier();
			        objectSpecifier.isProperty = false;
			        objectSpecifier.name = formatQualifiedName(IASLanguageConstants.Object);
			        objectSpecifier.parent = propertySpecifier;
			        propertySpecifier.propertySpecifiers.add(objectSpecifier);
			        instances.add(objectSpecifier);
		        }
	            moveDown(false, objectSpecifier, null);
                getMXMLWalker().walk(child); // RemoteObjectMethod
	            moveUp(false, true);
			}
		}
	}
}
