You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by cd...@apache.org on 2016/04/14 09:46:47 UTC

[18/18] git commit: [flex-falcon] [refs/heads/feature/maven-migration-test] - Merge branch 'develop' of https://git-wip-us.apache.org/repos/asf/flex-falcon into feature/maven-migration-test

Merge branch 'develop' of https://git-wip-us.apache.org/repos/asf/flex-falcon into feature/maven-migration-test


Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/de070636
Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/de070636
Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/de070636

Branch: refs/heads/feature/maven-migration-test
Commit: de070636246d09e27b8aa25898cd22aa2dee1ae1
Parents: c3dce49 bc19c66
Author: Christofer Dutz <ch...@codecentric.de>
Authored: Thu Apr 14 09:39:02 2016 +0200
Committer: Christofer Dutz <ch...@codecentric.de>
Committed: Thu Apr 14 09:39:02 2016 +0200

----------------------------------------------------------------------
 .../apache/flex/compiler/clients/MXMLJSC.java   | 109 ++++++++-------
 .../internal/codegen/js/JSSessionModel.java     |   2 +
 .../codegen/js/flexjs/JSFlexJSEmitter.java      |  12 ++
 .../codegen/js/jx/BinaryOperatorEmitter.java    |  17 +++
 .../codegen/js/jx/IdentifierEmitter.java        |  14 ++
 .../internal/codegen/js/jx/LiteralEmitter.java  |  26 ++--
 .../internal/codegen/js/utils/EmitterUtils.java |  12 ++
 .../internal/codegen/mxml/MXMLWriter.java       |   3 +-
 .../codegen/mxml/flexjs/MXMLFlexJSEmitter.java  |  73 +++++-----
 .../mxml/flexjs/MXMLFlexJSPublisher.java        | 140 ++++++++++---------
 .../driver/js/goog/JSGoogConfiguration.java     |  20 +++
 .../js/flexjs/TestFlexJSGlobalClasses.java      |  58 +++++++-
 .../projects/xml_requires/XMLRequire_result.js  |   2 +-
 13 files changed, 320 insertions(+), 168 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/de070636/compiler-jx/src/main/java/org/apache/flex/compiler/clients/MXMLJSC.java
----------------------------------------------------------------------
diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/clients/MXMLJSC.java
index d324c9f,0000000..c6d9508
mode 100644,000000..100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/MXMLJSC.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/MXMLJSC.java
@@@ -1,847 -1,0 +1,852 @@@
 +/*
 + *
 + *  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.flex.compiler.clients;
 +
 +import java.io.BufferedOutputStream;
 +import java.io.File;
 +import java.io.FileNotFoundException;
 +import java.io.FileOutputStream;
 +import java.io.IOException;
 +import java.util.ArrayList;
 +import java.util.Collection;
 +import java.util.Collections;
 +import java.util.List;
 +import java.util.Set;
 +
 +import org.apache.commons.io.FilenameUtils;
 +import org.apache.flex.compiler.clients.problems.ProblemPrinter;
 +import org.apache.flex.compiler.clients.problems.ProblemQuery;
 +import org.apache.flex.compiler.clients.problems.ProblemQueryProvider;
 +import org.apache.flex.compiler.clients.problems.WorkspaceProblemFormatter;
 +import org.apache.flex.compiler.codegen.js.IJSPublisher;
 +import org.apache.flex.compiler.codegen.js.IJSWriter;
 +import org.apache.flex.compiler.config.Configuration;
 +import org.apache.flex.compiler.config.ConfigurationBuffer;
 +import org.apache.flex.compiler.config.Configurator;
 +import org.apache.flex.compiler.config.ICompilerSettingsConstants;
 +import org.apache.flex.compiler.driver.IBackend;
 +import org.apache.flex.compiler.driver.js.IJSApplication;
 +import org.apache.flex.compiler.exceptions.ConfigurationException;
 +import org.apache.flex.compiler.exceptions.ConfigurationException.IOError;
 +import org.apache.flex.compiler.exceptions.ConfigurationException.MustSpecifyTarget;
 +import org.apache.flex.compiler.exceptions.ConfigurationException.OnlyOneSource;
 +import org.apache.flex.compiler.internal.codegen.js.JSSharedData;
 +import org.apache.flex.compiler.internal.config.FlashBuilderConfigurator;
 +import org.apache.flex.compiler.internal.driver.as.ASBackend;
 +import org.apache.flex.compiler.internal.driver.js.amd.AMDBackend;
 +import org.apache.flex.compiler.internal.driver.js.goog.GoogBackend;
 +import org.apache.flex.compiler.internal.driver.js.goog.JSGoogConfiguration;
 +import org.apache.flex.compiler.internal.driver.js.jsc.JSCBackend;
 +import org.apache.flex.compiler.internal.driver.js.node.NodeBackend;
 +import org.apache.flex.compiler.internal.driver.mxml.flexjs.MXMLFlexJSBackend;
 +import org.apache.flex.compiler.internal.driver.mxml.vf2js.MXMLVF2JSBackend;
 +import org.apache.flex.compiler.internal.parsing.as.FlexJSASDocDelegate;
 +import org.apache.flex.compiler.internal.projects.CompilerProject;
 +import org.apache.flex.compiler.internal.projects.FlexJSProject;
 +import org.apache.flex.compiler.internal.projects.ISourceFileHandler;
 +import org.apache.flex.compiler.internal.targets.JSTarget;
 +import org.apache.flex.compiler.internal.units.ResourceModuleCompilationUnit;
 +import org.apache.flex.compiler.internal.units.SourceCompilationUnitFactory;
 +import org.apache.flex.compiler.internal.workspaces.Workspace;
 +import org.apache.flex.compiler.problems.ConfigurationProblem;
 +import org.apache.flex.compiler.problems.ICompilerProblem;
 +import org.apache.flex.compiler.problems.InternalCompilerProblem;
 +import org.apache.flex.compiler.problems.UnableToBuildSWFProblem;
 +import org.apache.flex.compiler.problems.UnexpectedExceptionProblem;
 +import org.apache.flex.compiler.projects.ICompilerProject;
 +import org.apache.flex.compiler.targets.ITarget;
 +import org.apache.flex.compiler.targets.ITarget.TargetType;
 +import org.apache.flex.compiler.targets.ITargetSettings;
 +import org.apache.flex.compiler.units.ICompilationUnit;
 +import org.apache.flex.tools.FlexTool;
 +import org.apache.flex.utils.ArgumentUtil;
 +import org.apache.flex.utils.FilenameNormalization;
 +
 +import com.google.common.base.Preconditions;
 +import com.google.common.collect.Iterables;
 +
 +/**
 + * @author Erik de Bruin
 + * @author Michael Schmalle
 + */
 +public class MXMLJSC implements JSCompilerEntryPoint, ProblemQueryProvider,
 +        FlexTool
 +{
 +    @Override
 +    public ProblemQuery getProblemQuery()
 +    {
 +        return problems;
 +    }
 +
 +    /*
 +    	 * JS output type enumerations.
 +    	 */
 +    public enum JSOutputType
 +    {
 +        AMD("amd"),
 +        FLEXJS("flexjs"),
 +        GOOG("goog"),
 +        VF2JS("vf2js"),
 +        FLEXJS_DUAL("flexjs_dual"),
 +        JSC("jsc"),
 +        NODE("node");
 +
 +        private String text;
 +
 +        JSOutputType(String text)
 +        {
 +            this.text = text;
 +        }
 +
 +        public String getText()
 +        {
 +            return this.text;
 +        }
 +
 +        public static JSOutputType fromString(String text)
 +        {
 +            for (JSOutputType jsOutputType : JSOutputType.values())
 +            {
 +                if (text.equalsIgnoreCase(jsOutputType.text))
 +                    return jsOutputType;
 +            }
 +            return GOOG;
 +        }
 +    }
 +
 +    /*
 +     * Exit code enumerations.
 +     */
 +    static enum ExitCode
 +    {
 +        SUCCESS(0),
 +        PRINT_HELP(1),
 +        FAILED_WITH_PROBLEMS(2),
 +        FAILED_WITH_ERRORS(3),
 +        FAILED_WITH_EXCEPTIONS(4),
 +        FAILED_WITH_CONFIG_PROBLEMS(5);
 +
 +        ExitCode(int code)
 +        {
 +            this.code = code;
 +        }
 +
 +        final int code;
 +    }
 +
 +    public static JSOutputType jsOutputType;
 +    public static boolean keepASDoc;
 +
 +    @Override
 +    public String getName()
 +    {
 +        return FLEX_TOOL_MXMLC;
 +    }
 +
 +    @Override
 +    public int execute(String[] args)
 +    {
 +        final List<ICompilerProblem> problems = new ArrayList<ICompilerProblem>();
 +        return mainNoExit(args, problems, true);
 +    }
 +
 +    /**
 +     * Java program entry point.
 +     * 
 +     * @param args command line arguments
 +     */
 +    public static void main(final String[] args)
 +    {
 +        int exitCode = staticMainNoExit(args);
 +        System.exit(exitCode);
 +    }
 +
 +    /**
 +     * Entry point for the {@code <compc>} Ant task.
 +     *
 +     * @param args Command line arguments.
 +     * @return An exit code.
 +     */
 +    public static int staticMainNoExit(final String[] args)
 +    {
 +        long startTime = System.nanoTime();
 +
 +        IBackend backend = new ASBackend();
 +        String jsOutputTypeString = "";
 +        for (String s : args)
 +        {
 +            String[] kvp = s.split("=");
 +
 +            if (s.contains("-js-output-type"))
 +            {
 +                jsOutputTypeString = kvp[1];
 +            }
 +        }
 +
 +        if (jsOutputTypeString.equals(""))
 +        {
 +            jsOutputTypeString = JSOutputType.FLEXJS.getText();
 +        }
 +
 +        jsOutputType = JSOutputType.fromString(jsOutputTypeString);
 +        switch (jsOutputType)
 +        {
 +        case AMD:
 +            backend = new AMDBackend();
 +            break;
 +        case JSC:
 +            backend = new JSCBackend();
 +            break;
 +        case NODE:
 +            backend = new NodeBackend();
 +            break;
 +        case FLEXJS:
 +        case FLEXJS_DUAL:
 +            backend = new MXMLFlexJSBackend();
 +            break;
 +        case GOOG:
 +            backend = new GoogBackend();
 +            break;
 +        case VF2JS:
 +            backend = new MXMLVF2JSBackend();
 +            break;
 +        // if you add a new js-output-type here, don't forget to also add it
 +        // to flex2.tools.MxmlJSC in flex-compiler-oem for IDE support
 +        }
 +
 +        final MXMLJSC mxmlc = new MXMLJSC(backend);
 +        final List<ICompilerProblem> problems = new ArrayList<ICompilerProblem>();
 +        final int exitCode = mxmlc.mainNoExit(args, problems, true);
 +
 +        long endTime = System.nanoTime();
 +        JSSharedData.instance.stdout((endTime - startTime) / 1e9 + " seconds");
 +
 +        return exitCode;
 +    }
 +
 +    protected Workspace workspace;
 +    protected FlexJSProject project;
 +
 +    protected ProblemQuery problems;
 +    protected ISourceFileHandler asFileHandler;
 +    protected Configuration config;
 +    protected Configurator projectConfigurator;
 +    private ConfigurationBuffer configBuffer;
 +    private ICompilationUnit mainCU;
 +    protected ITarget target;
 +    protected ITargetSettings targetSettings;
 +    protected IJSApplication jsTarget;
 +    private IJSPublisher jsPublisher;
 +
 +    public MXMLJSC(IBackend backend)
 +    {
 +        JSSharedData.backend = backend;
 +        workspace = new Workspace();
 +        workspace.setASDocDelegate(new FlexJSASDocDelegate());
 +        project = new FlexJSProject(workspace);
 +        problems = new ProblemQuery(); // this gets replaced in configure().  Do we need it here?
 +        JSSharedData.OUTPUT_EXTENSION = backend.getOutputExtension();
 +        JSSharedData.workspace = workspace;
 +        asFileHandler = backend.getSourceFileHandlerInstance();
 +    }
 +
 +    @Override
 +    public int mainNoExit(final String[] args, List<ICompilerProblem> problems,
 +            Boolean printProblems)
 +    {
 +        int exitCode = -1;
 +        try
 +        {
 +            exitCode = _mainNoExit(ArgumentUtil.fixArgs(args), problems);
 +        }
 +        catch (Exception e)
 +        {
 +            JSSharedData.instance.stderr(e.toString());
 +        }
 +        finally
 +        {
 +            if (problems != null && !problems.isEmpty())
 +            {
 +                if (printProblems)
 +                {
 +                    final WorkspaceProblemFormatter formatter = new WorkspaceProblemFormatter(
 +                            workspace);
 +                    final ProblemPrinter printer = new ProblemPrinter(formatter);
 +                    printer.printProblems(problems);
 +                }
 +            }
 +        }
 +        return exitCode;
 +    }
 +
 +    /**
 +     * Entry point that doesn't call <code>System.exit()</code>. This is for
 +     * unit testing.
 +     * 
 +     * @param args command line arguments
 +     * @return exit code
 +     */
 +    private int _mainNoExit(final String[] args,
 +            List<ICompilerProblem> outProblems)
 +    {
 +        ExitCode exitCode = ExitCode.SUCCESS;
 +        try
 +        {
 +            String[] adjustedArgs = args;
 +
 +            if (jsOutputType != null)
 +            {
 +                switch (jsOutputType)
 +                {
 +                case VF2JS:
 +                    boolean isFlashBuilderProject = useFlashBuilderProjectFiles(args);
 +
 +                    if (isFlashBuilderProject)
 +                    {
 +                        adjustedArgs = FlashBuilderConfigurator.computeFlashBuilderArgs(
 +                                adjustedArgs, getTargetType().getExtension());
 +                    }
 +
 +                    //String projectFilePath = adjustedArgs[adjustedArgs.length - 1];
 +                    //
 +                    //String newProjectFilePath = VF2JSProjectUtils
 +                    //        .createTempProject(projectFilePath,
 +                    //                isFlashBuilderProject);
 +                    //
 +                    //adjustedArgs[adjustedArgs.length - 1] = newProjectFilePath;
 +
 +                    break;
 +                default:
 +                    break;
 +                }
 +            }
 +
 +            final boolean continueCompilation = configure(adjustedArgs);
 +
 +            // ToDo (erikdebruin): use JSSharedData for globals ...
 +            keepASDoc = ((JSGoogConfiguration) config).getKeepASDoc();
 +
 +            if (outProblems != null && !config.isVerbose())
 +                JSSharedData.STDOUT = JSSharedData.STDERR = null;
 +
 +            if (continueCompilation)
 +            {
 +                project.setProblems(problems.getProblems());
-                 compile();
++               	compile();
 +                if (problems.hasFilteredProblems())
 +                {
 +                    if (problems.hasErrors())
 +                        exitCode = ExitCode.FAILED_WITH_ERRORS;
 +                    else
 +                        exitCode = ExitCode.FAILED_WITH_PROBLEMS;
 +                }
 +            }
 +            else if (problems.hasFilteredProblems())
 +            {
 +                exitCode = ExitCode.FAILED_WITH_CONFIG_PROBLEMS;
 +            }
 +            else
 +            {
 +                exitCode = ExitCode.PRINT_HELP;
 +            }
 +        }
 +        catch (Exception e)
 +        {
 +            if (outProblems == null)
 +                JSSharedData.instance.stderr(e.getMessage());
 +            else
 +            {
 +                final ICompilerProblem unexpectedExceptionProblem = new UnexpectedExceptionProblem(
 +                        e);
 +                problems.add(unexpectedExceptionProblem);
 +            }
 +            exitCode = ExitCode.FAILED_WITH_EXCEPTIONS;
 +        }
 +        finally
 +        {
 +            waitAndClose();
 +
 +            if (outProblems != null && problems.hasFilteredProblems())
 +            {
 +                for (ICompilerProblem problem : problems.getFilteredProblems())
 +                {
 +                    outProblems.add(problem);
 +                }
 +            }
 +        }
 +        return exitCode.code;
 +    }
 +
 +    /**
 +     * Main body of this program. This method is called from the public static
 +     * method's for this program.
 +     * 
 +     * @return true if compiler succeeds
 +     * @throws IOException
 +     * @throws InterruptedException
 +     */
 +    protected boolean compile()
 +    {
 +        boolean compilationSuccess = false;
 +
 +        try
 +        {
 +            project.getSourceCompilationUnitFactory().addHandler(asFileHandler);
 +
-             if (!setupTargetFile())
-                 return false;
- 
-             buildArtifact();
++            if (!((JSGoogConfiguration) config).getSkipTranspile())
++            {
++	            if (!setupTargetFile())
++	                return false;
 +
-             if (jsTarget != null)
++	            buildArtifact();
++            }
++            if (jsTarget != null || ((JSGoogConfiguration) config).getSkipTranspile())
 +            {
 +                List<ICompilerProblem> errors = new ArrayList<ICompilerProblem>();
 +                List<ICompilerProblem> warnings = new ArrayList<ICompilerProblem>();
 +
 +                if (!config.getCreateTargetWithErrors())
 +                {
 +                    problems.getErrorsAndWarnings(errors, warnings);
 +                    if (errors.size() > 0)
 +                        return false;
 +                }
 +
 +                jsPublisher = (IJSPublisher) JSSharedData.backend.createPublisher(
 +                        project, errors, config);
 +
 +                File outputFolder = jsPublisher.getOutputFolder();
 +
-                 ArrayList<ICompilationUnit> roots = new ArrayList<ICompilationUnit>();
-                 roots.add(mainCU);
-                 Set<ICompilationUnit> incs = target.getIncludesCompilationUnits();
-                 roots.addAll(incs);
-                 List<ICompilationUnit> reachableCompilationUnits = project.getReachableCompilationUnitsInSWFOrder(roots);
-                 for (final ICompilationUnit cu : reachableCompilationUnits)
++                if (!((JSGoogConfiguration) config).getSkipTranspile())
 +                {
-                     ICompilationUnit.UnitType cuType = cu.getCompilationUnitType();
- 
-                     if (cuType == ICompilationUnit.UnitType.AS_UNIT
-                             || cuType == ICompilationUnit.UnitType.MXML_UNIT)
-                     {
-                         final File outputClassFile = getOutputClassFile(
-                                 cu.getQualifiedNames().get(0), outputFolder);
- 
-                         System.out.println("Compiling file: " + outputClassFile);
- 
-                         ICompilationUnit unit = cu;
- 
-                         IJSWriter writer;
-                         if (cuType == ICompilationUnit.UnitType.AS_UNIT)
-                         {
-                             writer = (IJSWriter) JSSharedData.backend.createWriter(project,
-                                     errors, unit, false);
-                         }
-                         else
-                         {
-                             writer = (IJSWriter) JSSharedData.backend.createMXMLWriter(
-                                     project, errors, unit, false);
-                         }
- 
-                         BufferedOutputStream out = new BufferedOutputStream(
-                                 new FileOutputStream(outputClassFile));
- 
-                         File outputSourceMapFile = null;
-                         if (project.config.getSourceMap())
-                         {
-                             outputSourceMapFile = getOutputSourceMapFile(
-                                     cu.getQualifiedNames().get(0), outputFolder);
-                         }
-                         
-                         writer.writeTo(out, outputSourceMapFile);
-                         out.flush();
-                         out.close();
-                         writer.close();
-                     }
++	                ArrayList<ICompilationUnit> roots = new ArrayList<ICompilationUnit>();
++	                roots.add(mainCU);
++	                Set<ICompilationUnit> incs = target.getIncludesCompilationUnits();
++	                roots.addAll(incs);
++	                List<ICompilationUnit> reachableCompilationUnits = project.getReachableCompilationUnitsInSWFOrder(roots);
++	                for (final ICompilationUnit cu : reachableCompilationUnits)
++	                {
++	                    ICompilationUnit.UnitType cuType = cu.getCompilationUnitType();
++	
++	                    if (cuType == ICompilationUnit.UnitType.AS_UNIT
++	                            || cuType == ICompilationUnit.UnitType.MXML_UNIT)
++	                    {
++	                        final File outputClassFile = getOutputClassFile(
++	                                cu.getQualifiedNames().get(0), outputFolder);
++	
++	                        System.out.println("Compiling file: " + outputClassFile);
++	
++	                        ICompilationUnit unit = cu;
++	
++	                        IJSWriter writer;
++	                        if (cuType == ICompilationUnit.UnitType.AS_UNIT)
++	                        {
++	                            writer = (IJSWriter) JSSharedData.backend.createWriter(project,
++	                                    errors, unit, false);
++	                        }
++	                        else
++	                        {
++	                            writer = (IJSWriter) JSSharedData.backend.createMXMLWriter(
++	                                    project, errors, unit, false);
++	                        }
++	
++	                        BufferedOutputStream out = new BufferedOutputStream(
++	                                new FileOutputStream(outputClassFile));
++	
++	                        File outputSourceMapFile = null;
++	                        if (project.config.getSourceMap())
++	                        {
++	                            outputSourceMapFile = getOutputSourceMapFile(
++	                                    cu.getQualifiedNames().get(0), outputFolder);
++	                        }
++	                        
++	                        writer.writeTo(out, outputSourceMapFile);
++	                        out.flush();
++	                        out.close();
++	                        writer.close();
++	                    }
++	                }
 +                }
- 
++                
 +                if (jsPublisher != null)
 +                {
 +                    compilationSuccess = jsPublisher.publish(problems);
 +                }
 +                else
 +                {
 +                    compilationSuccess = true;
 +                }
 +            }
 +        }
 +        catch (Exception e)
 +        {
 +            final ICompilerProblem problem = new InternalCompilerProblem(e);
 +            problems.add(problem);
 +        }
 +
 +        return compilationSuccess;
 +    }
 +
 +    /**
 +     * Build target artifact.
 +     * 
 +     * @throws InterruptedException threading error
 +     * @throws IOException IO error
 +     * @throws ConfigurationException
 +     */
 +    protected void buildArtifact() throws InterruptedException, IOException,
 +            ConfigurationException
 +    {
 +        jsTarget = buildJSTarget();
 +    }
 +
 +    private IJSApplication buildJSTarget() throws InterruptedException,
 +            FileNotFoundException, ConfigurationException
 +    {
 +        final List<ICompilerProblem> problemsBuildingSWF = new ArrayList<ICompilerProblem>();
 +
 +        project.mainCU = mainCU;
 +        final IJSApplication app = buildApplication(project,
 +                config.getMainDefinition(), mainCU, problemsBuildingSWF);
 +        problems.addAll(problemsBuildingSWF);
 +        if (app == null)
 +        {
 +            ICompilerProblem problem = new UnableToBuildSWFProblem(
 +                    getOutputFilePath());
 +            problems.add(problem);
 +        }
 +
 +        return app;
 +    }
 +
 +    /**
 +     * Replaces FlexApplicationProject::buildSWF()
 +     * 
 +     * @param applicationProject
 +     * @param rootClassName
 +     * @param problems
 +     * @return
 +     * @throws InterruptedException
 +     */
 +
 +    private IJSApplication buildApplication(CompilerProject applicationProject,
 +            String rootClassName, ICompilationUnit mainCU,
 +            Collection<ICompilerProblem> problems) throws InterruptedException,
 +            ConfigurationException, FileNotFoundException
 +    {
 +        Collection<ICompilerProblem> fatalProblems = applicationProject.getFatalProblems();
 +        if (!fatalProblems.isEmpty())
 +        {
 +            problems.addAll(fatalProblems);
 +            return null;
 +        }
 +
 +        return ((JSTarget) target).build(mainCU, problems);
 +    }
 +
 +    /**
 +     * Get the output file path. If {@code -output} is specified, use its value;
 +     * otherwise, use the same base name as the target file.
 +     * 
 +     * @return output file path
 +     */
 +    private String getOutputFilePath()
 +    {
 +        if (config.getOutput() == null)
 +        {
 +            final String extension = "." + JSSharedData.OUTPUT_EXTENSION;
 +            return FilenameUtils.removeExtension(config.getTargetFile()).concat(
 +                    extension);
 +        }
 +        else
 +            return config.getOutput();
 +    }
 +
 +    /**
 +     * @author Erik de Bruin
 +     * 
 +     *         Get the output class file. This includes the (sub)directory in
 +     *         which the original class file lives. If the directory structure
 +     *         doesn't exist, it is created.
 +     * 
 +     * @param qname
 +     * @param outputFolder
 +     * @return output class file path
 +     */
 +    private File getOutputClassFile(String qname, File outputFolder)
 +    {
 +        String[] cname = qname.split("\\.");
 +        String sdirPath = outputFolder + File.separator;
 +        if (cname.length > 0)
 +        {
 +            for (int i = 0, n = cname.length - 1; i < n; i++)
 +            {
 +                sdirPath += cname[i] + File.separator;
 +            }
 +
 +            File sdir = new File(sdirPath);
 +            if (!sdir.exists())
 +                sdir.mkdirs();
 +
 +            qname = cname[cname.length - 1];
 +        }
 +
 +        return new File(sdirPath + qname + "." + JSSharedData.OUTPUT_EXTENSION);
 +    }
 +
 +    /**
 +     * @param qname
 +     * @param outputFolder
 +     * @return output source map file path
 +     */
 +    private File getOutputSourceMapFile(String qname, File outputFolder)
 +    {
 +        String[] cname = qname.split("\\.");
 +        String sdirPath = outputFolder + File.separator;
 +        if (cname.length > 0)
 +        {
 +            for (int i = 0, n = cname.length - 1; i < n; i++)
 +            {
 +                sdirPath += cname[i] + File.separator;
 +            }
 +
 +            File sdir = new File(sdirPath);
 +            if (!sdir.exists())
 +                sdir.mkdirs();
 +
 +            qname = cname[cname.length - 1];
 +        }
 +
 +        return new File(sdirPath + qname + "." + JSSharedData.OUTPUT_EXTENSION + ".map");
 +    }
 +
 +    /**
 +     * Mxmlc uses target file as the main compilation unit and derive the output
 +     * SWF file name from this file.
 +     * 
 +     * @return true if successful, false otherwise.
 +     * @throws OnlyOneSource
 +     * @throws InterruptedException
 +     */
 +    protected boolean setupTargetFile() throws InterruptedException
 +    {
 +        final String mainFileName = config.getTargetFile();
 +
 +        final String normalizedMainFileName = FilenameNormalization.normalize(mainFileName);
 +
 +        final SourceCompilationUnitFactory compilationUnitFactory = project.getSourceCompilationUnitFactory();
 +
 +        File normalizedMainFile = new File(normalizedMainFileName);
 +        if (compilationUnitFactory.canCreateCompilationUnit(normalizedMainFile))
 +        {
 +            project.addIncludeSourceFile(normalizedMainFile);
 +
 +            final List<String> sourcePath = config.getCompilerSourcePath();
 +            String mainQName = null;
 +            if (sourcePath != null && !sourcePath.isEmpty())
 +            {
 +                for (String path : sourcePath)
 +                {
 +                    final String otherPath = new File(path).getAbsolutePath();
 +                    if (mainFileName.startsWith(otherPath))
 +                    {
 +                        mainQName = mainFileName.substring(otherPath.length() + 1);
 +                        mainQName = mainQName.replaceAll("\\\\", "/");
 +                        mainQName = mainQName.replaceAll("\\/", ".");
 +                        if (mainQName.endsWith(".as"))
 +                            mainQName = mainQName.substring(0,
 +                                    mainQName.length() - 3);
 +                        break;
 +                    }
 +                }
 +            }
 +
 +            if (mainQName == null)
 +                mainQName = FilenameUtils.getBaseName(mainFileName);
 +
 +            Collection<ICompilationUnit> mainFileCompilationUnits = workspace.getCompilationUnits(
 +                    normalizedMainFileName, project);
 +
 +            mainCU = Iterables.getOnlyElement(mainFileCompilationUnits);
 +
 +            config.setMainDefinition(mainQName);
 +        }
 +
 +        Preconditions.checkNotNull(mainCU,
 +                "Main compilation unit can't be null");
 +
 +        ITargetSettings settings = getTargetSettings();
 +        if (settings != null)
 +            project.setTargetSettings(settings);
 +
 +        target = JSSharedData.backend.createTarget(project,
 +                getTargetSettings(), null);
 +
 +        return true;
 +    }
 +
 +    private ITargetSettings getTargetSettings()
 +    {
 +        if (targetSettings == null)
 +            targetSettings = projectConfigurator.getTargetSettings(null);
 +
 +        return targetSettings;
 +    }
 +
 +    /**
 +     * Create a new Configurator. This method may be overridden to allow
 +     * Configurator subclasses to be created that have custom configurations.
 +     * 
 +     * @return a new instance or subclass of {@link Configurator}.
 +     */
 +    protected Configurator createConfigurator()
 +    {
 +        return JSSharedData.backend.createConfigurator();
 +    }
 +
 +    /**
 +     * Load configurations from all the sources.
 +     * 
 +     * @param args command line arguments
 +     * @return True if mxmlc should continue with compilation.
 +     */
 +    protected boolean configure(final String[] args)
 +    {
 +        project.getSourceCompilationUnitFactory().addHandler(asFileHandler);
 +        projectConfigurator = createConfigurator();
 +
 +        try
 +        {
 +            if (useFlashBuilderProjectFiles(args)
 +                    && !jsOutputType.equals(JSOutputType.VF2JS))
 +            {
 +                projectConfigurator.setConfiguration(
 +                        FlashBuilderConfigurator.computeFlashBuilderArgs(args,
 +                                getTargetType().getExtension()),
 +                        ICompilerSettingsConstants.FILE_SPECS_VAR);
 +            }
 +            else
 +            {
 +                projectConfigurator.setConfiguration(args,
 +                        ICompilerSettingsConstants.FILE_SPECS_VAR);
 +            }
 +
 +            projectConfigurator.applyToProject(project);
 +            problems = new ProblemQuery(
 +                    projectConfigurator.getCompilerProblemSettings());
 +
 +            project.config = (JSGoogConfiguration)projectConfigurator.getConfiguration();
 +            config = projectConfigurator.getConfiguration();
 +            configBuffer = projectConfigurator.getConfigurationBuffer();
 +            problems.addAll(projectConfigurator.getConfigurationProblems());
 +
 +            if (configBuffer.getVar("version") != null) //$NON-NLS-1$
 +                return false;
 +
 +            if (problems.hasErrors())
 +                return false;
 +
 +            validateTargetFile();
 +            return true;
 +        }
 +        catch (ConfigurationException e)
 +        {
 +            final ICompilerProblem problem = new ConfigurationProblem(e);
 +            problems.add(problem);
 +            return false;
 +        }
 +        catch (Exception e)
 +        {
 +            final ICompilerProblem problem = new ConfigurationProblem(null, -1,
 +                    -1, -1, -1, e.getMessage());
 +            problems.add(problem);
 +            return false;
 +        }
 +        finally
 +        {
 +            if (config == null)
 +            {
 +                config = new Configuration();
 +                configBuffer = new ConfigurationBuffer(Configuration.class,
 +                        Configuration.getAliases());
 +            }
 +        }
 +    }
 +
 +    private boolean useFlashBuilderProjectFiles(String[] args)
 +    {
 +        for (String arg : args)
 +        {
 +            if (arg.equals("-fb")
 +                    || arg.equals("-use-flashbuilder-project-files"))
 +                return true;
 +        }
 +        return false;
 +    }
 +
 +    protected TargetType getTargetType()
 +    {
 +        return TargetType.SWF;
 +    }
 +
 +    /**
 +     * Validate target file.
 +     * 
 +     * @throws MustSpecifyTarget
 +     * @throws IOError
 +     */
 +    protected void validateTargetFile() throws ConfigurationException
 +    {
 +        if (mainCU instanceof ResourceModuleCompilationUnit)
 +            return; //when compiling a Resource Module, no target file is defined.
 +
 +        final String targetFile = config.getTargetFile();
 +        if (targetFile == null)
 +            throw new ConfigurationException.MustSpecifyTarget(null, null, -1);
 +
 +        final File file = new File(targetFile);
 +        if (!file.exists())
 +            throw new ConfigurationException.IOError(targetFile);
 +    }
 +
 +    /**
 +     * Wait till the workspace to finish compilation and close.
 +     */
 +    protected void waitAndClose()
 +    {
 +        workspace.startIdleState();
 +        try
 +        {
 +            workspace.close();
 +        }
 +        finally
 +        {
 +            workspace.endIdleState(Collections.<ICompilerProject, Set<ICompilationUnit>> emptyMap());
 +        }
 +    }
 +
 +    /**
 +     * Force terminate the compilation process.
 +     */
 +    protected void close()
 +    {
 +        workspace.close();
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/de070636/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSessionModel.java
----------------------------------------------------------------------
diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSessionModel.java
index 5c45227,0000000..acd8232
mode 100644,000000..100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSessionModel.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSessionModel.java
@@@ -1,180 -1,0 +1,182 @@@
 +/*
 + *
 + *  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.flex.compiler.internal.codegen.js;
 +
 +import java.util.ArrayList;
 +import java.util.HashMap;
 +import java.util.LinkedHashMap;
 +import java.util.List;
 +import java.util.Stack;
 +
 +import org.apache.flex.compiler.definitions.IClassDefinition;
 +import org.apache.flex.compiler.tree.as.IFunctionNode;
 +import org.apache.flex.compiler.tree.as.IGetterNode;
 +import org.apache.flex.compiler.tree.as.ISetterNode;
 +import org.apache.flex.compiler.tree.as.IVariableNode;
 +
 +/**
 + * @author Michael Schmalle
 + */
 +public class JSSessionModel
 +{
 +    public static final String CONSTRUCTOR_EMPTY = "emptyConstructor";
 +    public static final String CONSTRUCTOR_FULL = "fullConstructor";
 +    public static final String SUPER_FUNCTION_CALL = "replaceSuperFunction";
 +
 +    private IClassDefinition currentClass;
 +
 +    public static class PropertyNodes
 +    {
 +        public IGetterNode getter;
 +        public ISetterNode setter;
 +    }
 +
 +    private static class Context
 +    {
 +    	public LinkedHashMap<String, PropertyNodes> propertyMap;
 +    	public List<String> interfacePropertyMap;
 +    	public LinkedHashMap<String, PropertyNodes> staticPropertyMap;
 +    	public ArrayList<String> bindableVars;
 +    	public ArrayList<IVariableNode> vars;
 +    	public ArrayList<IFunctionNode> methods;
 +    	public IClassDefinition classDefinition;
 +    }
 +    private Stack<Context> stack = new Stack<Context>();
 +    
++    public boolean inE4xFilter = false;
++    
 +    private LinkedHashMap<String, PropertyNodes> propertyMap = new LinkedHashMap<String, PropertyNodes>();
 +
 +    private List<String> interfacePropertyMap = new ArrayList<String>();
 +
 +    private LinkedHashMap<String, PropertyNodes> staticPropertyMap = new LinkedHashMap<String, PropertyNodes>();
 +
 +    private ArrayList<String> bindableVars = new ArrayList<String>();
 +
 +    private ArrayList<IVariableNode> vars = new ArrayList<IVariableNode>();
 +    
 +    private ArrayList<IFunctionNode> methods = new ArrayList<IFunctionNode>();
 +    
 +    private HashMap<String, String> internalClasses;
 +    
 +    private int foreachLoopCount = 0;
 +
 +    public IClassDefinition getCurrentClass()
 +    {
 +        return currentClass;
 +    }
 +
 +    public void setCurrentClass(IClassDefinition currentClass)
 +    {
 +        this.currentClass = currentClass;
 +    }
 +
 +    public void pushClass(IClassDefinition currentClass)
 +    {
 +    	Context context = new Context();
 +    	context.bindableVars = bindableVars;
 +    	context.interfacePropertyMap = interfacePropertyMap;
 +    	context.propertyMap = propertyMap;
 +    	context.staticPropertyMap = staticPropertyMap;
 +    	context.classDefinition = this.currentClass;
 +    	context.vars = vars;
 +    	context.methods = methods;
 +    	stack.push(context);
 +        this.currentClass = currentClass;
 +        bindableVars = new ArrayList<String>();
 +        staticPropertyMap = new LinkedHashMap<String, PropertyNodes>();
 +        interfacePropertyMap = new ArrayList<String>();
 +        propertyMap = new LinkedHashMap<String, PropertyNodes>();
 +        vars = new ArrayList<IVariableNode>();
 +        methods = new ArrayList<IFunctionNode>();
 +    }
 +
 +    public void popClass()
 +    {
 +    	Context context = stack.pop();
 +    	this.currentClass = context.classDefinition;
 +    	bindableVars = context.bindableVars;
 +    	staticPropertyMap = context.staticPropertyMap;
 +    	propertyMap = context.propertyMap;
 +    	interfacePropertyMap = context.interfacePropertyMap;
 +    	vars = context.vars;
 +    	methods = context.methods;
 +    }
 +    
 +    public HashMap<String, PropertyNodes> getPropertyMap()
 +    {
 +        return propertyMap;
 +    }
 +
 +    public List<String> getInterfacePropertyMap()
 +    {
 +        return interfacePropertyMap;
 +    }
 +
 +    public HashMap<String, PropertyNodes> getStaticPropertyMap()
 +    {
 +        return staticPropertyMap;
 +    }
 +
 +    public boolean hasBindableVars()
 +    {
 +        return bindableVars.size() > 0;
 +    }
 +
 +    public List<String> getBindableVars()
 +    {
 +        return bindableVars;
 +    }
 +
 +    public List<IVariableNode> getVars()
 +    {
 +        return vars;
 +    }
 +
 +    public List<IFunctionNode> getMethods()
 +    {
 +        return methods;
 +    }
 +
 +    public HashMap<String, String> getInternalClasses()
 +    {
 +    	if (internalClasses == null)
 +    		internalClasses = new HashMap<String, String>();
 +        return internalClasses;
 +    }
 +
 +    public boolean isInternalClass(String className)
 +    {
 +    	if (internalClasses == null) return false;
 +    	
 +        return internalClasses.containsKey(className);
 +    }
 +
 +    public final void incForeachLoopCount()
 +    {
 +        foreachLoopCount++;
 +    }
 +
 +    public String getCurrentForeachName()
 +    {
 +        return "foreachiter" + Integer.toString(foreachLoopCount);
 +    }
 +
 +}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/de070636/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
----------------------------------------------------------------------
diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
index cde30e8,0000000..c954e2c
mode 100644,000000..100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
@@@ -1,1009 -1,0 +1,1021 @@@
 +/*
 + *
 + *  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.flex.compiler.internal.codegen.js.flexjs;
 +
 +import java.io.FilterWriter;
 +import java.util.ArrayList;
 +import java.util.List;
 +
 +import org.apache.flex.compiler.codegen.js.flexjs.IJSFlexJSEmitter;
 +import org.apache.flex.compiler.codegen.js.goog.IJSGoogDocEmitter;
 +import org.apache.flex.compiler.constants.IASLanguageConstants;
 +import org.apache.flex.compiler.definitions.IClassDefinition;
 +import org.apache.flex.compiler.definitions.IDefinition;
 +import org.apache.flex.compiler.definitions.IPackageDefinition;
 +import org.apache.flex.compiler.definitions.ITypeDefinition;
 +import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
 +import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
 +import org.apache.flex.compiler.internal.codegen.js.jx.AccessorEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.AsIsEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.BinaryOperatorEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.BindableEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.ClassEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.DefinePropertyFunctionEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.FieldEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.ForEachEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.FunctionCallEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.IdentifierEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.InterfaceEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.LiteralEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.MemberAccessEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.MethodEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.ObjectDefinePropertyEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.PackageFooterEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.PackageHeaderEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.SelfReferenceEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.SuperCallEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.VarDeclarationEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.utils.EmitterUtils;
 +import org.apache.flex.compiler.internal.codegen.mxml.flexjs.MXMLFlexJSEmitter;
 +import org.apache.flex.compiler.internal.definitions.AccessorDefinition;
 +import org.apache.flex.compiler.internal.projects.FlexJSProject;
 +import org.apache.flex.compiler.internal.projects.FlexProject;
 +import org.apache.flex.compiler.internal.tree.as.BinaryOperatorAsNode;
 +import org.apache.flex.compiler.internal.tree.as.BlockNode;
 +import org.apache.flex.compiler.internal.tree.as.DynamicAccessNode;
 +import org.apache.flex.compiler.internal.tree.as.FunctionCallNode;
 +import org.apache.flex.compiler.internal.tree.as.IdentifierNode;
 +import org.apache.flex.compiler.internal.tree.as.LabeledStatementNode;
 +import org.apache.flex.compiler.internal.tree.as.MemberAccessExpressionNode;
 +import org.apache.flex.compiler.internal.tree.as.NumericLiteralNode;
 +import org.apache.flex.compiler.projects.ICompilerProject;
 +import org.apache.flex.compiler.tree.ASTNodeID;
 +import org.apache.flex.compiler.tree.as.IASNode;
 +import org.apache.flex.compiler.tree.as.IAccessorNode;
 +import org.apache.flex.compiler.tree.as.IBinaryOperatorNode;
 +import org.apache.flex.compiler.tree.as.IClassNode;
 +import org.apache.flex.compiler.tree.as.IContainerNode;
 +import org.apache.flex.compiler.tree.as.IDefinitionNode;
 +import org.apache.flex.compiler.tree.as.IExpressionNode;
 +import org.apache.flex.compiler.tree.as.IFileNode;
 +import org.apache.flex.compiler.tree.as.IForLoopNode;
 +import org.apache.flex.compiler.tree.as.IFunctionCallNode;
 +import org.apache.flex.compiler.tree.as.IFunctionNode;
 +import org.apache.flex.compiler.tree.as.IFunctionObjectNode;
 +import org.apache.flex.compiler.tree.as.IGetterNode;
 +import org.apache.flex.compiler.tree.as.IIdentifierNode;
 +import org.apache.flex.compiler.tree.as.IInterfaceNode;
 +import org.apache.flex.compiler.tree.as.ILiteralNode;
 +import org.apache.flex.compiler.tree.as.IMemberAccessExpressionNode;
 +import org.apache.flex.compiler.tree.as.INamespaceNode;
 +import org.apache.flex.compiler.tree.as.IPackageNode;
 +import org.apache.flex.compiler.tree.as.IScopedNode;
 +import org.apache.flex.compiler.tree.as.ISetterNode;
 +import org.apache.flex.compiler.tree.as.IUnaryOperatorNode;
 +import org.apache.flex.compiler.tree.as.IVariableNode;
 +import org.apache.flex.compiler.utils.ASNodeUtils;
 +
 +import com.google.common.base.Joiner;
 +
 +/**
 + * Concrete implementation of the 'FlexJS' JavaScript production.
 + * 
 + * @author Michael Schmalle
 + * @author Erik de Bruin
 + */
 +public class JSFlexJSEmitter extends JSGoogEmitter implements IJSFlexJSEmitter
 +{
 +
 +    private JSFlexJSDocEmitter docEmitter = null;
 +
 +    private PackageHeaderEmitter packageHeaderEmitter;
 +    public PackageFooterEmitter packageFooterEmitter;
 +
 +    private BindableEmitter bindableEmitter;
 +
 +    private ClassEmitter classEmitter;
 +    private InterfaceEmitter interfaceEmitter;
 +
 +    private FieldEmitter fieldEmitter;
 +    public VarDeclarationEmitter varDeclarationEmitter;
 +    public AccessorEmitter accessorEmitter;
 +    public MethodEmitter methodEmitter;
 +
 +    private FunctionCallEmitter functionCallEmitter;
 +    private SuperCallEmitter superCallEmitter;
 +    private ForEachEmitter forEachEmitter;
 +    private MemberAccessEmitter memberAccessEmitter;
 +    private BinaryOperatorEmitter binaryOperatorEmitter;
 +    private IdentifierEmitter identifierEmitter;
 +    private LiteralEmitter literalEmitter;
 +
 +    private AsIsEmitter asIsEmitter;
 +    private SelfReferenceEmitter selfReferenceEmitter;
 +    private ObjectDefinePropertyEmitter objectDefinePropertyEmitter;
 +    private DefinePropertyFunctionEmitter definePropertyFunctionEmitter;
 +
 +    public ArrayList<String> usedNames = new ArrayList<String>();
 +    
 +    @Override
 +    public String postProcess(String output)
 +    {
 +        output = super.postProcess(output);
 +        
 +    	String[] lines = output.split("\n");
 +    	ArrayList<String> finalLines = new ArrayList<String>();
 +        boolean foundLanguage = false;
 +        boolean foundXML = false;
 +    	boolean sawRequires = false;
 +    	boolean stillSearching = true;
 +        int addIndex = -1;
 +        int len = lines.length;
 +    	for (int i = 0; i < len; i++)
 +    	{
 +            String line = lines[i];
 +    		if (stillSearching)
 +    		{
 +                int c = line.indexOf(JSGoogEmitterTokens.GOOG_PROVIDE.getToken());
 +                if (c != -1)
 +                {
 +                    // if zero requires are found, require Language after the
 +                    // call to goog.provide
 +                    addIndex = i + 1;
 +                }
 +	            c = line.indexOf(JSGoogEmitterTokens.GOOG_REQUIRE.getToken());
 +	            if (c != -1)
 +	            {
 +                    // we found other requires, so we'll just add Language at
 +                    // the end of the list
 +                    addIndex = -1;
 +	                int c2 = line.indexOf(")");
 +	                String s = line.substring(c + 14, c2 - 1);
 +                    if (s.equals(JSFlexJSEmitterTokens.LANGUAGE_QNAME.getToken()))
 +                    {
 +                        foundLanguage = true;
 +                    }
 +                    else if (s.equals(IASLanguageConstants.XML))
 +                    {
 +                        foundXML = true;
 +                    }
 +	    			sawRequires = true;
 +	    			if (!usedNames.contains(s))
 +                    {
 +                        removeLineFromMappings(i);
 +                        continue;
 +                    }
 +	    		}
 +	    		else if (sawRequires || i == len - 1)
 +                {
 +                    stillSearching = false;
 +
 +                    //when we emitted the requires based on the imports, we may
 +                    //not have known if Language was needed yet because the
 +                    //imports are at the beginning of the file. other code,
 +                    //later in the file, may require Language. 
 +                    ICompilerProject project = getWalker().getProject();
 +                    if (project instanceof FlexJSProject)
 +                    {
 +                        FlexJSProject flexJSProject = (FlexJSProject) project;
 +                        boolean needLanguage = flexJSProject.needLanguage;
 +                        if (needLanguage && !foundLanguage)
 +                        {
 +                            StringBuilder appendString = new StringBuilder();
 +                            appendString.append(JSGoogEmitterTokens.GOOG_REQUIRE.getToken());
 +                            appendString.append(ASEmitterTokens.PAREN_OPEN.getToken());
 +                            appendString.append(ASEmitterTokens.SINGLE_QUOTE.getToken());
 +                            appendString.append(JSFlexJSEmitterTokens.LANGUAGE_QNAME.getToken());
 +                            appendString.append(ASEmitterTokens.SINGLE_QUOTE.getToken());
 +                            appendString.append(ASEmitterTokens.PAREN_CLOSE.getToken());
 +                            appendString.append(ASEmitterTokens.SEMICOLON.getToken());
 +                            if(addIndex != -1)
 +                            {
 +                                // if we didn't find other requires, this index
 +                                // points to the line after goog.provide
 +                                finalLines.add(addIndex, appendString.toString());
 +                                addLineToMappings(addIndex);
 +                            }
 +                            else
 +                            {
 +                                finalLines.add(appendString.toString());
 +                                addLineToMappings(i);
 +                            }
 +                        }
 +                        boolean needXML = flexJSProject.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());
 +                            if(addIndex != -1)
 +                            {
 +                                // if we didn't find other requires, this index
 +                                // points to the line after goog.provide
 +                                finalLines.add(addIndex, appendString.toString());
 +                                addLineToMappings(addIndex);
 +                            }
 +                            else
 +                            {
 +                                finalLines.add(appendString.toString());
 +                                addLineToMappings(i);
 +                            }
 +                        }
 +                    }
 +                }
 +    		}
 +    		finalLines.add(line);
 +    	}
 +    	
 +    	return Joiner.on("\n").join(finalLines);
 +    }
 +    
 +    public BindableEmitter getBindableEmitter()
 +    {
 +        return bindableEmitter;
 +    }
 +
 +    public ClassEmitter getClassEmiter()
 +    {
 +        return classEmitter;
 +    }
 +
 +    public AccessorEmitter getAccessorEmitter()
 +    {
 +        return accessorEmitter;
 +    }
 +
 +    public PackageFooterEmitter getPackageFooterEmitter()
 +    {
 +        return packageFooterEmitter;
 +    }
 +
 +    // TODO (mschmalle) Fix; this is not using the backend doc strategy for replacement
 +    @Override
 +    public IJSGoogDocEmitter getDocEmitter()
 +    {
 +        if (docEmitter == null)
 +            docEmitter = new JSFlexJSDocEmitter(this);
 +        return docEmitter;
 +    }
 +
 +    public JSFlexJSEmitter(FilterWriter out)
 +    {
 +        super(out);
 +
 +        packageHeaderEmitter = new PackageHeaderEmitter(this);
 +        packageFooterEmitter = new PackageFooterEmitter(this);
 +
 +        bindableEmitter = new BindableEmitter(this);
 +
 +        classEmitter = new ClassEmitter(this);
 +        interfaceEmitter = new InterfaceEmitter(this);
 +
 +        fieldEmitter = new FieldEmitter(this);
 +        varDeclarationEmitter = new VarDeclarationEmitter(this);
 +        accessorEmitter = new AccessorEmitter(this);
 +        methodEmitter = new MethodEmitter(this);
 +
 +        functionCallEmitter = new FunctionCallEmitter(this);
 +        superCallEmitter = new SuperCallEmitter(this);
 +        forEachEmitter = new ForEachEmitter(this);
 +        memberAccessEmitter = new MemberAccessEmitter(this);
 +        binaryOperatorEmitter = new BinaryOperatorEmitter(this);
 +        identifierEmitter = new IdentifierEmitter(this);
 +        literalEmitter = new LiteralEmitter(this);
 +
 +        asIsEmitter = new AsIsEmitter(this);
 +        selfReferenceEmitter = new SelfReferenceEmitter(this);
 +        objectDefinePropertyEmitter = new ObjectDefinePropertyEmitter(this);
 +        definePropertyFunctionEmitter = new DefinePropertyFunctionEmitter(this);
 +        
 +    }
 +
 +    @Override
 +    protected void writeIndent()
 +    {
 +        write(JSFlexJSEmitterTokens.INDENT);
 +    }
 +
 +    @Override
 +    protected String getIndent(int numIndent)
 +    {
 +        final StringBuilder sb = new StringBuilder();
 +        for (int i = 0; i < numIndent; i++)
 +            sb.append(JSFlexJSEmitterTokens.INDENT.getToken());
 +        return sb.toString();
 +    }
 +
 +    @Override
 +    public void emitLocalNamedFunction(IFunctionNode node)
 +    {
 +		IFunctionNode fnNode = (IFunctionNode)node.getAncestorOfType(IFunctionNode.class);
 +    	if (fnNode.getEmittingLocalFunctions())
 +    	{
 +    		super.emitLocalNamedFunction(node);
 +    	}
 +    }
 +    
 +    @Override
 +    public void emitFunctionBlockHeader(IFunctionNode node)
 +    {
 +    	node.setEmittingLocalFunctions(true);
 +    	super.emitFunctionBlockHeader(node);
 +    	if (node.isConstructor())
 +    	{
 +            IClassNode cnode = (IClassNode) node
 +            .getAncestorOfType(IClassNode.class);
 +            emitComplexInitializers(cnode);
 +    	}
 +        if (node.containsLocalFunctions())
 +        {
 +            List<IFunctionNode> anonFns = node.getLocalFunctions();
 +            int n = anonFns.size();
 +            for (int i = 0; i < n; i++)
 +            {
 +                IFunctionNode anonFn = anonFns.get(i);
 +                if (anonFn.getParent().getNodeID() == ASTNodeID.AnonymousFunctionID)
 +                {
 +                    write("var /** @type {Function} */ __localFn" + Integer.toString(i) + "__ = ");
 +                	getWalker().walk(anonFn.getParent());
 +                }
 +                else
 +                {
 +                	getWalker().walk(anonFn);
 +                	write(ASEmitterTokens.SEMICOLON);
 +                }
 +                this.writeNewline();
 +            }
 +        }
 +    	node.setEmittingLocalFunctions(false);
 +    }
 +    
 +    @Override
 +    public void emitFunctionObject(IFunctionObjectNode node)
 +    {
 +		IFunctionNode fnNode = (IFunctionNode)node.getAncestorOfType(IFunctionNode.class);
 +    	if (fnNode == null || fnNode.getEmittingLocalFunctions())
 +    	{
 +    		super.emitFunctionObject(node);
 +    	}
 +    	else
 +    	{
 +            List<IFunctionNode> anonFns = fnNode.getLocalFunctions();
 +            int i = anonFns.indexOf(node.getFunctionNode());
 +            if (i < 0)
 +            	System.out.println("missing index for " + node.toString());
 +            else
 +            	write("__localFn" + Integer.toString(i) + "__");
 +    	}
 +    }
 +    
 +    @Override
 +    public void emitNamespace(INamespaceNode node)
 +    {
 +        write(formatQualifiedName(node.getName()));
 +        write(ASEmitterTokens.SPACE);
 +        writeToken(ASEmitterTokens.EQUAL);
 +        writeToken(ASEmitterTokens.NEW);
 +        write(IASLanguageConstants.Namespace);
 +        write(ASEmitterTokens.PAREN_OPEN);
 +        getWalker().walk(node.getNamespaceURINode());
 +        write(ASEmitterTokens.PAREN_CLOSE);
 +        write(ASEmitterTokens.SEMICOLON);
 +    }
 +
 +    @Override
 +    public void emitMemberName(IDefinitionNode node)
 +    {
 +        write(node.getName());
 +    }
 +
 +    @Override
 +    public String formatQualifiedName(String name)
 +    {
 +        return formatQualifiedName(name, false);
 +    }
 +
 +    public MXMLFlexJSEmitter mxmlEmitter = null;
 +    
 +    public String formatQualifiedName(String name, boolean isDoc)
 +    {
 +    	if (mxmlEmitter != null)
 +    		name = mxmlEmitter.formatQualifiedName(name);
 +        /*
 +        if (name.contains("goog.") || name.startsWith("Vector."))
 +            return name;
 +        name = name.replaceAll("\\.", "_");
 +        */
 +    	if (getModel().isInternalClass(name))
 +    		return getModel().getInternalClasses().get(name);
 +    	if (name.startsWith("window."))
 +    		name = name.substring(7);
 +    	else if (!isDoc)
 +    	{
 +    		if (!usedNames.contains(name))
 +    			usedNames.add(name);
 +    	}
 +        return name;
 +    }
 +    
 +    //--------------------------------------------------------------------------
 +    // Package Level
 +    //--------------------------------------------------------------------------
 +
 +    @Override
 +    public void emitPackageHeader(IPackageDefinition definition)
 +    {
 +    	IPackageNode packageNode = definition.getNode();
 +    	IFileNode fileNode = (IFileNode) packageNode.getAncestorOfType(IFileNode.class);
 +        int nodeCount = fileNode.getChildCount();
 +        String mainClassName = null;
 +        for (int i = 0; i < nodeCount; i++)
 +        {
 +	        IASNode pnode = fileNode.getChild(i);
 +	        
 +	        if (pnode instanceof IPackageNode)
 +	        {
 +	        	IScopedNode snode = ((IPackageNode)pnode).getScopedNode();
 +	            int snodeCount = snode.getChildCount();
 +	            for (int j = 0; j < snodeCount; j++)
 +	            {
 +	    	        IASNode cnode = snode.getChild(j);
 +	    	        if (cnode instanceof IClassNode)
 +	    	        {
 +	    	        	mainClassName = ((IClassNode)cnode).getQualifiedName();
 +	    	        	break;
 +	    	        }
 +	            }
 +	        }
 +	        else if (pnode instanceof IClassNode)
 +	        {
 +	        	String className = ((IClassNode)pnode).getQualifiedName();
 +	        	getModel().getInternalClasses().put(className, mainClassName + "." + className);
 +	        }
 +	        else if (pnode instanceof IInterfaceNode)
 +	        {
 +	        	String className = ((IInterfaceNode)pnode).getQualifiedName();
 +	        	getModel().getInternalClasses().put(className, mainClassName + "." + className);
 +	        }
 +            else if (pnode instanceof IFunctionNode)
 +            {
 +                String className = ((IFunctionNode)pnode).getQualifiedName();
 +                getModel().getInternalClasses().put(className, mainClassName + "." + className);
 +            }
 +            else if (pnode instanceof INamespaceNode)
 +            {
 +                String className = ((INamespaceNode)pnode).getQualifiedName();
 +                getModel().getInternalClasses().put(className, mainClassName + "." + className);
 +            }
 +            else if (pnode instanceof IVariableNode)
 +            {
 +                String className = ((IVariableNode)pnode).getQualifiedName();
 +                getModel().getInternalClasses().put(className, mainClassName + "." + className);
 +            }
 +        }
 +        
 +        packageHeaderEmitter.emit(definition);
 +    }
 +
 +    @Override
 +    public void emitPackageHeaderContents(IPackageDefinition definition)
 +    {
 +        packageHeaderEmitter.emitContents(definition);
 +        usedNames.clear();
 +    }
 +
 +    @Override
 +    public void emitPackageFooter(IPackageDefinition definition)
 +    {
 +        packageFooterEmitter.emit(definition);
 +    }
 +
 +    //--------------------------------------------------------------------------
 +    // Class
 +    //--------------------------------------------------------------------------
 +
 +    @Override
 +    public void emitClass(IClassNode node)
 +    {
 +        classEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitInterface(IInterfaceNode node)
 +    {
 +        interfaceEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitField(IVariableNode node)
 +    {
 +        fieldEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitVarDeclaration(IVariableNode node)
 +    {
 +        varDeclarationEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitAccessors(IAccessorNode node)
 +    {
 +        accessorEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitGetAccessor(IGetterNode node)
 +    {
 +        accessorEmitter.emitGet(node);
 +    }
 +
 +    @Override
 +    public void emitSetAccessor(ISetterNode node)
 +    {
 +        accessorEmitter.emitSet(node);
 +    }
 +
 +    @Override
 +    public void emitMethod(IFunctionNode node)
 +    {
 +        methodEmitter.emit(node);
 +    }
 +
 +    public void emitComplexInitializers(IClassNode node)
 +    {
 +    	classEmitter.emitComplexInitializers(node);
 +    }
 +    
 +    //--------------------------------------------------------------------------
 +    // Statements
 +    //--------------------------------------------------------------------------
 +
 +    @Override
 +    public void emitFunctionCall(IFunctionCallNode node)
 +    {
 +        functionCallEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitForEachLoop(IForLoopNode node)
 +    {
 +        forEachEmitter.emit(node);
 +    }
 +
 +    //--------------------------------------------------------------------------
 +    // Expressions
 +    //--------------------------------------------------------------------------
 +
 +    @Override
 +    public void emitSuperCall(IASNode node, String type)
 +    {
 +        superCallEmitter.emit(node, type);
 +    }
 +
 +    @Override
 +    public void emitMemberAccessExpression(IMemberAccessExpressionNode node)
 +    {
 +        memberAccessEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitArguments(IContainerNode node)
 +    {
 +        IContainerNode newNode = node;
 +        int len = node.getChildCount();
 +    	if (len == 2)
 +    	{
 +            ICompilerProject project = getWalker().getProject();;
 +    		IFunctionCallNode fcNode = (IFunctionCallNode) node.getParent();
 +    		IExpressionNode nameNode = fcNode.getNameNode();
 +            IDefinition def = nameNode.resolve(project);
 +        	if (def != null && def.getBaseName().equals("insertAt"))
 +        	{
 +        		if (def.getParent() != null &&
 +            		def.getParent().getQualifiedName().equals("Array"))
 +        		{
 +            		if (nameNode instanceof MemberAccessExpressionNode)
 +            		{
 +                        newNode = EmitterUtils.insertArgumentsAt(node, 1, new NumericLiteralNode("0"));
 +            		}
 +    			}
 +    		}
 +    	}
 +        if (len == 1)
 +        {
 +            ICompilerProject project = getWalker().getProject();;
 +            IFunctionCallNode fcNode = (IFunctionCallNode) node.getParent();
 +            IExpressionNode nameNode = fcNode.getNameNode();
 +            IDefinition def = nameNode.resolve(project);
 +            if (def != null && def.getBaseName().equals("removeAt"))
 +            {
 +                if (def.getParent() != null &&
 +                        def.getParent().getQualifiedName().equals("Array"))
 +                {
 +                    if (nameNode instanceof MemberAccessExpressionNode)
 +                    {
 +                        newNode = EmitterUtils.insertArgumentsAfter(node, new NumericLiteralNode("1"));
 +                    }
 +                }
 +            }
 +            else if (def != null && def.getBaseName().equals("parseInt"))
 +            {
 +                IDefinition parentDef = def.getParent();
 +                if (parentDef == null)
 +                {
 +                    if (nameNode instanceof IdentifierNode)
 +                    {
 +                        newNode = EmitterUtils.insertArgumentsAfter(node, new NumericLiteralNode("10"));
 +                    }
 +                }
 +            }
 +        }
 +        super.emitArguments(newNode);
 +    }
 +
 +    @Override
 +    public void emitE4XFilter(IMemberAccessExpressionNode node)
 +    {
++    	getModel().inE4xFilter = true;
 +    	getWalker().walk(node.getLeftOperandNode());
 +    	write(".filter(function(node){return (node.");
 +    	String s = stringifyNode(node.getRightOperandNode());
 +    	if (s.startsWith("(") && s.endsWith(")"))
 +    		s = s.substring(1, s.length() - 1);
 +    	write(s);
 +    	write(")})");
++    	getModel().inE4xFilter = false;
 +    }
 +
 +    @Override
 +    public void emitBinaryOperator(IBinaryOperatorNode node)
 +    {
 +        binaryOperatorEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitIdentifier(IIdentifierNode node)
 +    {
 +        identifierEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitLiteral(ILiteralNode node)
 +    {
 +        literalEmitter.emit(node);
 +    }
 +
 +    //--------------------------------------------------------------------------
 +    // Specific
 +    //--------------------------------------------------------------------------
 +
 +    public void emitIsAs(IExpressionNode node, IExpressionNode left, IExpressionNode right, ASTNodeID id, boolean coercion)
 +    {
 +        asIsEmitter.emitIsAs(node, left, right, id, coercion);
 +    }
 +
 +    @Override
 +    protected void emitSelfReference(IFunctionNode node)
 +    {
 +        selfReferenceEmitter.emit(node);
 +    }
 +
 +    @Override
 +    protected void emitObjectDefineProperty(IAccessorNode node)
 +    {
 +        objectDefinePropertyEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitDefinePropertyFunction(IAccessorNode node)
 +    {
 +        definePropertyFunctionEmitter.emit(node);
 +    }
 +    
 +    public String stringifyDefineProperties(IClassDefinition cdef)
 +    {
 +    	setBufferWrite(true);
 +    	accessorEmitter.emit(cdef);
 +        String result = getBuilder().toString();
 +        getBuilder().setLength(0);
 +        setBufferWrite(false);
 +        return result;
 +    }
 +
 +    @Override
 +	public void emitClosureStart()
 +    {
 +        ICompilerProject project = getWalker().getProject();;
 +        if (project instanceof FlexJSProject)
 +        	((FlexJSProject)project).needLanguage = true;
 +        write(JSFlexJSEmitterTokens.CLOSURE_FUNCTION_NAME);
 +        write(ASEmitterTokens.PAREN_OPEN);
 +    }
 +
 +    @Override
 +	public void emitClosureEnd(IASNode node)
 +    {
 +    	write(ASEmitterTokens.COMMA);
 +    	write(ASEmitterTokens.SPACE);
 +    	write(ASEmitterTokens.SINGLE_QUOTE);
 +    	if (node.getNodeID() == ASTNodeID.IdentifierID)
 +    		write(((IIdentifierNode)node).getName());
 +    	else if (node.getNodeID() == ASTNodeID.MemberAccessExpressionID)
 +    		writeChainName(node);
 +    	else
 +    		System.out.println("unexpected node in emitClosureEnd");
 +    	write(ASEmitterTokens.SINGLE_QUOTE);
 +        write(ASEmitterTokens.PAREN_CLOSE);
 +    }
 +    
 +    @Override
 +    public void emitStatement(IASNode node)
 +    {
 +    	// don't emit named local functions as statements
 +    	// they are emitted as part of the function block header
 +    	if (node.getNodeID() == ASTNodeID.FunctionID)
 +    	{
 +    		return;
 +    	}
 +    	super.emitStatement(node);
 +    }
 +    private void writeChainName(IASNode node)
 +    {
 +    	while (node.getNodeID() == ASTNodeID.MemberAccessExpressionID)
 +    	{    		
 +    		node = ((IMemberAccessExpressionNode)node).getRightOperandNode();
 +    	}
 +    	if (node.getNodeID() == ASTNodeID.IdentifierID)
 +    		write(((IdentifierNode)node).getName());
 +    	else
 +    		System.out.println("unexpected node in emitClosureEnd");
 +    }
 +    
 +    @Override
 +    public void emitUnaryOperator(IUnaryOperatorNode node)
 +    {
 +        if (node.getNodeID() == ASTNodeID.Op_DeleteID)
 +        {
 +        	if (node.getChild(0).getNodeID() == ASTNodeID.ArrayIndexExpressionID)
 +        	{
 +        		if (node.getChild(0).getChild(0).getNodeID() == ASTNodeID.MemberAccessExpressionID)
 +        		{
 +        			MemberAccessExpressionNode obj = (MemberAccessExpressionNode)(node.getChild(0).getChild(0));
 +        			if (isXMLList(obj))
 +        			{
 +        		        if (ASNodeUtils.hasParenOpen(node))
 +        		            write(ASEmitterTokens.PAREN_OPEN);
 +        		        
 +        	            getWalker().walk(obj);
 +        	            DynamicAccessNode dan = (DynamicAccessNode)(node.getChild(0));
 +        	            IASNode indexNode = dan.getChild(1);
 +        	            write(".removeChildAt(");
 +        	            getWalker().walk(indexNode);
 +        	            write(")");
 +        		        if (ASNodeUtils.hasParenClose(node))
 +        		            write(ASEmitterTokens.PAREN_CLOSE);
 +        		        return;
 +        			}
 +        		}
 +        		else if (node.getChild(0).getChild(0).getNodeID() == ASTNodeID.IdentifierID)
 +        		{
 +        			if (isXML((IdentifierNode)(node.getChild(0).getChild(0))))
 +        			{
 +        		        if (ASNodeUtils.hasParenOpen(node))
 +        		            write(ASEmitterTokens.PAREN_OPEN);
 +        		        
 +        	            getWalker().walk(node.getChild(0).getChild(0));
 +        	            DynamicAccessNode dan = (DynamicAccessNode)(node.getChild(0));
 +        	            IASNode indexNode = dan.getChild(1);
 +        	            write(".removeChild(");
 +        	            getWalker().walk(indexNode);
 +        	            write(")");
 +        		        if (ASNodeUtils.hasParenClose(node))
 +        		            write(ASEmitterTokens.PAREN_CLOSE);
 +        		        return;        				
 +        			}
 +        			else if (isProxy((IdentifierNode)(node.getChild(0).getChild(0))))
 +        			{
 +        		        if (ASNodeUtils.hasParenOpen(node))
 +        		            write(ASEmitterTokens.PAREN_OPEN);
 +        		        
 +        	            getWalker().walk(node.getChild(0).getChild(0));
 +        	            DynamicAccessNode dan = (DynamicAccessNode)(node.getChild(0));
 +        	            IASNode indexNode = dan.getChild(1);
 +        	            write(".deleteProperty(");
 +        	            getWalker().walk(indexNode);
 +        	            write(")");
 +        		        if (ASNodeUtils.hasParenClose(node))
 +        		            write(ASEmitterTokens.PAREN_CLOSE);
 +        		        return;        				
 +        			}
 +        		}
 +
 +        	}
 +        	else if (node.getChild(0).getNodeID() == ASTNodeID.MemberAccessExpressionID)
 +    		{
 +    			MemberAccessExpressionNode obj = (MemberAccessExpressionNode)(node.getChild(0));
 +    			if (isXMLList(obj))
 +    			{
 +    		        if (ASNodeUtils.hasParenOpen(node))
 +    		            write(ASEmitterTokens.PAREN_OPEN);
 +    		        
 +    	            String s = stringifyNode(obj.getLeftOperandNode());
 +    	            write(s);
 +    	            write(".removeChild('");
 +    	            s = stringifyNode(obj.getRightOperandNode());
 +    	            write(s);
 +    	            write("')");
 +    		        if (ASNodeUtils.hasParenClose(node))
 +    		            write(ASEmitterTokens.PAREN_CLOSE);
 +    		        return;
 +    			}
 +    		}
 +
 +        }
 +        else if (node.getNodeID() == ASTNodeID.Op_AtID)
 +        {
 +        	write("attribute('");
 +            getWalker().walk(node.getOperandNode());
 +        	write("')");
 +        	return;
 +        }
 +
 +        super.emitUnaryOperator(node);
 +
 +    }
 +
 +    /**
 +     * resolveType on an XML expression returns null
 +     * (see IdentiferNode.resolveType).
 +     * So, we have to walk the tree ourselves and resolve
 +     * individual pieces.
 +     * @param obj
 +     * @return
 +     */
 +    public boolean isXMLList(MemberAccessExpressionNode obj)
 +    {
 +    	IExpressionNode leftNode = obj.getLeftOperandNode();
 +    	IExpressionNode rightNode = obj.getRightOperandNode();
 +    	ASTNodeID rightID = rightNode.getNodeID();
 +		if (rightID == ASTNodeID.IdentifierID)
 +		{
 +			IDefinition rightDef = rightNode.resolveType(getWalker().getProject());
 +			if (rightDef != null)
 +				return IdentifierNode.isXMLish(rightDef, getWalker().getProject());
 +		}
 +    	ASTNodeID leftID = leftNode.getNodeID();
 +		if (leftID == ASTNodeID.IdentifierID)
 +		{
 +			IDefinition leftDef = leftNode.resolveType(getWalker().getProject());
 +			if (leftDef != null)
 +				return IdentifierNode.isXMLish(leftDef, getWalker().getProject());
 +		}
 +		else if (leftID == ASTNodeID.MemberAccessExpressionID)
 +		{
 +			return isXMLList((MemberAccessExpressionNode)leftNode);
 +		}
 +		else if (leftID == ASTNodeID.FunctionCallID)
 +		{
 +			FunctionCallNode fcn = (FunctionCallNode)leftNode;
 +			String fname = fcn.getFunctionName();
 +			if (fname.equals("XML") || fname.equals("XMLList"))
 +				return true;
 +		}
 +		else if (leftID == ASTNodeID.Op_AsID)
 +		{
 +			BinaryOperatorAsNode boan = (BinaryOperatorAsNode)leftNode;
 +			String fname = ((IdentifierNode)boan.getChild(1)).getName();
 +			if (fname.equals("XML") || fname.equals("XMLList"))
 +				return true;
 +		}
++		else if (leftID == ASTNodeID.ArrayIndexExpressionID)
++		{
++			leftNode = (IExpressionNode)(leftNode.getChild(0));
++			IDefinition leftDef = leftNode.resolveType(getWalker().getProject());
++			if (leftDef != null)
++				return IdentifierNode.isXMLish(leftDef, getWalker().getProject());
++
++		}
++		else if (leftID == ASTNodeID.E4XFilterID)
++			return true;
 +    	return false;
 +    }
 +    
 +    /**
 +     * resolveType on an XML expression returns null
 +     * (see IdentiferNode.resolveType).
 +     * So, we have to walk the tree ourselves and resolve
 +     * individual pieces.
 +     * @param obj
 +     * @return
 +     */
 +    public boolean isProxy(IExpressionNode obj)
 +    {
 +		FlexProject project = (FlexProject)getWalker().getProject();
 +		// See if it is Proxy
 +		ITypeDefinition leftDef = obj.resolveType(project);
 +		if (leftDef == null)
 +		{
 +			if (obj.getNodeID() == ASTNodeID.MemberAccessExpressionID)
 +			{
 +				IExpressionNode leftNode = ((MemberAccessExpressionNode)obj).getLeftOperandNode();
 +				leftDef = leftNode.resolveType(project);
 +				if (leftDef != null && leftDef.isInstanceOf(project.getProxyBaseClass(), project))
 +					return true;
 +				while (leftNode.getNodeID() == ASTNodeID.MemberAccessExpressionID)
 +				{
 +					// walk up chain looking for a proxy
 +					leftNode = ((MemberAccessExpressionNode)leftNode).getLeftOperandNode();
 +					leftDef = leftNode.resolveType(project);
 +					if (leftDef != null && leftDef.isInstanceOf(project.getProxyBaseClass(), project))
 +						return true;
 +				}
 +			}
 +			return false;
 +		}
 +		return leftDef.isInstanceOf(project.getProxyBaseClass(), project);
 +    }
 +    
 +    /**
 +     * resolveType on an XML expression returns null
 +     * (see IdentiferNode.resolveType).
 +     * So, we have to walk the tree ourselves and resolve
 +     * individual pieces.
 +     * @param obj
 +     * @return
 +     */
 +    public boolean isDateProperty(IExpressionNode obj)
 +    {
 +		FlexProject project = (FlexProject)getWalker().getProject();
 +		if (obj.getNodeID() == ASTNodeID.MemberAccessExpressionID)
 +		{
 +			IDefinition leftDef;
 +			IExpressionNode leftNode = ((MemberAccessExpressionNode)obj).getLeftOperandNode();
 +			IExpressionNode rightNode = ((MemberAccessExpressionNode)obj).getRightOperandNode();
 +			leftDef = leftNode.resolveType(project);
 +			IDefinition rightDef = rightNode.resolve(project);
 +			if (leftDef != null && leftDef.getQualifiedName().equals("Date") && rightDef instanceof AccessorDefinition)
 +			{
 +				return true;
 +			}
 +		}
 +		return false;
 +	}
 +    
 +    /**
 +     * resolveType on an XML expression returns null
 +     * (see IdentiferNode.resolveType).
 +     * So, we have to walk the tree ourselves and resolve
 +     * individual pieces.
 +     * @param obj
 +     * @return
 +     */
 +    public boolean isXML(IExpressionNode obj)
 +    {
 +		// See if the left side is XML or XMLList
 +		IDefinition leftDef = obj.resolveType(getWalker().getProject());
 +		return IdentifierNode.isXMLish(leftDef, getWalker().getProject());
 +    }
 +    
 +    public MemberAccessExpressionNode getLastMAEInChain(MemberAccessExpressionNode node)
 +    {
 +    	while (node.getRightOperandNode() instanceof MemberAccessExpressionNode)
 +    		node = (MemberAccessExpressionNode)node.getRightOperandNode();
 +    	return node;
 +    }
 +    
 +    @Override
 +    public void emitLabelStatement(LabeledStatementNode node)
 +    {
 +    	BlockNode innerBlock = node.getLabeledStatement();
 +    	if (innerBlock.getChildCount() == 1 && innerBlock.getChild(0).getNodeID() == ASTNodeID.ForEachLoopID)
 +    	{        
 +    		getWalker().walk(node.getLabeledStatement());
 +    		return; // for each emitter will emit label in the right spot
 +    	}
 +    	super.emitLabelStatement(node);
 +    }
 +}