compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCNode.java [360:878]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        watcherThread.start();
    }

    /**
     * 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()
    {
        JSGoogConfiguration googConfiguration = (JSGoogConfiguration) config;
        boolean compilationSuccess = false;

        try
        {
            project.getSourceCompilationUnitFactory().addHandler(asFileHandler);

            if (!googConfiguration.getSkipTranspile())
            {
	            if (!setupTargetFile()) {
                    return false;
                }

	            buildArtifact();
            }
            if (jsTarget != null || googConfiguration.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;
                }

                Set<String> closurePropNamesToKeep = new HashSet<String>();
                //use a LinkedHashSet because the order of the exported names matters -JT
                LinkedHashSet<String> closureSymbolNamesToExport = new LinkedHashSet<String>();
                jsPublisher = (IJSGoogPublisher) project.getBackend().createPublisher(
                        project, errors, config);

                File outputFolder = jsPublisher.getOutputFolder();

                if (!googConfiguration.getSkipTranspile())
                {
	                ArrayList<ICompilationUnit> roots = new ArrayList<ICompilationUnit>();
	                roots.add(mainCU);
	                Set<ICompilationUnit> incs = target.getIncludesCompilationUnits();
	                roots.addAll(incs);
	                project.mixinClassNames = new TreeSet<String>();
	                List<ICompilationUnit> reachableCompilationUnits = project.getReachableCompilationUnitsInSWFOrder(roots);
	                ((RoyaleJSTarget)target).collectMixinMetaData(project.mixinClassNames, reachableCompilationUnits);
	                for (final ICompilationUnit cu : reachableCompilationUnits)
	                {
	                    writeCompilationUnit(cu, outputFolder);
                        ClosureUtils.collectPropertyNamesToKeep(cu, project, closurePropNamesToKeep);
                        ClosureUtils.collectSymbolNamesToExport(cu, project, closureSymbolNamesToExport);
	                }
                }
                
                if (jsPublisher != null)
                {
                    jsPublisher.setClosurePropertyNamesToKeep(closurePropNamesToKeep);
                    jsPublisher.setClosureSymbolNamesToExport(closureSymbolNamesToExport);
                    compilationSuccess = jsPublisher.publish(problems);
                }
                else
                {
                    compilationSuccess = true;
                }
            }
        }
        catch (Exception e)
        {
            final ICompilerProblem problem = new InternalCompilerProblem(e);
            problems.add(problem);
        }

        return compilationSuccess;
    }

    protected void writeCompilationUnit(ICompilationUnit cu, File outputFolder) throws InterruptedException, IOException
    {
        ICompilationUnit.UnitType cuType = cu.getCompilationUnitType();
        if (cuType != ICompilationUnit.UnitType.AS_UNIT
                && cuType != ICompilationUnit.UnitType.MXML_UNIT)
        {
            return;
        }

        final File outputClassFile = getOutputClassFile(
                cu.getQualifiedNames().get(0), outputFolder);

        if (config.isVerbose())
        {
            System.out.println("Compiling file: " + outputClassFile);
        }

        ICompilationUnit unit = cu;

        IJSWriter writer;
        if (cuType == ICompilationUnit.UnitType.AS_UNIT)
        {
            writer = (IJSWriter) project.getBackend().createWriter(project,
                    problems.getProblems(), unit, false);
        }
        else
        {
            writer = (IJSWriter) project.getBackend().createMXMLWriter(
                    project, problems.getProblems(), unit, false);
        }

        BufferedOutputStream out = new BufferedOutputStream(
                new FileOutputStream(outputClassFile));

        BufferedOutputStream sourceMapOut = null;
        File outputSourceMapFile = null;
        if (project.config.getSourceMap())
        {
            outputSourceMapFile = getOutputSourceMapFile(
                    cu.getQualifiedNames().get(0), outputFolder);
            sourceMapOut = new BufferedOutputStream(
                    new FileOutputStream(outputSourceMapFile));
        }
        
        writer.writeTo(out, sourceMapOut, outputSourceMapFile);
        out.flush();
        out.close();
        if (sourceMapOut != null)
        {
            sourceMapOut.flush();
            sourceMapOut.close();
        }
        writer.close();
    }

    /**
     * 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 RoyaleApplicationProject::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 = "." + project.getBackend().getOutputExtension();
            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 + "." + project.getBackend().getOutputExtension());
    }

    /**
     * @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 + "." + project.getBackend().getOutputExtension() + ".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 = project.getBackend().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 project.getBackend().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);
        project.configurator = projectConfigurator = createConfigurator();

        try
        {
            if (useFlashBuilderProjectFiles(args))
            {
                projectConfigurator.setConfiguration(
                        FlashBuilderConfigurator.computeFlashBuilderArgs(args,
                                getTargetType().getExtension()),
                        ICompilerSettingsConstants.FILE_SPECS_VAR);
            }
            else
            {
                projectConfigurator.setConfiguration(args,
                        ICompilerSettingsConstants.FILE_SPECS_VAR);
            }

            projectConfigurator.applyToProject(project);
            project.config = (JSGoogConfiguration) projectConfigurator.getConfiguration();

            config = (JSGoogConfiguration) projectConfigurator.getConfiguration();
            configBuffer = projectConfigurator.getConfigurationBuffer();

            problems = new ProblemQuery(projectConfigurator.getCompilerProblemSettings());
            problems.addAll(projectConfigurator.getConfigurationProblems());

            if (configBuffer.getVar("version") != null) //$NON-NLS-1$
                return false;

            if (problems.hasErrors())
                return false;

            validateTargetFile();
            DefinitionBase.setPerformanceCachingEnabled(!config.getWatch());
            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 JSConfiguration();
                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();
    }
    
    public List<String> getSourceList()
    {
        ArrayList<String> list = new ArrayList<String>();
        try
        {
            ArrayList<ICompilationUnit> roots = new ArrayList<ICompilationUnit>();
            roots.add(mainCU);
            Set<ICompilationUnit> incs = target.getIncludesCompilationUnits();
            roots.addAll(incs);
            project.mixinClassNames = new TreeSet<String>();
            List<ICompilationUnit> units = project.getReachableCompilationUnitsInSWFOrder(roots);
            for (ICompilationUnit unit : units)
            {
                UnitType ut = unit.getCompilationUnitType();
                if (ut == UnitType.AS_UNIT || ut == UnitType.MXML_UNIT)
                {
                    list.add(unit.getAbsoluteFilename());
                }
            }
        }
        catch (InterruptedException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        return list;
    }
    
    public String getMainSource()
    {
        return mainCU.getAbsoluteFilename();
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCRoyaleCordova.java [362:880]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        watcherThread.start();
    }

    /**
     * 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()
    {
        JSGoogConfiguration googConfiguration = (JSGoogConfiguration) config;
        boolean compilationSuccess = false;

        try
        {
            project.getSourceCompilationUnitFactory().addHandler(asFileHandler);

            if (!googConfiguration.getSkipTranspile())
            {
	            if (!setupTargetFile()) {
                    return false;
                }

	            buildArtifact();
            }
            if (jsTarget != null || googConfiguration.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;
                }

                Set<String> closurePropNamesToKeep = new HashSet<String>();
                //use a LinkedHashSet because the order of the exported names matters -JT
                LinkedHashSet<String> closureSymbolNamesToExport = new LinkedHashSet<String>();
                jsPublisher = (IJSGoogPublisher) project.getBackend().createPublisher(
                        project, errors, config);

                File outputFolder = jsPublisher.getOutputFolder();

                if (!googConfiguration.getSkipTranspile())
                {
	                ArrayList<ICompilationUnit> roots = new ArrayList<ICompilationUnit>();
	                roots.add(mainCU);
	                Set<ICompilationUnit> incs = target.getIncludesCompilationUnits();
	                roots.addAll(incs);
	                project.mixinClassNames = new TreeSet<String>();
	                List<ICompilationUnit> reachableCompilationUnits = project.getReachableCompilationUnitsInSWFOrder(roots);
	                ((RoyaleJSTarget)target).collectMixinMetaData(project.mixinClassNames, reachableCompilationUnits);
	                for (final ICompilationUnit cu : reachableCompilationUnits)
	                {
	                    writeCompilationUnit(cu, outputFolder);
                        ClosureUtils.collectPropertyNamesToKeep(cu, project, closurePropNamesToKeep);
                        ClosureUtils.collectSymbolNamesToExport(cu, project, closureSymbolNamesToExport);
	                }
                }
                
                if (jsPublisher != null)
                {
                    jsPublisher.setClosurePropertyNamesToKeep(closurePropNamesToKeep);
                    jsPublisher.setClosureSymbolNamesToExport(closureSymbolNamesToExport);
                    compilationSuccess = jsPublisher.publish(problems);
                }
                else
                {
                    compilationSuccess = true;
                }
            }
        }
        catch (Exception e)
        {
            final ICompilerProblem problem = new InternalCompilerProblem(e);
            problems.add(problem);
        }

        return compilationSuccess;
    }

    protected void writeCompilationUnit(ICompilationUnit cu, File outputFolder) throws InterruptedException, IOException
    {
        ICompilationUnit.UnitType cuType = cu.getCompilationUnitType();
        if (cuType != ICompilationUnit.UnitType.AS_UNIT
                && cuType != ICompilationUnit.UnitType.MXML_UNIT)
        {
            return;
        }

        final File outputClassFile = getOutputClassFile(
                cu.getQualifiedNames().get(0), outputFolder);

        if (config.isVerbose())
        {
            System.out.println("Compiling file: " + outputClassFile);
        }

        ICompilationUnit unit = cu;

        IJSWriter writer;
        if (cuType == ICompilationUnit.UnitType.AS_UNIT)
        {
            writer = (IJSWriter) project.getBackend().createWriter(project,
                    problems.getProblems(), unit, false);
        }
        else
        {
            writer = (IJSWriter) project.getBackend().createMXMLWriter(
                    project, problems.getProblems(), unit, false);
        }

        BufferedOutputStream out = new BufferedOutputStream(
                new FileOutputStream(outputClassFile));

        BufferedOutputStream sourceMapOut = null;
        File outputSourceMapFile = null;
        if (project.config.getSourceMap())
        {
            outputSourceMapFile = getOutputSourceMapFile(
                    cu.getQualifiedNames().get(0), outputFolder);
            sourceMapOut = new BufferedOutputStream(
                    new FileOutputStream(outputSourceMapFile));
        }
        
        writer.writeTo(out, sourceMapOut, outputSourceMapFile);
        out.flush();
        out.close();
        if (sourceMapOut != null)
        {
            sourceMapOut.flush();
            sourceMapOut.close();
        }
        writer.close();
    }

    /**
     * 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 RoyaleApplicationProject::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 = "." + project.getBackend().getOutputExtension();
            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 + "." + project.getBackend().getOutputExtension());
    }

    /**
     * @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 + "." + project.getBackend().getOutputExtension() + ".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 = project.getBackend().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 project.getBackend().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);
        project.configurator = projectConfigurator = createConfigurator();

        try
        {
            if (useFlashBuilderProjectFiles(args))
            {
                projectConfigurator.setConfiguration(
                        FlashBuilderConfigurator.computeFlashBuilderArgs(args,
                                getTargetType().getExtension()),
                        ICompilerSettingsConstants.FILE_SPECS_VAR);
            }
            else
            {
                projectConfigurator.setConfiguration(args,
                        ICompilerSettingsConstants.FILE_SPECS_VAR);
            }

            projectConfigurator.applyToProject(project);
            project.config = (JSGoogConfiguration) projectConfigurator.getConfiguration();

            config = (JSGoogConfiguration) projectConfigurator.getConfiguration();
            configBuffer = projectConfigurator.getConfigurationBuffer();

            problems = new ProblemQuery(projectConfigurator.getCompilerProblemSettings());
            problems.addAll(projectConfigurator.getConfigurationProblems());

            if (configBuffer.getVar("version") != null) //$NON-NLS-1$
                return false;

            if (problems.hasErrors())
                return false;

            validateTargetFile();
            DefinitionBase.setPerformanceCachingEnabled(!config.getWatch());
            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 JSConfiguration();
                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();
    }
    
    public List<String> getSourceList()
    {
        ArrayList<String> list = new ArrayList<String>();
        try
        {
            ArrayList<ICompilationUnit> roots = new ArrayList<ICompilationUnit>();
            roots.add(mainCU);
            Set<ICompilationUnit> incs = target.getIncludesCompilationUnits();
            roots.addAll(incs);
            project.mixinClassNames = new TreeSet<String>();
            List<ICompilationUnit> units = project.getReachableCompilationUnitsInSWFOrder(roots);
            for (ICompilationUnit unit : units)
            {
                UnitType ut = unit.getCompilationUnitType();
                if (ut == UnitType.AS_UNIT || ut == UnitType.MXML_UNIT)
                {
                    list.add(unit.getAbsoluteFilename());
                }
            }
        }
        catch (InterruptedException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        return list;
    }
    
    public String getMainSource()
    {
        return mainCU.getAbsoluteFilename();
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



