/*
 *
 *  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.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.semantics.MethodInfo;
import org.apache.royale.abc.semantics.Name;
import org.apache.royale.abc.semantics.Namespace;
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.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.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.mxml.MXMLDocumentNode;
import org.apache.royale.compiler.internal.tree.mxml.MXMLFileNode;
import org.apache.royale.compiler.internal.tree.mxml.MXMLBindingNode;
import org.apache.royale.compiler.mxml.IMXMLLanguageConstants;
import org.apache.royale.compiler.projects.ICompilerProject;
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.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 boolean inStatesOverride;
    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) ((IMXMLBlockWalker) getMXMLWalker())
                .getASEmitter();

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

        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)
                            {
                            	ICompilationUnit cu = royaleProject.resolveQNameToCompilationUnit(usedName);
                            	if (cu != null && royaleProject.isExternalLinkage(cu))
                            		continue;
                            	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 (isExternal(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 (isExternal(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;
	            				}
	            			}
	            		}
	            	}
	            	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);
    }

    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;
        MXMLDescriptorSpecifier currentInstance = getCurrentDescriptor("i");

        MXMLDescriptorSpecifier currentPropertySpecifier = new MXMLDescriptorSpecifier();
        currentPropertySpecifier.isProperty = true;
        currentPropertySpecifier.name = "mxmlContent";
        currentPropertySpecifier.parent = currentInstance;
        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.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());
	        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();
            writeNewline("this.generateMXMLAttributes");
            write(ASEmitterTokens.PAREN_OPEN);
            write(ASEmitterTokens.SQUARE_OPEN);

            MXMLDescriptorSpecifier root = propertiesTree;
            root.isTopNode = true;
            writeNewline(root.output(true));

            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("/**");
	    writeNewline(" * Prevent renaming of class. Needed for reflection.");
        writeNewline(" */");
	    write(JSRoyaleEmitterTokens.GOOG_EXPORT_SYMBOL);
	    write(ASEmitterTokens.PAREN_OPEN);
	    write(ASEmitterTokens.SINGLE_QUOTE);
	    write(formatQualifiedName(cname));
	    write(ASEmitterTokens.SINGLE_QUOTE);
	    write(ASEmitterTokens.COMMA);
	    write(ASEmitterTokens.SPACE);
	    write(formatQualifiedName(cname));
	    write(ASEmitterTokens.PAREN_CLOSE);
	    write(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();
        	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)
    {
        BindingDatabase bd = BindingDatabase.bindingMap.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

        for (BindingInfo bi : bindingInfo)
        {
            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);
                	if (getterNode.getNodeID() == ASTNodeID.LiteralStringID)
                	{
                		sb.append(ASEmitterTokens.DOUBLE_QUOTE.getToken());
                		sb.append(asEmitter.stringifyNode(getterNode));
                		sb.append(ASEmitterTokens.DOUBLE_QUOTE.getToken());
                	}
                	else
                		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)
            {
                writeNewline(ASEmitterTokens.NULL.getToken() + ASEmitterTokens.COMMA.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());
                }
                writeNewline(ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.COMMA.getToken());
            }
            else
                writeNewline(ASEmitterTokens.DOUBLE_QUOTE.getToken() + s +
                        ASEmitterTokens.DOUBLE_QUOTE.getToken() + ASEmitterTokens.COMMA.getToken());
        }
        Set<Entry<Object, WatcherInfoBase>> watcherChains = bindingDataBase.getWatcherChains();

        if (watcherChains != null)
        {
            int count = watcherChains.size();
            for (Entry<Object, WatcherInfoBase> entry : watcherChains)
            {
                count--;
                WatcherInfoBase watcherInfoBase = entry.getValue();
                encodeWatcher(watcherInfoBase);
                if (count > 0) writeNewline(ASEmitterTokens.COMMA);
            }
        }

        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;
    	sb.append("this.");
    	sb.append(((IMXMLInstanceNode)parentNode).getEffectiveID());
    	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
            MethodInfo propertyGetterFunction = null;
            if (watcherInfoBase.isRoot && !makeStaticWatcher)
            {
                // TODO: figure out what this looks like
                // propertyGetterFunction = this.propertyGetter;
                // assert propertyGetterFunction != null;
            }
            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
            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() {");
            indentPush();
            writeNewline("{");
            writeNewline("if (this.mxmldd == undefined)");
            indentPush();
            writeNewline("{");
            writeNewline("/** @type {Array} */");
            writeNewline("var arr = " + formatQualifiedName(cname) + ".superClass_.get__MXMLDescriptor.apply(this);");
            writeNewline("/** @type {Array} */");
            indentPop();
            indentPop();
            writeNewline("var data = [");

            writeNewline(root.output(true));

            indentPush();
            writeNewline("];");
            indentPush();
            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;");
            writeNewline("}");
            indentPop();
            writeNewline("}");
            indentPop();
            writeNewline("}");
        	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)
    {
    	if (isStateDependent(node) && !inStatesOverride)
    		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) // in theory, if no currentdescriptor must be top tag event
	        propertiesTree.eventSpecifiers.add(eventSpecifier);
        events.add(eventSpecifier);
    }

    @Override
    public void emitInstance(IMXMLInstanceNode node)
    {
        if (isStateDependent(node) && !inStatesOverride)
            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");

        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
        {
            currentInstance.parent = propertiesTree;
            propertiesTree.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)
            {
                for (int i=snodes.size()-1; i>=0; --i)
                {
                    IMXMLNode inode = snodes.get(i);
                    if (inode.getNodeID() == ASTNodeID.MXMLInstanceID)
                    {
                        emitInstanceOverride((IMXMLInstanceNode)inode);
                    }
                }
                // 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;
                        }
                    }
                }
            }

            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);
	        BindingDatabase bd = BindingDatabase.bindingMap.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)
    {
        inStatesOverride = true;

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

        inStatesOverride = false;
    }

    public void emitInstanceOverride(IMXMLInstanceNode instanceNode)
    {
        inStatesOverride = true;

        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;
            getMXMLWalker().walk(instanceNode); // instance node
            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))
            {
                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);
        }

        inStatesOverride = false;
    }

    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 node is state-dependent.
     * TODO: we should move to IMXMLNode
     */
    protected boolean isStateDependent(IASNode node)
    {
        if (node instanceof IMXMLSpecifierNode)
        {
            String suffix = ((IMXMLSpecifierNode)node).getSuffix();
            return suffix != null && suffix.length() > 0;
        }
        else if (isStateDependentInstance(node))
            return true;
        return false;
    }

    /**
     * Determines whether the geven node is an instance node, as is state dependent
     */
    protected boolean isStateDependentInstance(IASNode node)
    {
        if (node instanceof IMXMLInstanceNode)
        {
            String[] includeIn = ((IMXMLInstanceNode)node).getIncludeIn();
            String[] excludeFrom = ((IMXMLInstanceNode)node).getExcludeFrom();
            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))
            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)
            {
            	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 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) && !isExternal(name))
    			staticUsedNames.add(name);

		if (useName && !usedNames.contains(name) && !isExternal(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);
    	                    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 isExternal(String className)
	{
        ICompilerProject project = getMXMLWalker().getProject();
		ICompilationUnit cu = project.resolveQNameToCompilationUnit(className);
		if (cu == null) return false; // unit testing

		return ((RoyaleJSProject)project).isExternalLinkage(cu);
	}

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