/*
 *
 *  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.MethodInfo;
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.as.IASEmitter;
import org.apache.royale.compiler.codegen.js.IJSEmitter;
import org.apache.royale.compiler.codegen.js.IMappingEmitter;
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.IFunctionDefinition;
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.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, IMappingEmitter
{

	// 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;

    /**
     * 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>();
    }

    @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();

        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;

        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;
        ((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();
	        write(root.outputStateDescriptors(false));
	        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;
            for(int i = 0; i < getCurrentIndent(); i++)
            {
                root.indentPush();
            }
            write(root.output(true));
            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 =	varNode.getVariableTypeNode().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)
        {
            if (instance.id != null)
            {
	        	PackageFooterEmitter.AccessorData data = asEmitter.packageFooterEmitter.new AccessorData();
	        	accessorData.add(data);
	        	data.name = instance.id;
	        	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"))) {
                    qualifiedTypeName = methodNode.getReturnTypeNode().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)
                {
                    data.type = p.getter.getReturnTypeNode().resolveType(fjs).getQualifiedName();
                    if (p.setter !=null) {
                        data.access = "readwrite";
                    } else data.access = "readonly";
                }
                else
                {
                    data.type = p.setter.getVariableTypeNode().resolveType(fjs).getQualifiedName();
                    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)
        {
            writeNewline();
            writeNewline("/**");
            writeNewline(" * @private");
            writeNewline(" * @type {" + instance.name + "}");
            writeNewline(" */");
            write(ASEmitterTokens.THIS);
            write(ASEmitterTokens.MEMBER_ACCESS);
            write((instance.id != null ? instance.id : instance.effectiveId) + "_");
            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)
    {
        IASEmitter asEmitter = ((IMXMLBlockWalker) getMXMLWalker())
                .getASEmitter();
        
        writeNewline("/**");
        writeNewline(" * @export"); // must export or else GCC will remove it
        writeNewline(" */");
        writeNewline(formatQualifiedName(cname)
                + ".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.getToken());
            hadOutput = true;
            String s;
            IMXMLNode node = bi.node;
            if (node instanceof IMXMLSingleDataBindingNode)
            {
            	IMXMLSingleDataBindingNode sbdn = (IMXMLSingleDataBindingNode)node;
            	RoyaleJSProject project = (RoyaleJSProject)getMXMLWalker().getProject();
            	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 (s == null || s.length() == 0)
            {
                List<IExpressionNode> getterNodes = bi.getExpressionNodesForGetter();
                StringBuilder sb = new StringBuilder();
                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() + ASEmitterTokens.PLUS.getToken() + ASEmitterTokens.SPACE.getToken());
                }
                sb.append("; },");
                writeNewline(sb.toString());
            }
            else if (s.contains("."))
            {
            	if (bi.classDef != null)
            	{
	                String[] parts = s.split("\\.");
	                write(ASEmitterTokens.SQUARE_OPEN.getToken() + ASEmitterTokens.DOUBLE_QUOTE.getToken() +
	                        bi.classDef.getQualifiedName() + ASEmitterTokens.DOUBLE_QUOTE.getToken());
	                String qname = bi.classDef.getQualifiedName();
	                if (!usedNames.contains(qname))
	                	usedNames.add(qname);
	                if (!staticUsedNames.contains(qname))
	                	staticUsedNames.add(qname);
	                int n = parts.length;
	                for (int i = 1; i < n; i++)
	                {
	                    String part = parts[i];
	                    write(", " +  ASEmitterTokens.DOUBLE_QUOTE.getToken() + part + ASEmitterTokens.DOUBLE_QUOTE.getToken());
	                }
	                writeNewline(ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.COMMA.getToken());
            	}
            	else
            	{
	                String[] parts = s.split("\\.");
	                write(ASEmitterTokens.SQUARE_OPEN.getToken() + ASEmitterTokens.DOUBLE_QUOTE.getToken() +
	                        parts[0] + ASEmitterTokens.DOUBLE_QUOTE.getToken());
	                int n = parts.length;
	                for (int i = 1; i < n; i++)
	                {
	                    String part = parts[i];
	                    write(", " +  ASEmitterTokens.DOUBLE_QUOTE.getToken() + part + ASEmitterTokens.DOUBLE_QUOTE.getToken());
	                }
	                writeNewline(ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.COMMA.getToken());
            	}
            }
            else
                writeNewline(ASEmitterTokens.DOUBLE_QUOTE.getToken() + s +
                        ASEmitterTokens.DOUBLE_QUOTE.getToken() + ASEmitterTokens.COMMA.getToken());

            IExpressionNode destNode = bi.getExpressionNodeForDestination();
            s = bi.getDestinationString();
            if (destNode != null && s == null)
            {
                StringBuilder sb = new StringBuilder();
                sb.append(generateSetterFunction(bi, destNode));
                writeNewline(sb.toString() + ASEmitterTokens.COMMA.getToken());
            }
            else
                writeNewline(ASEmitterTokens.NULL.getToken() + ASEmitterTokens.COMMA.getToken());

            if (s == null)
            {
                write(ASEmitterTokens.NULL.getToken());
            }
            else if (s.contains("."))
            {
                String[] parts = s.split("\\.");
                write(ASEmitterTokens.SQUARE_OPEN.getToken() + ASEmitterTokens.DOUBLE_QUOTE.getToken() +
                        parts[0] + ASEmitterTokens.DOUBLE_QUOTE.getToken());
                int n = parts.length;
                for (int i = 1; i < n; i++)
                {
                    String part = parts[i];
                    write(", " + ASEmitterTokens.DOUBLE_QUOTE.getToken() + part + ASEmitterTokens.DOUBLE_QUOTE.getToken());
                }
                write(ASEmitterTokens.SQUARE_CLOSE.getToken());
            }
            else
                write(ASEmitterTokens.DOUBLE_QUOTE.getToken() + s +
                        ASEmitterTokens.DOUBLE_QUOTE.getToken());
            
        }
        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();
        }

        writeNewline( ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.SEMICOLON.getToken());
    }

    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;
                            }

                            bindableVarInfo.type = variableNode.getVariableTypeNode().resolveType(getMXMLWalker().getProject()).getQualifiedName();
                            ((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("Object.defineProperties(");
    	write(formattedCName);
    	writeNewline(".prototype, /** @lends {" + formattedCName + ".prototype} */ {");
        indentPush();
        int i = 0;
        for (MXMLDescriptorSpecifier instance : instances)
        {
        	String instanceId = instance.id;
        	if (instanceId == null && instance.hasLocalId ){
        		instanceId = instance.effectiveId;
			}
            if (instanceId != null)
            {
                indentPush();
    	        writeNewline("/** @export */");
                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 data = [");

            for(int i = 0; i < getCurrentIndent(); i++)
            {
                root.indentPush();
            }
            write(root.output(true));
            indentPop();
            writeNewline();

            writeNewline("];");
            indentPush();
            writeNewline("if (arr)");
            indentPop();
            writeNewline("this.mxmldd = arr.concat(data);");
            indentPush();
            writeNewline("else");
            indentPop();
            indentPop();
            writeNewline("this.mxmldd = data;");
            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();
        eventSpecifier.eventHandler = MXMLRoyaleEmitterTokens.EVENT_PREFIX
                .getToken() + 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);
            IFunctionDefinition fdef = fnode.getValue(project);
            IExpressionNode fexpNode = (IExpressionNode)fnode.getExpressionNode();
            String fnName = fdef.getBaseName();
            IASEmitter asEmitter = ((IMXMLBlockWalker) getMXMLWalker())
                    .getASEmitter();
            if (fdef.isPrivate() && project.getAllowPrivateNameConflicts())
            	fnName = ((JSRoyaleEmitter)asEmitter).formatPrivateName(fdef.getParent().getQualifiedName(), fdef.getBaseName());
            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");
            if (ps.hasObject || 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();
            if (nodeID == ASTNodeID.MXMLArrayID || nodeID == ASTNodeID.MXMLInstanceID || 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 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)
    {
    	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;
    	                    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);
                            fjs.emitAssignmentCoercion(vnode, varnode.getVariableTypeNode().resolve(getMXMLWalker().getProject()));
    	                    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;
	    			varname = stringNode.getEffectiveID();
	                writeNewline();
	                write(ASEmitterTokens.THIS);
	                write(ASEmitterTokens.MEMBER_ACCESS);
	                write(varname);
	                write(ASEmitterTokens.SPACE);
	                writeToken(ASEmitterTokens.EQUAL);
	                IMXMLLiteralNode valueNode = (IMXMLLiteralNode)(stringNode.getExpressionNode());
	                Object value = valueNode.getValue();
	                write(objectToString(value));
	                write(ASEmitterTokens.SEMICOLON);
	                break;
	    		}
				case MXMLArrayID:
				{
					IMXMLArrayNode arrayNode = (IMXMLArrayNode)declNode;
					varname = arrayNode.getEffectiveID();
		            writeNewline();
		            write(ASEmitterTokens.THIS);
		            write(ASEmitterTokens.MEMBER_ACCESS);
		            write(varname);
		            write(ASEmitterTokens.SPACE);
		            writeToken(ASEmitterTokens.EQUAL);
		            write("[");
		            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
		            		writeToken(",");
			            write(instanceToString(valueNode));
		            }
		            write("]");
		            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;
				}
    		}
    	}
    }

    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 "''";
    	}
    	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);
			}
		}
	}
}
