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 2014/07/22 15:35:54 UTC

[28/51] [partial] - Migrated the directory structure to a more Maven style structure. - Started migrating the Parser from Antlr2+3 and JFlex to Antlr4.

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/59f6373b/compiler/src/main/java/org/apache/flex/compiler/config/Configuration.java
----------------------------------------------------------------------
diff --git a/compiler/src/main/java/org/apache/flex/compiler/config/Configuration.java b/compiler/src/main/java/org/apache/flex/compiler/config/Configuration.java
new file mode 100644
index 0000000..893dead
--- /dev/null
+++ b/compiler/src/main/java/org/apache/flex/compiler/config/Configuration.java
@@ -0,0 +1,5807 @@
+/*
+ *
+ *  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.config;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.text.DateFormat;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.regex.Pattern;
+
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.IOUtils;
+
+import org.apache.flex.compiler.common.IPathResolver;
+import org.apache.flex.compiler.common.VersionInfo;
+import org.apache.flex.compiler.exceptions.ConfigurationException;
+import org.apache.flex.compiler.exceptions.ConfigurationException.CannotOpen;
+import org.apache.flex.compiler.exceptions.ConfigurationException.IncorrectArgumentCount;
+import org.apache.flex.compiler.exceptions.ConfigurationException.NotAFile;
+import org.apache.flex.compiler.exceptions.ConfigurationException.NotDirectory;
+import org.apache.flex.compiler.exceptions.ConfigurationException.RedundantFile;
+import org.apache.flex.compiler.filespecs.FileSpecification;
+import org.apache.flex.compiler.filespecs.IFileSpecification;
+import org.apache.flex.compiler.internal.config.FileConfigurator;
+import org.apache.flex.compiler.internal.config.FrameInfo;
+import org.apache.flex.compiler.internal.config.LoadExternsParser;
+import org.apache.flex.compiler.internal.config.QNameNormalization;
+import org.apache.flex.compiler.internal.config.RSLArgumentNameGenerator;
+import org.apache.flex.compiler.internal.config.RuntimeSharedLibraryPathInfo;
+import org.apache.flex.compiler.internal.config.annotations.ArgumentNameGenerator;
+import org.apache.flex.compiler.internal.config.annotations.Arguments;
+import org.apache.flex.compiler.internal.config.annotations.Config;
+import org.apache.flex.compiler.internal.config.annotations.DefaultArgumentValue;
+import org.apache.flex.compiler.internal.config.annotations.DeprecatedConfig;
+import org.apache.flex.compiler.internal.config.annotations.FlexOnly;
+import org.apache.flex.compiler.internal.config.annotations.InfiniteArguments;
+import org.apache.flex.compiler.internal.config.annotations.Mapping;
+import org.apache.flex.compiler.internal.config.annotations.SoftPrerequisites;
+import org.apache.flex.compiler.internal.config.localization.LocalizationManager;
+import org.apache.flex.compiler.internal.mxml.MXMLNamespaceMapping;
+import org.apache.flex.compiler.mxml.IMXMLTypeConstants;
+import org.apache.flex.compiler.problems.ConfigurationProblem;
+import org.apache.flex.compiler.problems.DeprecatedConfigurationOptionProblem;
+import org.apache.flex.compiler.problems.FlexOnlyConfigurationOptionNotSupported;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.problems.RemovedConfigurationOptionProblem;
+import org.apache.flex.swc.catalog.XMLFormatter;
+import org.apache.flex.utils.FileUtils;
+import org.apache.flex.utils.FilenameNormalization;
+
+import com.google.common.base.Function;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+/**
+ * The model for all the configuration options supported by the compiler. Each
+ * option is stored in a private field. It usually has a getter method, a setter
+ * method and a configuration method (started with "cfg"). The configuration
+ * methods are used by the configurators to set the values of a given option
+ * name.
+ * <p>
+ * This class is currently being reviewed and refactored. See CMP-471 as the
+ * master bug for the tasks.
+ * <p>
+ * Steps to refactor:
+ * <ol>
+ * <li>Check "mxmlc" manual (http://adobe.ly/bffN8A) and copy documents to
+ * Javadoc on setters of options.</li>
+ * <li>Check "configuration support" WIKI (http://bit.ly/oAI8gj) to see if an
+ * option should be deprecated.</li>
+ * <li>Merge {@code cfgXXX} to {@code setXXX}, and annotate the setter.</li>
+ * <li>Remove {@code getXXXInfo()} static method.</li>
+ * </ol>
+ * 
+ * @see "http://bugs.adobe.com/jira/browse/CMP-471"
+ */
+public class Configuration
+{
+    private static final int DEFAULT_HEIGHT_MAX = 4096;
+    private static final int DEFAULT_HEIGHT_MIN = 1;
+    private static final int DEFAULT_WIDTH_MAX = 4096;
+    private static final int DEFAULT_WIDTH_MIN = 1;
+
+    public static final String DEFAULT_OUTPUT_DIRECTORY_TOKEN = "org.apache.flex.default.output.directory"; 
+    
+    public static final String SWC_AIRGLOBAL = "airglobal.swc";
+    
+    /**
+     * Singleton empty string list. All getters returning a list of string
+     * should return this object when the field is null.
+     */
+    private static final List<String> EMPTY_STRING_LIST = Collections.emptyList();
+
+    private static final List<String> compcOnlyOptions = new ArrayList<String>(9);
+    
+    static 
+    {
+        compcOnlyOptions.add("directory");
+        compcOnlyOptions.add("include-classes");
+        compcOnlyOptions.add("include-file");
+        compcOnlyOptions.add("include-lookup-only");
+        compcOnlyOptions.add("include-namespaces");
+        compcOnlyOptions.add("include-sources");
+        compcOnlyOptions.add("include-stylesheet");
+        compcOnlyOptions.add("include-inheritance-dependencies-only");
+    }
+    
+    /**
+     * Validate configuration options values.
+     * 
+     * @param configurationBuffer Configuration buffer.
+     * @throws ConfigurationException Error.
+     */
+    public void validate(ConfigurationBuffer configurationBuffer) throws ConfigurationException
+    {
+        // process the merged configuration buffer. right, can't just process the args.
+        processDeprecatedAndRemovedOptions(configurationBuffer);
+
+        validateDumpConfig(configurationBuffer);
+    }
+    
+    /**
+     * Validate that no compc-only options are used in a given configuration buffer.
+     * Use this method to verify no compc-only args are used in mxmlc. 
+     * 
+     * @param configurationBuffer the configuration buffer to check for compc-only options.
+     * 
+     * @throws ConfigurationException if a compc-only option is found in the configuration buffer.
+     */
+    public static void validateNoCompcOnlyOptions(ConfigurationBuffer configurationBuffer) throws ConfigurationException
+    {
+        for (String option : compcOnlyOptions)
+        {
+            List<ConfigurationValue> values = configurationBuffer.getVar(option);
+            if (values != null && values.size() > 0)
+                throw new ConfigurationException.UnknownVariable(values.get(0).getVar(), 
+                        values.get(0).getSource(), values.get(0).getLine());
+        }
+    }
+    
+    /**
+     * The path of a given file name based on the context of the configuration
+     * value or the default output directory token.
+     * 
+     * @param cv
+     * @param fileName
+     * @return the full path of the file.
+     */
+    protected String getOutputPath(ConfigurationValue cv, String fileName)
+    {
+        String result = fileName;
+
+        if (fileName != null)
+        {
+            File file = new File(fileName);
+            if (!FileUtils.isAbsolute(file))
+            {
+                String directory = cv.getBuffer().getToken(DEFAULT_OUTPUT_DIRECTORY_TOKEN);
+
+                // if no default output directory, then use the configuration context.
+                if (directory == null)
+                {
+                    directory = cv.getContext();
+                }
+
+                if (directory != null)
+                {
+                    result = FileUtils.addPathComponents(directory, fileName, File.separatorChar);
+                }
+            }
+        }
+
+        return pathResolver.resolve(result).getAbsolutePath();
+    }
+
+    private static Map<String, String> aliases = null;
+
+    public static Map<String, String> getAliases()
+    {
+        if (aliases == null)
+        {
+            aliases = new HashMap<String, String>();
+
+            aliases.put( "l", "compiler.library-path" );
+            aliases.put( "el", "compiler.external-library-path" );
+            aliases.put( "fb", "use-flashbuilder-project-files" );
+            aliases.put( "is", "include-sources");
+            aliases.put( "sp", "compiler.source-path");
+            aliases.put( "rsl", "runtime-shared-libraries");
+            aliases.put( "keep", "compiler.keep-generated-actionscript");
+	        aliases.put( "o", "output" );
+	        aliases.put("rslp", "runtime-shared-library-path");
+	        aliases.put("static-rsls", "static-link-runtime-shared-libraries");
+        }
+        return aliases;
+    }
+
+    //
+    // PathResolver
+    //
+    private IPathResolver pathResolver;
+    
+    /**
+     * Set a path resolver to resolver files relative to a
+     * configuration. Files inside of configuration files are resolved relative
+     * to those configuration files and files on the command line are resolved
+     * relative to the root directory of the compile.
+     * 
+     * @param pathResolver a path resolver for this configuration. May not be null.
+     */
+    public void setPathResolver(IPathResolver pathResolver)
+    {
+        this.pathResolver = pathResolver;
+    }
+    
+    //
+    // mainDefinition
+    //
+    private String mainDefinition;
+
+    /**
+     * Main definition is the root class of a SWF. {@code mxmlc} only takes one
+     * file in the source list. The main definition name is the main source file
+     * name.
+     * 
+     * @return main definition
+     */
+    public String getMainDefinition()
+    {
+        return mainDefinition;
+    }
+
+    public void setMainDefinition(String mainDefinition)
+    {
+        assert mainDefinition != null : "main definition can't be null";
+        assert !"".equals(mainDefinition) : "main definition can't be empty";
+
+        this.mainDefinition = mainDefinition;
+    }
+
+    //
+    // 'benchmark' option
+    //
+    @Config(removed = true)
+    @Mapping("benchmark")
+    public void setBenchmark(ConfigurationValue cv, boolean b)
+    {
+    }
+
+    //
+    // 'debug-password' option
+    //
+
+    private String debugPassword;
+
+    /**
+     * Lets you engage in remote debugging sessions with the Flash IDE.
+     */
+    public String getDebugPassword()
+    {
+        return debugPassword;
+    }
+
+    @Config(advanced = true)
+    @Mapping("debug-password")
+    @DefaultArgumentValue("")
+    public void setDebugPassword(ConfigurationValue cv, String debugPassword)
+    {
+        this.debugPassword = debugPassword;
+    }
+
+    //
+    // 'default-background-color' option
+    //
+
+    private int backgroundColor = 0x50727E;
+
+    public int getDefaultBackgroundColor()
+    {
+        return this.backgroundColor;
+    }
+
+    @Config(advanced = true)
+    @Mapping("default-background-color")
+    public void setDefaultBackgroundColor(ConfigurationValue cv, int backgroundColor)
+    {
+        this.backgroundColor = backgroundColor;
+    }
+
+    //
+    // 'default-frame-rate' option
+    //
+
+    private int frameRate = 24;
+
+    public int getDefaultFrameRate()
+    {
+        return frameRate;
+    }
+
+    @Config(advanced = true)
+    @Mapping("default-frame-rate")
+    public void setDefaultFrameRate(ConfigurationValue cv, int rate)
+            throws ConfigurationException
+    {
+        if (rate <= 0)
+            throw new ConfigurationException.GreaterThanZero(cv.getVar(),
+                                              cv.getSource(), cv.getLine());
+        frameRate = rate;
+    }
+
+    //
+    // 'default-script-limits' option
+    //
+
+    private int scriptLimit = 60;
+    private int scriptRecursionLimit = 1000;
+    private boolean scriptLimitsSet = false;
+
+    public int getScriptTimeLimit()
+    {
+        return scriptLimit;
+    }
+
+    public int getScriptRecursionLimit()
+    {
+        return scriptRecursionLimit;
+    }
+
+    public boolean scriptLimitsSet()
+    {
+        return scriptLimitsSet;
+    }
+
+    @Config(advanced = true)
+    @Mapping("default-script-limits")
+    @Arguments({"max-recursion-depth", "max-execution-time"})
+    public void setDefaultScriptLimits(ConfigurationValue cv, int scriptLimit, int scriptRecursionLimit)
+            throws ConfigurationException
+    {
+        if (scriptLimit <= 0)
+            throw new ConfigurationException.GreaterThanZero(cv.getVar(), cv.getSource(), cv.getLine());
+
+        if (scriptRecursionLimit <= 0)
+            throw new ConfigurationException.GreaterThanZero(cv.getVar(),
+                                              cv.getSource(), cv.getLine());
+
+        this.scriptLimitsSet = true;
+        this.scriptLimit = scriptRecursionLimit;
+        this.scriptRecursionLimit = scriptLimit;
+    }
+
+    //
+    // 'default-size' option
+    //
+
+    private int defaultWidth = 500;
+    private int defaultHeight = 375;
+
+    public int getDefaultWidth()
+    {
+        return defaultWidth;
+    }
+
+    public int getDefaultHeight()
+    {
+        return defaultHeight;
+    }
+
+    @Config(advanced = true)
+    @Arguments({"width", "height"})
+    @Mapping("default-size")
+    public void setDefaultSize(ConfigurationValue cv, int width, int height)
+            throws ConfigurationException
+    {
+        if (width < DEFAULT_WIDTH_MIN || width > DEFAULT_WIDTH_MAX ||
+            height < DEFAULT_HEIGHT_MIN || height > DEFAULT_HEIGHT_MAX)
+            throw new ConfigurationException.IllegalDimensions(width, height, cv.getVar(), cv.getSource(), cv.getLine());
+
+        this.defaultWidth = width;
+        this.defaultHeight = height;
+    }
+
+    //
+    // 'externs' option
+    //
+
+    private final Set<String> externs = new LinkedHashSet<String>();
+
+    public Set<String> getExterns()
+    {
+        return externs;
+    }
+
+    /**
+     * Sets a list of classes to exclude from linking when compiling a SWF file.
+     * This option provides compile-time link checking for external references
+     * that are dynamically linked.
+     */
+    @Config(advanced = true, allowMultiple = true)
+    @Mapping("externs")
+    @Arguments("symbol")
+    @InfiniteArguments
+    public void setExterns(ConfigurationValue cfgval, List<String> vals)
+    {
+        externs.addAll(QNameNormalization.normalize(vals));
+    }
+
+    //
+    // 'includes' option
+    //
+
+    private final Set<String> includes = new LinkedHashSet<String>();
+
+    public Set<String> getIncludes()
+    {
+        return includes;
+    }
+
+    /**
+     * Links one or more classes to the resulting application SWF file, whether
+     * or not those classes are required at compile time. To link an entire SWC
+     * file rather than individual classes, use the include-libraries option.
+     */
+    @Config(allowMultiple = true, advanced = true)
+    @Mapping("includes")
+    @Arguments("symbol")
+    @InfiniteArguments
+    public void setIncludes(ConfigurationValue cfgval, List<String> vals)
+    {
+        includes.addAll(QNameNormalization.normalize(vals));
+    }
+
+    //
+    // 'framework' option
+    //
+    //
+    @Config(allowMultiple = true, advanced = true, removed = true)
+    @Mapping("framework")
+    public void setFramework(ConfigurationValue cfgval, String value)
+    {
+    }
+    
+    // 'link-report' option
+    //
+
+    private String linkReportFileName = null;
+
+    public File getLinkReport()
+    {
+        return linkReportFileName != null ? new File(linkReportFileName) : null;
+    }
+
+    /**
+     * Prints linking information to the specified output file. This file is an
+     * XML file that contains {@code def} tags, {@code pre} tags and {@code ext}
+     * tags showing linker dependencies in the final SWF file. The file format
+     * output by this command can be used to write a file for input to the
+     * {@code load-externs} option.
+     */
+    @Config(advanced = true)
+    @Mapping("link-report")
+    @Arguments("filename")
+    public void setLinkReport(ConfigurationValue cv, String filename)
+    {
+        this.linkReportFileName = getOutputPath(cv, filename);
+    }
+
+    //
+    // 'size-report' option
+    //
+
+    private String sizeReportFileName = null;
+
+    public File getSizeReport()
+    {
+        return sizeReportFileName != null ? new File(sizeReportFileName) : null;
+    }
+
+    @Config(advanced = true)
+    @Mapping("size-report")
+    @Arguments("filename")
+    public void setSizeReport(ConfigurationValue cv, String filename)
+    {
+        this.sizeReportFileName = getOutputPath(cv, filename);
+    }
+
+    //
+    // 'load-externs' option
+    //
+
+    /**
+     * Specifies the location of an XML file that contains def, pre, and ext
+     * symbols to omit from linking when compiling a SWF file. The XML file uses
+     * the same syntax as the one produced by the link-report option.
+     * <p>
+     * This option provides compile-time link checking for external components
+     * that are dynamically linked.
+     */
+    @Config(allowMultiple = true, advanced = true)
+    @Mapping("load-externs")
+    @Arguments("filename")
+    public void setLoadExterns(ConfigurationValue cfgval, String filename) throws ConfigurationException
+    {
+        final String path = resolvePathStrict(filename, cfgval);
+        final FileSpecification f = new FileSpecification(path);
+        final List<String> externsFromFile = LoadExternsParser.collectExterns(cfgval, f);
+        externs.addAll(externsFromFile);
+    }
+
+    //
+    // 'raw-metadata' option
+    //
+
+    private String metadata = null;
+
+    public String getRawMetadata()
+    {
+        if (metadata != null)
+            return metadata;
+
+        return generateMetadata();
+    }
+
+    private static final String RDF_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+    private static final String DC_URI = "http://purl.org/dc/elements/1.1";
+    
+    /**
+     * @return Metadata XML string.
+     */
+    private final String generateMetadata()
+    {
+        final XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance();
+        assert xmlOutputFactory != null : "Expect XMLOutputFactory implementation.";
+        final StringWriter stringWriter = new StringWriter();
+        XMLStreamWriter xmlWriter = null;
+        
+        try
+        {
+            xmlWriter = new XMLFormatter(
+                    xmlOutputFactory.createXMLStreamWriter(stringWriter));
+            xmlWriter.writeStartDocument();
+            
+            xmlWriter.writeStartElement("rdf", "RDF", RDF_URI);
+            xmlWriter.setPrefix("rdf", RDF_URI);
+            xmlWriter.writeNamespace("rdf", RDF_URI);
+            
+            // write rdf:Description
+            xmlWriter.writeStartElement(RDF_URI, "Description");
+            xmlWriter.setPrefix("dc", DC_URI);
+            xmlWriter.setPrefix(VersionInfo.COMPILER_NAMESPACE_PREFIX, 
+                    VersionInfo.COMPILER_NAMESPACE_URI);
+            xmlWriter.writeNamespace("dc", DC_URI);
+            xmlWriter.writeNamespace(VersionInfo.COMPILER_NAMESPACE_PREFIX, 
+                    VersionInfo.COMPILER_NAMESPACE_URI);
+            
+            // write dc:format
+            xmlWriter.writeStartElement(DC_URI, "format");
+            xmlWriter.writeCharacters("application/x-shockwave-flash");
+            xmlWriter.writeEndElement();
+            
+            if (isFlex())
+            {
+                // write localizedTitles
+                writeMap(xmlWriter, DC_URI, "description", localizedDescriptions);
+            
+                // write localizedDescription
+                writeMap(xmlWriter, DC_URI, "title", localizedTitles);
+
+                // write publisher
+                writeCollection(xmlWriter, DC_URI, "publisher", publishers);
+                
+                // write creators
+                writeCollection(xmlWriter, DC_URI, "creator", creators);
+                
+                // write contributor
+                writeCollection(xmlWriter, DC_URI, "contributor", contributors);
+                
+                // write language
+                writeCollection(xmlWriter, DC_URI, "language", langs);
+                
+                // write date
+                writeDate(xmlWriter);
+            }
+            
+            // write compiledBy
+            writeCompiledBy(xmlWriter);
+            
+            // write
+            xmlWriter.writeEndElement(); // Description
+            xmlWriter.writeEndDocument();
+        }
+        catch (XMLStreamException e)
+        {
+            return "";
+        }
+        
+        return stringWriter.toString();
+    }
+
+    /**
+     * Write information about the compiler that compiled the swf.
+     * 
+     * @param writer
+     * @throws XMLStreamException
+     */
+    private void writeCompiledBy(XMLStreamWriter writer) throws XMLStreamException
+    {
+        writer.writeEmptyElement(VersionInfo.COMPILER_NAMESPACE_URI, VersionInfo.COMPILER_ELEMENT);
+        writer.writeAttribute(VersionInfo.COMPILER_NAME_ATTRIBUTE, VersionInfo.getCompilerName());
+        writer.writeAttribute(VersionInfo.COMPILER_VERSION_ATTRIBUTE, VersionInfo.getCompilerVersion());
+        writer.writeAttribute(VersionInfo.COMPILER_BUILD_ATTRIBUTE, VersionInfo.getCompilerBuild());
+
+        writer.writeEndElement(); // compiledBy
+    }
+
+    /**
+     * Write the data to rdf/xml
+     * 
+     * @param writer
+     * @throws XMLStreamException
+     */
+    private void writeDate(XMLStreamWriter writer) throws XMLStreamException
+    {
+        if (date == null)
+        {
+            date = DateFormat.getDateInstance().format(new Date());
+        }
+        
+        writer.writeStartElement(DC_URI, "date");
+        writer.writeCharacters(date);
+        writer.writeEndElement();
+    }
+
+    /**
+     * Write a map of values to rdf/xml
+     * 
+     * @param writer
+     * @param namespaceURI
+     * @param localName
+     * @param mapData
+     * @throws XMLStreamException
+     */
+    private void writeMap(XMLStreamWriter writer, String namespaceURI,
+            String localName, Map<String, String> mapData) throws XMLStreamException
+    {
+        if (mapData.size() > 0)
+        {
+            writer.writeStartElement(namespaceURI, localName);
+            if ((mapData.size() == 1) && (mapData.get("x-default") != null))
+            {
+                String data = mapData.get("x-default");
+                writer.writeCharacters(data);
+            }
+            else
+            {
+                writer.writeStartElement(RDF_URI, "Alt");
+                for (final String key : mapData.keySet())
+                {
+                    final String value = mapData.get(key);
+                    writer.writeStartElement(RDF_URI, "li");
+                    writer.writeAttribute("xml", "", "lang", key);
+                    writer.writeCharacters(value);
+                    writer.writeEndElement();
+                }
+                writer.writeEndElement();
+            }
+
+            writer.writeEndElement();
+        }
+
+    }
+
+    /**
+     * Write a collection values to rdf/xml.
+     * 
+     * @param writer
+     * @param namespaceURI
+     * @param localName
+     * @param values
+     * @throws XMLStreamException
+     */
+    private void writeCollection(XMLStreamWriter writer, String namespaceURI,
+            String localName, Collection<String> values) throws XMLStreamException
+    {
+        if (values.isEmpty())
+            return;
+        
+        writer.writeStartElement(namespaceURI, localName);
+        
+        if (values.size() > 1)
+            writer.writeStartElement(RDF_URI, "Bag");
+        
+        for (String value : values)
+        {
+            writer.writeCharacters(value);
+        }
+
+        if (values.size() > 1)
+            writer.writeEndElement();
+
+        writer.writeEndElement();
+        
+    }
+
+    /**
+     * Defines the metadata for the resulting SWF file. The value of this option
+     * overrides any metadata-related compiler options such as contributor,
+     * creator, date, and description.
+     */
+    @Config(advanced = true)
+    @Mapping("raw-metadata")
+    @Arguments("text")
+    public void setRawMetadata(ConfigurationValue cv, String xml) throws ConfigurationException
+    {
+        if (metadata != null)
+        {
+            throw new ConfigurationException.BadMetadataCombo(cv.getVar(), cv.getSource(), cv.getLine());
+        }
+
+        this.metadata = xml;
+    }
+
+    //
+    // 'resource-bundle-list' option
+    //
+
+    private String rbListFileName = null;
+
+    public String getResourceBundleList()
+    {
+        return rbListFileName;
+    }
+    
+    
+    //
+    // 'include-resource-bundles' option
+    //
+    
+    /**
+     * include-resource-bundles [...]
+     */
+    private List<String> includeResourceBundles = new ArrayList<String>();
+
+    /**
+     * @return a list of resource bundles to include in the swc
+     */
+    public List<String> getIncludeResourceBundles()
+    {
+        return includeResourceBundles;
+    }
+    
+    /**
+     * Sets the resource bundles that should be included in this SWC or SWF. This list 
+     * can have locale independent qualified name for property files 
+     * (with the name not including the suffix) or qualified name for classes that 
+     * extend ResourceBundle. 
+     * <p>
+     * Qualified name of a properties file is determined by its relative path to its 
+     * parent source folder. Such as:
+     * <p>
+     * Source path: locale/{locale}
+     * <p>
+     * Path of properties file 1: locale/en_US/A.properties
+     * Qualified name of properties file 1: A
+     * <p>
+     * Path of properties file 2: locale/en_US/com/resources/B.properties
+     * Qualified name of properties file 1: com.resources.B 
+     * <p>
+     * Note: Source folders of all the properties files passed using this argument 
+     * should be in the project's source path list.
+     * 
+     * @param cv configuration value objects
+     * @param values list of resource bundles to include in the swc or swf
+     */
+    @Config(allowMultiple = true)
+    @Mapping("include-resource-bundles")
+    @Arguments("bundle")
+    @FlexOnly
+    public void setIncludeResourceBundles(ConfigurationValue cv, List<String> values)
+    {
+        includeResourceBundles.addAll(values);
+    }
+
+    /**
+     * Prints a list of resource bundles that are used by the current
+     * application to a file named with the filename argument. You then use this
+     * list as input that you specify with the include-resource-bundles option
+     * to create a resource module.
+     */
+    @Config(advanced = true)
+    @Mapping("resource-bundle-list")
+    @Arguments("filename")
+    @FlexOnly
+    public void setResourceBundleList(ConfigurationValue cv, String filename)
+    {
+        this.rbListFileName = getOutputPath(cv, filename);
+    }
+
+    //
+    // 'runtime-shared-libraries' option
+    //
+
+    private List<String> rslList = new LinkedList<String>();
+    
+    public List<String> getRuntimeSharedLibraries()
+    {
+        return rslList;
+    }
+
+    /**
+     * Specifies a list of runtime shared libraries (RSLs) to use for this
+     * application. RSLs are dynamically-linked at run time. The compiler
+     * externalizes the contents of the application that you are compiling that
+     * overlap with the RSL.
+     * <p>
+     * You specify the location of the SWF file relative to the deployment
+     * location of the application. For example, if you store a file named
+     * library.swf file in the web_root/libraries directory on the web server,
+     * and the application in the web root, you specify libraries/library.swf.
+     */
+    @Config(allowMultiple = true)
+    @Mapping("runtime-shared-libraries")
+    @Arguments("url")
+    @InfiniteArguments
+    @FlexOnly
+    public void setRuntimeSharedLibraries(ConfigurationValue cfgval, List<String> urls) throws ConfigurationException
+    {
+        rslList.addAll(urls);
+    }
+
+    //
+    // 'use-network' option
+    //
+
+    private boolean useNetwork = true;
+
+    public boolean getUseNetwork()
+    {
+        return useNetwork;
+    }
+
+    /**
+     * Specifies that the current application uses network services.
+     * <p>
+     * The default value is true.
+     * <p>
+     * When the use-network property is set to false, the application can access
+     * the local filesystem (for example, use the XML.load() method with file:
+     * URLs) but not network services. In most circumstances, the value of this
+     * property should be true.
+     */
+    @Config
+    @Mapping("use-network")
+    public void setUseNetwork(ConfigurationValue cv, boolean b)
+    {
+        this.useNetwork = b;
+    }
+
+    //
+    // runtime-shared-library-path
+    //
+
+    private List<RuntimeSharedLibraryPathInfo> rslPathInfoList;
+
+    /**
+     * @return List of of all the -runtime-shared-libraries-path options.
+     * Each-runtime-shared-libraries-path option supplied results in a
+     * RslPathInfo object. Each object in the list is of type RslPathInfo.
+     * <p>
+     * The list will be empty if -static-link-runtime-shared-libraries=true.
+     * <p>
+     * TODO Verify if this is still true and make the code do what it says.
+     */
+    public List<RuntimeSharedLibraryPathInfo> getRslPathInfo()
+    {
+        if (rslPathInfoList == null)
+            return Collections.emptyList();
+        else
+            return rslPathInfoList;
+    }
+
+    public List<File> getRslExcludedLibraries()
+    {
+        if (rslPathInfoList == null || getStaticLinkRsl())
+            return Collections.emptyList();
+
+        return Lists.transform(
+                rslPathInfoList,
+                new Function<RuntimeSharedLibraryPathInfo, File>()
+                {
+                    @Override
+                    public File apply(RuntimeSharedLibraryPathInfo info)
+                    {
+                        return info.getSWCFile();
+                    }
+                });
+    }
+
+    /**
+     * Specifies the location of a runtime shared library (RSL). The compiler
+     * externalizes the contents of the application that you are compiling that
+     * overlap with the RSL.
+     * <p>
+     * The path-element argument is the location of the SWC file or open
+     * directory to compile against. For example,
+     * c:\flexsdk\frameworks\libs\framework.swc. This is the equivalent of the
+     * using the external-library-path option when compiling against an RSL
+     * using the runtime-shared-libraries option.
+     * <p>
+     * The rsl-url argument is the URL of the RSL that will be used to load the
+     * RSL at runtime. The compiler does not verify the existence of the SWF
+     * file at this location at compile time. It does store this string in the
+     * application, however, and uses it at run time. As a result, the SWF file
+     * must be available at run time but necessarily not at compile time.
+     * <p>
+     * The policy-file-url is the location of the crossdomain.xml file that
+     * gives permission to read the RSL from the server. This might be necessary
+     * because the RSL can be on a separate server as the application. For
+     * example, http://www.mydomain.com/rsls/crossdomain.xml.
+     * <p>
+     * The failover-url and second policy-file-url arguments specify the
+     * location of the secondary RSL and crossdomain.xml file if the first RSL
+     * cannot be loaded. This most commonly happens when the client Player
+     * version does not support cross-domain RSLs. You can add any number of
+     * failover RSLs, but must include a policy file URL for each one.
+     * <p>
+     * Do not include spaces between the comma-separated values. The following
+     * example shows how to use this option:
+     * 
+     * <pre>
+     * mxmlc -o=../lib/app.swf -runtime-shared-library-path=../lib/mylib.swc,../bin/myrsl.swf Main.mxml
+     * </pre>
+     * 
+     * You can specify more than one library file to be used as an RSL. You do
+     * this by adding additional runtime-shared-library-path options.
+     * <p>
+     * You can also use the runtime-shared-libraries command to use RSLs with
+     * your applications. However, the runtime-shared-library-path option lets
+     * you also specify the location of the policy file and failover RSL.
+     * <p>
+     */
+    // NOTE: if the annotations are modified, then also modify the annotations
+    // in COMPCConfiguration.
+    @Config(allowMultiple = true)
+    @Mapping({"runtime-shared-library-path"})
+    @SoftPrerequisites({"static-link-runtime-shared-libraries"})
+    @ArgumentNameGenerator(RSLArgumentNameGenerator.class)
+    @InfiniteArguments
+    @FlexOnly
+    public void setRuntimeSharedLibraryPath(
+            ConfigurationValue cfgval,
+            List<String> urls) throws ConfigurationException
+    {
+
+        if (urls.isEmpty())
+            return;
+
+        // Usage rule: if you use -rslp on the command line
+        // it will take effect unless you also specify -static-rsls=true on the command line.
+        if (CommandLineConfigurator.SOURCE_COMMAND_LINE.equals(cfgval.getSource()))
+        {
+            setOverrideStaticLinkRsl(false);
+        }
+
+        // ignore rsl if told to
+        if (getStaticLinkRsl())
+        {
+            return;
+        }
+
+        if (urls.size() < 2)
+        {
+            // insufficent arguments
+            throw new ConfigurationException.MissingArgument("rsl-url",
+            "runtime-shared-library-path", cfgval.getSource(),
+            cfgval.getLine());
+        }
+
+        RuntimeSharedLibraryPathInfo info = new RuntimeSharedLibraryPathInfo();
+
+        // validate the first argument, the swc or open directory, required.
+        String include = resolvePathStrict(urls.get(0), cfgval, true);
+        info.setSWCPath(urls.get(0));
+        info.setSWCFile(new File(include));
+
+        // the rest of the args are: rsl-url, policy-file-url, rsl-url, policy-file-url,... 
+        for (int i = 1; i < urls.size(); ++i)
+        {
+            final String url = urls.get(i);
+            if ((i + 1) % 2 == 0)
+            {
+                if ("".equals(url.length()))
+                {
+                    // rsl urls is required
+                    throw new ConfigurationException.MissingArgument("rsl-url",
+                    "runtime-shared-library-path", cfgval.getSource(),
+                    cfgval.getLine());
+                }
+                info.addRSLURL(url);
+            }
+            else
+            {
+                info.addPolicyFileURL(url);
+            }
+        }
+
+        // if the last policy file was not specified, then add an empty one so
+        // there are always the same number of rsls and policy files.
+        if ((urls.size() % 2) == 0)
+        {
+            info.addPolicyFileURL("");
+        }
+
+        // take local variables and add to overall arguments.
+        if (rslPathInfoList == null)
+        {
+            rslPathInfoList = new ArrayList<RuntimeSharedLibraryPathInfo>();
+        }
+
+        rslPathInfoList.add(info);
+    }
+
+    //
+    // 'static-link-runtime-shared-libraries' option
+    // 
+
+    private boolean staticLinkRsl = true;
+    private String staticLinkRslSource;
+
+    /**
+     * @return true if -cd-rsl option should be used. False otherwise.
+     */
+    public boolean getStaticLinkRsl()
+    {
+        return staticLinkRsl;
+    }
+
+    /**
+     * Allow another option, namely -rslp to override the value of static-rsls.
+     * But you can not override a -static-rsls option that came from the command
+     * line.
+     * 
+     * @param staticLinkRsl
+     */
+    protected void setOverrideStaticLinkRsl(boolean staticLinkRsl)
+    {
+        if (CommandLineConfigurator.SOURCE_COMMAND_LINE.equals(staticLinkRslSource))
+        {
+            return;
+        }
+
+        this.staticLinkRsl = staticLinkRsl;
+    }
+
+    /**
+     * Determines whether to compile against libraries statically or use RSLs.
+     * Set this option to true to ignore the RSLs specified by the
+     * runtime-shared-library-path option. Set this option to false to use the
+     * RSLs.
+     * <p>
+     * This option is useful so that you can quickly switch between a statically
+     * and dynamically linked application without having to change the
+     * runtime-shared-library-path option, which can be verbose, or edit the
+     * configuration files.
+     */
+    @Config
+    @Mapping("static-link-runtime-shared-libraries")
+    @FlexOnly
+    public void setStaticLinkRuntimeSharedLibraries(ConfigurationValue cv, boolean b)
+    {
+        staticLinkRsl = b;
+        staticLinkRslSource = cv.getSource();
+    }
+
+    //
+    // 'use-flashbuilder-project-files' option
+    //
+    private Boolean useFlashBuilderProjectFiles = false;
+    
+    public Boolean getUseFlashBuilderProjectFiles()
+    {
+        return useFlashBuilderProjectFiles;
+    }
+
+    @Config
+    @Mapping({"use-flashbuilder-project-files"})
+    @FlexOnly
+    public void setUseFlashBuilderProjectFiles(ConfigurationValue cv, Boolean useFiles) throws ConfigurationException
+    {
+        useFlashBuilderProjectFiles = useFiles;
+    }
+
+    //
+    // 'verify-digests' options
+    // 
+
+    private boolean verifyDigests = true;
+
+    /**
+     * @return true if digest information associated with the -cd-rsl option is
+     * used by the application at runtime. False otherwise.
+     */
+    public boolean getVerifyDigests()
+    {
+        return verifyDigests;
+    }
+
+    /**
+     * Instructs the application to check the digest of the RSL SWF file against
+     * the digest that was compiled into the application at compile time. This
+     * is a security measure that lets you load RSLs from remote domains or
+     * different sub-domains. It also lets you enforce versioning of your RSLs
+     * by forcing an application's digest to match the RSL's digest. If the
+     * digests are out of sync, you must recompile your application or load a
+     * different RSL SWF file.
+     */
+    @Config(advanced = true)
+    @FlexOnly
+    public void setVerifyDigests(ConfigurationValue cv, boolean b)
+    {
+        verifyDigests = b;
+    }
+
+    //
+    // 'remove-unused-rsls' option
+    // 
+
+    private boolean removeUnusedRSLs = false;
+
+    /**
+     * @return true if the user wants to remove unused RSLs. Otherwise false.
+     */
+    public boolean getRemoveUnusedRsls()
+    {
+        return removeUnusedRSLs;
+    }
+
+    @Config(advanced = true)
+    @FlexOnly
+    public void setRemoveUnusedRsls(ConfigurationValue cv, boolean b)
+    {
+        removeUnusedRSLs = b;
+    }
+
+    //
+    // '-include-inheritance-dependencies-only' option
+    // 
+
+    private boolean includeInheritanceDependenciesOnly = false;
+
+    /**
+     * @return true if the user want to include inheritance dependencies only.
+     */
+    public boolean getIncludeInheritanceDependenciesOnly()
+    {
+        return includeInheritanceDependenciesOnly;
+    }
+
+    @Config(advanced = true)
+    public void setIncludeInheritanceDependenciesOnly(ConfigurationValue cv, boolean b)
+    {
+        includeInheritanceDependenciesOnly = b;
+    }
+
+    //
+    // 'target-player' option
+    // 
+
+    // targeted player version (also set in DefaultsConfigurator)
+    private int majorVersionTarget = 11;
+    private int minorVersionTarget = 1;
+    private int revisionTarget = 0;
+    
+    /**
+     * The major part the earliest player version that this compiler can target.
+     * The code generator generates bytecode which will not pass
+     * verification on players earlier than 10.1.
+     */
+    public static final int TARGET_PLAYER_MAJOR_VERSION_MIN = 10;
+
+    /**
+     * The minor part the earliest player version that this compiler can target.
+     * The code generator generates bytecode which will not pass
+     * verification on players earlier than 10.1.
+     */
+    public static final int TARGET_PLAYER_MINOR_VERSION_MIN = 1;
+   
+    /**
+     * @return The major version of the player targeted by this application. The
+     * returned value will be greater to or equal to 9.
+     */
+    public int getTargetPlayerMajorVersion()
+    {
+        return majorVersionTarget;
+    }
+
+    /**
+     * @return The minor version of the player targeted by this application. The
+     * returned value will be greater to or equal to 0.
+     */
+    public int getTargetPlayerMinorVersion()
+    {
+        return minorVersionTarget;
+    }
+
+    /**
+     * @return The revision of the player targeted by this application. The
+     * returned value will be greater to or equal to 0.
+     */
+    public int getTargetPlayerRevision()
+    {
+        return revisionTarget;
+    }
+
+    /**
+     * Specifies the version of Flash Player that you want to target with the
+     * application. Features requiring a later version of Flash Player are not
+     * compiled into the application.
+     * <p>
+     * The player_version parameter has the following format:<br>
+     * <code>major_version.minor_version.revision</code>
+     * <p>
+     * The major_version is required while minor_version and revision are
+     * optional. The minimum value is 10.0.0. If you do not specify the
+     * minor_version or revision, then the compiler uses zeros.
+     * <p>
+     * The value of major_version is also used by the {targetPlayerMajorVersion}
+     * token in the flex-config.xml file. This token can be used in any
+     * <path-element> element.
+     * <p>
+     * If you do not explicitly set the value of this option, the compiler uses
+     * the default from the flex-config.xml file. The value in flex-config.xml
+     * is the version of Flash Player that shipped with the SDK.
+     * <p>
+     * This option is useful if your application's audience has a specific
+     * player and cannot upgrade. You can use this to "downgrade" your
+     * application for that audience.
+     */
+    @Config
+    @Arguments("version")
+    public void setTargetPlayer(ConfigurationValue cv, String version)
+            throws ConfigurationException
+    {
+        if (version == null || version.equals(""))
+            return;
+
+        final String[] results = Iterables.toArray(
+                Splitter.on(".").omitEmptyStrings().trimResults().split(version),
+                String.class);
+
+        // major.minor.revision
+        // major is required, minor and revision are optional
+        if (results.length < 1 || results.length > 3)
+            throw new ConfigurationException.BadVersion(version, "target-player");
+
+        final String majorVersion = results[0];
+
+        final String minorVersion;
+        if (results.length > 1)
+            minorVersion = results[1];
+        else
+            minorVersion = "0";
+
+        final String revision;
+        if (results.length > 2)
+            revision = results[2];
+        else
+            revision = "0";
+
+        try
+        {
+            majorVersionTarget = Integer.parseInt(majorVersion);
+            minorVersionTarget = Integer.parseInt(minorVersion);
+            revisionTarget = Integer.parseInt(revision);
+        }
+        catch (NumberFormatException e)
+        {
+            throw new ConfigurationException.BadVersion(version, "target-player");
+        }
+
+        if (majorVersionTarget < TARGET_PLAYER_MAJOR_VERSION_MIN ||
+            majorVersionTarget == TARGET_PLAYER_MAJOR_VERSION_MIN &&
+            minorVersionTarget < TARGET_PLAYER_MINOR_VERSION_MIN)
+        {
+            throw new ConfigurationException.BadVersion(version, "target-player");
+        }
+    }
+
+    //
+    // 'swf-version' option
+    //
+
+    // swf version 13 is what shipped with player 11, and is the min version for
+    // LZMA compression
+    private static final Map<String,Integer> targetPlayerToSWFVersionMap = getSwfVersionMap();
+    
+    private static Map<String,Integer> getSwfVersionMap()
+    {
+        // Player 9 and below are not supported.
+        // 10.0 -> 10
+        // 10.1 -> 10
+        // 10.2 -> 11
+        // 10.3 -> 12
+        // 11.0 -> 13
+        // 11.1 -> 14
+        // 11.2 -> 15
+        // 11.3 -> 16
+        // 11.4 -> 17 
+        // 11.5 -> 18
+        // 11.6 -> 19
+        // 11.7 -> 20
+        // 11.8 -> 21
+        // 11.9 -> 22
+        
+        Map<String, Integer> map  = new HashMap<String, Integer>(10);
+        
+        map.put("10.0", 10);
+        map.put("10.1", 10);
+        map.put("10.2", 11);
+        map.put("10.3", 12);
+        map.put("11.0", 13);
+        map.put("11.1", 14);
+        map.put("11.2", 15);
+        map.put("11.3", 16);
+        map.put("11.4", 17);
+        map.put("11.5", 18);
+        map.put("11.6", 19);
+        map.put("11.7", 20);
+        map.put("11.8", 21);
+        map.put("11.9", 22);
+    
+        return map;
+    }
+    
+    private int lookupSwfVersion()
+    {
+        int swfVersion = DEFAULT_SWF_VERSION;
+        Integer lookupVersion = targetPlayerToSWFVersionMap.get(
+                Integer.toString(getTargetPlayerMajorVersion()) + "." + 
+                Integer.toString(getTargetPlayerMinorVersion()));
+        if (lookupVersion != null)
+            swfVersion = lookupVersion;
+        
+        return swfVersion;
+    }
+    
+    private final int UNSET_SWF_VERSION = -1;
+    private final int DEFAULT_SWF_VERSION = 14; // matches default target-player
+    private final int MINIMUM_SWF_VERSION = 10; // matches minimum target-player
+    
+    private int swfVersion = UNSET_SWF_VERSION;
+
+    public int getSwfVersion()
+    {
+        if (swfVersion == UNSET_SWF_VERSION)
+            swfVersion = lookupSwfVersion();
+        return swfVersion;
+    }
+
+    @Config
+    @Mapping("swf-version")
+    public void setSwfVersion(ConfigurationValue cv, int version) 
+        throws ConfigurationException
+    {
+        if (version < MINIMUM_SWF_VERSION)
+            throw new ConfigurationException.BadVersion(Integer.toString(version), "swf-version");
+        
+        swfVersion = version;
+    }
+
+    //
+    // 'use-direct-blit' option
+    //
+
+    private boolean useDirectBlit = true;
+
+    public boolean getUseDirectBlit()
+    {
+        return useDirectBlit;
+    }
+
+    @Config
+    public void setUseDirectBlit(ConfigurationValue cv, boolean value)
+    {
+        useDirectBlit = value;
+    }
+
+    //
+    // 'use-gpu' option
+    //
+
+    private boolean useGpu = true;
+
+    public boolean getUseGpu()
+    {
+        return useGpu;
+    }
+
+    @Config
+    public void setUseGpu(ConfigurationValue cv, boolean value)
+    {
+        useGpu = value;
+    }
+
+    //
+    // 'tools-locale' options
+    // 
+    
+    private Locale toolsLocale = null;
+    
+    /**
+     * @return locale to use when reporting compile time errors, or 
+     * <code>null</code> if not specified. In that case, system's 
+     * locale is used.
+     */
+    public Locale getToolsLocale()
+    {
+        return toolsLocale;
+    }
+            
+    /**
+     * Configures the LocalizationManager's locale, which is used when reporting
+     * compile time errors, warnings, and info.
+     * 
+     * @param toolsLocale A locale in Java format. For example, "en" or "ja_JP".
+     * @throws ConfigurationException When the specified toolsLocale is not
+     * available a ToolsLocaleNotAvailable error is reported.
+     */
+    @Config
+    @Mapping("tools-locale")
+    public void setToolsLocale(ConfigurationValue cv, String toolsLocale)
+            throws ConfigurationException
+    {
+        Locale[] locales = Locale.getAvailableLocales();
+
+        for (int i = 0; i < locales.length; i++)
+        {
+            if (locales[i].toString().equals(toolsLocale))
+            {
+                this.toolsLocale = locales[i];
+
+                LocalizationManager.get().setLocale(locales[i]);
+                return;
+            }
+        }
+
+        throw new ConfigurationException.ToolsLocaleNotAvailable(cv.getVar(),
+                                                                 cv.getSource(),
+                                                                 cv.getLine());
+    }
+
+    //
+    // 'compiler.accessible' option
+    //
+
+    private boolean accessible = false;
+
+    public boolean getCompilerAccessible()
+    {
+        return accessible;
+    }
+
+    /**
+     * Enables accessibility features when compiling the application or SWC
+     * file.
+     */
+    @Config
+    @Mapping({"compiler", "accessible"})
+    @FlexOnly
+    public void setCompilerAccessible(ConfigurationValue cv, boolean accessible)
+    {
+        this.accessible = accessible;
+    }
+
+    //
+    // 'compiler.actionscript-file-encoding' option
+    //
+
+    private String actionscriptFileEncoding = null;
+
+    public String getCompilerActionscriptFileEncoding()
+    {
+        return actionscriptFileEncoding;
+    }
+
+    /**
+     * Sets the file encoding for ActionScript files.
+     */
+    @Config
+    @Mapping({"compiler", "actionscript-file-encoding"})
+    public void setCompilerActionscriptFileEncoding(ConfigurationValue cv, String encoding)
+    {
+        actionscriptFileEncoding = encoding;
+    }
+
+    //
+    // 'compiler.adjust-opdebugline' option (hidden)
+    //
+
+    private boolean adjustOpDebugLine = true;
+
+    public boolean getAdjustOpDebugLine()
+    {
+        return adjustOpDebugLine;
+    }
+
+    /**
+     * For internal use only. Set it to false so that debugging mxmlc
+     * auto-generated code is easier.
+     */
+    @Config(advanced = true, hidden = true)
+    public void setCompilerAdjustOpdebugline(ConfigurationValue cv, boolean b)
+    {
+        adjustOpDebugLine = b;
+    }
+
+    //
+    // 'compiler.allow-source-path-overlap' option
+    //
+
+    private boolean allowSourcePathOverlap = false;
+
+    public boolean getAllowSourcePathOverlap()
+    {
+        return allowSourcePathOverlap;
+    }
+
+    /**
+     * Checks if a source-path entry is a sub-directory of another source-path
+     * entry. It helps make the package names of MXML components unambiguous.
+     */
+    @Config(advanced = true)
+    public void setCompilerAllowSourcePathOverlap(ConfigurationValue cv, boolean b)
+    {
+        allowSourcePathOverlap = b;
+    }
+
+    //
+    // 'compiler.binding-value-change-event' option
+    //
+
+    private String bindingValueChangeEvent = "mx.events.PropertyChangeEvent";
+
+    public String getBindingValueChangeEvent()
+    {
+        return bindingValueChangeEvent;
+    }
+
+    /**
+     * The change event class for generated binding code
+     */
+    @Config(advanced = true)
+    public void setCompilerBindingValueChangeEvent(ConfigurationValue cv, String b)
+    {
+        bindingValueChangeEvent = b;
+    }
+
+    //
+    // 'compiler.binding-value-change-event-kind' option
+    //
+
+    private String bindingValueChangeEventKind = "mx.events.PropertyChangeEventKind";
+
+    public String getBindingValueChangeEventKind()
+    {
+        return bindingValueChangeEventKind;
+    }
+
+    /**
+     * The change event kind for generated binding code
+     */
+    @Config(advanced = true)
+    public void setCompilerBindingValueChangeEventKind(ConfigurationValue cv, String b)
+    {
+        bindingValueChangeEventKind = b;
+    }
+
+    //
+    // 'compiler.binding-value-change-event-type' option
+    //
+
+    private String bindingValueChangeEventType = "propertyChange";
+
+    public String getBindingValueChangeEventType()
+    {
+        return bindingValueChangeEventType;
+    }
+
+    /**
+     * The change event type for generated binding code
+     */
+    @Config(advanced = true)
+    public void setCompilerBindingValueChangeEventType(ConfigurationValue cv, String b)
+    {
+        bindingValueChangeEventType = b;
+    }
+
+    //
+    // 'compiler.binding-event-handler-event' option
+    //
+
+    private String bindingEventHandlerEvent = "flash.events.Event";
+
+    public String getBindingEventHandlerEvent()
+    {
+        return bindingEventHandlerEvent;
+    }
+
+    /**
+     * The event handler event for generated binding code
+     */
+    @Config(advanced = true)
+    public void setCompilerBindingEventHandlerEvent(ConfigurationValue cv, String b)
+    {
+        bindingEventHandlerEvent = b;
+    }
+
+    //
+    // 'compiler.binding-event-handler-class' option
+    //
+
+    private String bindingEventHandlerClass = "flash.events.EventDispatcher";
+
+    public String getBindingEventHandlerClass()
+    {
+        return bindingEventHandlerClass;
+    }
+
+    /**
+     * The event handler class for generated binding code
+     */
+    @Config(advanced = true)
+    public void setCompilerBindingEventHandlerClass(ConfigurationValue cv, String b)
+    {
+        bindingEventHandlerClass = b;
+    }
+    
+    //
+    // 'compiler.binding-event-handler-interface' option
+    //
+
+    private String bindingEventHandlerInterface = "flash.events.IEventDispatcher";
+
+    public String getBindingEventHandlerInterface()
+    {
+        return bindingEventHandlerInterface;
+    }
+
+    /**
+     * The event handler interface for generated binding code
+     */
+    @Config(advanced = true)
+    public void setCompilerBindingEventHandlerInterface(ConfigurationValue cv, String b)
+    {
+        bindingEventHandlerInterface = b;
+    }
+    
+    /**
+     * Syntax:<br/>
+     * <code>-define=&lt;name&gt;,&lt;value&gt;</code>
+     * where name is <code>NAMESPACE::name</code> and value is a legal definition value
+     * (e.g. <code>true</code> or <code>1</code> or <code>!CONFIG::debugging</code>)
+     *
+     * Example: <code>-define=CONFIG::debugging,true</code>
+     *
+     * In <code>flex-config.xml</code>:<br/>
+     * <pre>
+     * <flex-config>
+     *    <compiler>
+     *       <define>
+     *          <name>CONFIG::debugging</name>
+     *          <value>true</value>
+     *       </define>
+     *       ...
+     *    </compile>
+     * </flex-config>
+     * </pre>
+     *
+     * Values:<br/>
+     * Values are ActionScript expressions that must coerce and evaluate to constants at compile-time.
+     * Effectively, they are replaced in AS code, verbatim, so <code>-define=TEST::oneGreaterTwo,"1>2"</code>
+     * will getCompiler coerced and evaluated, at compile-time, to <code>false</code>.
+     *
+     * It is good practice to wrap values with double-quotes,
+     * so that MXMLC correctly parses them as a single argument:<br/>
+     * <code>-define=TEST::oneShiftRightTwo,"1 >> 2"</code>
+     *
+     * Values may contain compile-time constants and other configuration values:<br/>
+     * <code>-define=CONFIG::bool2,false -define=CONFIG::and1,"CONFIG::bool2 && false" TestApp.mxml</code>
+     *
+     * String values on the command-line <i>must</i> be surrounded by double-quotes, and either
+     * escape-quoted (<code>"\"foo\""</code> or <code>"\'foo\'"</code>) or single-quoted
+     * (<code>"'foo'"</code>).
+     *
+     * String values in configuration files need only be single- or double- quoted:<br/>
+     * <pre>
+     * <flex-config>
+     *    <compiler>
+     *       <define>
+     *          <name>NAMES::Organization</name>
+     *          <value>'Apache Software Foundation'</value>
+     *       </define>
+     *       <define>
+     *          <name>NAMES::Application</name>
+     *          <value>"Flex 4.8.0"</value>
+     *       </define>
+     *       ...
+     *    </compile>
+     * </flex-config>
+     * </pre>
+     *
+     * Empty strings <i>must</i> be passed as <code>"''"</code> on the command-line, and
+     * <code>''</code> or <code>""</code> in configuration files.
+     * 
+     * Finally, if you have existing definitions in a configuration file, and you would
+     * like to add to them with the command-line (let's say most of your build setCompilertings
+     * are in the configuration, and that you are adding one temporarily using the
+     * command-line), you use the following syntax:
+     * <code>-define+=TEST::temporary,false</code> (noting the plus sign)
+     * 
+     * Note that definitions can be overridden/redefined if you use the append ("+=") syntax
+     * (on the commandline or in a user config file, for instance) with the same namespace
+     * and name, and a new value.
+     * 
+     * Definitions cannot be removed/undefined. You can undefine ALL existing definitions
+     * from (e.g. from flex-config.xml) if you do not use append syntax ("=" or append="false").
+     * 
+     * IMPORTANT FOR FLEXBUILDER
+     * If you are using "Additional commandline arguments" to "-define", don't use the following
+     * syntax though I suggest it above:
+     *     -define+=CONFIG::foo,"'value'"
+     * The trouble is that FB parses the double quotes incorrectly as <"'value'> -- the trailing
+     * double-quote is dropped. The solution is to avoid inner double-quotes and put them around the whole expression:
+     *    -define+="CONFIG::foo,'value'"
+     */
+    private Map<String, String> configVars;
+
+    /**
+     * @return A list of ConfigVars
+     */
+
+    public Map<String, String> getCompilerDefine()
+    {
+        return configVars;
+    }
+
+    @Config(advanced = true, allowMultiple = true)
+    @Arguments({"name", "value"})
+    public void setCompilerDefine(ConfigurationValue cv, String name, String value) throws ConfigurationException
+    {
+        if (configVars == null)
+            configVars = new LinkedHashMap<String, String>();
+
+        configVars.put(name, value);
+    }
+
+    //
+    // 'compiler.conservative' option (hidden)
+    //
+
+    private boolean useConservativeAlgorithm = false;
+
+    public boolean useConservativeAlgorithm()
+    {
+        return useConservativeAlgorithm;
+    }
+
+    @Config(advanced = true, hidden = true)
+    @Mapping({"compiler", "conservative"})
+    public void setCompilerConservative(ConfigurationValue cv, boolean c)
+    {
+        useConservativeAlgorithm = c;
+    }
+
+    //
+    // 'compiler.context-root' option
+    //
+
+    private String contextRoot = null;
+
+    public String getCompilerContextRoot()
+    {
+        return contextRoot;
+    }
+
+    /**
+     * "Context root" is used to resolve {context.root} tokens in services
+     * configuration files to improve portability.
+     */
+    @Config
+    @Mapping({"compiler", "context-root"})
+    @Arguments("context-path")
+    @FlexOnly
+    public void setCompilerContextRoot(ConfigurationValue cv, String contextRoot)
+    {
+        this.contextRoot = contextRoot;
+    }
+
+    //
+    // 'compiler.debug' option
+    //
+
+    private boolean generateDebugTags = false;
+
+    public boolean isDebuggingEnabled()
+    {
+        return generateDebugTags;
+    }
+    
+    protected void setDebug(boolean value)
+    {
+        generateDebugTags = value;
+    }
+    
+    @Config
+    @Mapping({"compiler", "debug"})
+    public void setCompilerDebug(ConfigurationValue cv, boolean generateDebugTags)
+    {
+        this.generateDebugTags = generateDebugTags;
+    }
+
+    //
+    // 'compiler.defaults-css-url' option
+    //
+
+    /**
+     * Location of defaults stylesheet.
+     */
+    private String defaultsCssUrl;
+
+    public String getCompilerDefaultsCssUrl()
+    {
+        return defaultsCssUrl;
+    }
+
+    /**
+     * Defines the location of the default style sheet. Setting this option
+     * overrides the implicit use of the defaults.css style sheet in the
+     * framework.swc file.
+     */
+    @Config(advanced = true)
+    @Mapping({"compiler", "defaults-css-url"})
+    @FlexOnly
+    public void setCompilerDefaultsCssUrl(ConfigurationValue cv, String defaultsCssUrlPath) throws CannotOpen
+    {
+        defaultsCssUrl = resolvePathStrict(defaultsCssUrlPath, cv);
+    }
+
+    //
+    // 'compiler.doc' option (hidden)
+    //
+
+    private boolean doc = false;
+
+    public boolean getCompilerDoc()
+    {
+        return this.doc;
+    }
+
+    @Config(advanced = true, hidden = true)
+    @Mapping({"compiler", "doc"})
+    public void setCompilerDoc(ConfigurationValue cv, boolean doc)
+    {
+        this.doc = doc;
+    }
+
+    //
+    // 'compiler.external-library-path' option
+    //
+
+    private final List<String> externalLibraryPath = new ArrayList<String>();
+
+    public List<String> getCompilerExternalLibraryPath()
+    {
+        return externalLibraryPath;
+    }
+
+    private boolean compilingForAIR = false;
+
+    /**
+     * @return True if AIR libraries are included in the
+     * {@code external-library-path}.
+     */
+    public boolean getCompilingForAIR()
+    {
+        return compilingForAIR;
+    }
+
+    @Config(allowMultiple = true, isPath = true)
+    @Mapping({"compiler", "external-library-path"})
+    @Arguments(Arguments.PATH_ELEMENT)
+    @SoftPrerequisites({"target-player"})
+    @InfiniteArguments
+    public void setCompilerExternalLibraryPath(ConfigurationValue cv, String[] pathlist) throws ConfigurationException
+    {
+        final ImmutableList<String> pathElements = ImmutableList.copyOf(pathlist);
+        final ImmutableList<String> resolvedPaths = expandTokens(pathElements, 
+                locales, cv, !reportMissingCompilerLibraries);
+        externalLibraryPath.addAll(resolvedPaths);
+
+        // TODO: Review usages of "compilingForAIR", because only looking at path elements
+        // on library path isn't enough. There might be a folder on the library path that
+        // contains AIR libraries.
+        compilingForAIR = containsAIRLibraries(pathElements);
+    }
+
+    /**
+     * Returns true if there's AIR libraries on the library paths.
+     * 
+     * @param libraryPaths Library paths.
+     * @return True if there's AIR libraries on the library paths.
+     */
+    private static boolean containsAIRLibraries(final ImmutableList<String> libraryPaths)
+    {
+        for (final String path : libraryPaths)
+        {
+            if (path.equals(SWC_AIRGLOBAL) ||
+                path.endsWith("/" + SWC_AIRGLOBAL) ||
+                path.endsWith("\\" + SWC_AIRGLOBAL))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    //
+    // 'compiler.generated-directory' option
+    // This can only be configured using getter and setter.
+    //
+
+    private String generatedDir = null;
+
+    public String getCompilerGeneratedDirectory()
+    {
+        return generatedDir;
+    }
+
+    public void setCompilerGeneratedDirectory(String generatedDir)
+    {
+        this.generatedDir = generatedDir;
+    }
+
+    //
+    // 'compiler.headless-server' option
+    //
+
+    private boolean headlessServer;
+
+    public boolean isHeadlessServer()
+    {
+        return headlessServer;
+    }
+
+    @Config(advanced = true)
+    @Mapping({"compiler", "headless-server"})
+    @FlexOnly
+    public void setCompilerHeadlessServer(ConfigurationValue cv, boolean headlessServer)
+    {
+        this.headlessServer = headlessServer;
+    }
+
+    //
+    // 'compiler.include-libraries' option
+    //
+
+    private final List<String> includeLibraries = new ArrayList<String>();
+
+    public List<String> getCompilerIncludeLibraries()
+    {
+        return includeLibraries;
+    }
+
+    /**
+     * Links all classes inside a SWC file to the resulting application SWF
+     * file, regardless of whether or not they are used.
+     * <p>
+     * Contrast this option with the library-path option that includes only
+     * those classes that are referenced at compile time.
+     * <p>
+     * To link one or more classes whether or not they are used and not an
+     * entire SWC file, use the includes option.
+     * <p>
+     * This option is commonly used to specify resource bundles.
+     */
+    @Config(allowMultiple = true, isPath = true)
+    @Mapping({"compiler", "include-libraries"})
+    @Arguments("library")
+    @InfiniteArguments
+    public void setCompilerIncludeLibraries(ConfigurationValue cv, String[] pathlist) throws CannotOpen
+    {
+        final ImmutableList<String> resolvedPaths = expandTokens(
+                Arrays.asList(pathlist),
+                locales,
+                cv, !reportMissingCompilerLibraries);
+        includeLibraries.addAll(resolvedPaths);
+    }
+
+    //
+    // 'compiler.incremental' option
+    //
+
+    @Config(removed = true)
+    @Mapping({"compiler", "incremental"})
+    public void setCompilerIncremental(ConfigurationValue cv, boolean b)
+    {
+    }
+
+    //
+    // 'compiler.keep-all-type-selectors' option.  
+
+    /**
+     * This was initially used by Flex Builder when building design view, but
+     * they no longer use it.
+     */
+    private boolean keepAllTypeSelectors;
+
+    public boolean keepAllTypeSelectors()
+    {
+        return keepAllTypeSelectors;
+    }
+
+    @Config(advanced = true)
+    @Mapping({"compiler", "keep-all-type-selectors"})
+    @FlexOnly
+    public void setCompilerKeepAllTypeSelectors(ConfigurationValue cv, boolean keepAllTypeSelectors)
+    {
+        this.keepAllTypeSelectors = keepAllTypeSelectors;
+    }
+
+    //
+    // 'compiler.keep-as3-metadata' option
+    //
+
+    private Set<String> as3metadata = null;
+
+    public Set<String> getCompilerKeepAs3Metadata()
+    {
+        return as3metadata == null ? Collections.<String> emptySet() : as3metadata;
+    }
+
+    @Config(advanced = true, allowMultiple = true)
+    @Mapping({"compiler", "keep-as3-metadata"})
+    @Arguments("name")
+    @InfiniteArguments
+    public void setCompilerKeepAs3Metadata(ConfigurationValue cv, List<String> values)
+    {
+        if (as3metadata == null)
+            as3metadata = new HashSet<String>();
+        as3metadata.addAll(values);
+    }
+
+    //
+    // 'compiler.keep-generated-actionscript' option (removed)
+    //
+
+    @Config(removed = true)
+    @Mapping({"compiler", "keep-generated-actionscript"})
+    public void setCompilerKeepGeneratedActionscript(ConfigurationValue cv, boolean keep)
+    {
+    }
+
+    //
+    // 'compiler.keep-generated-signatures' option (removed)
+    //
+
+    @Config(removed = true)
+    @Mapping({"compiler", "keep-generated-signatures"})
+    public void setCompilerKeepGeneratedSignatures(ConfigurationValue cv, boolean keep)
+    {
+    }
+
+    //
+    // 'compiler.enable-runtime-design-layers' option
+    //
+
+    private boolean enableRuntimeDesignLayers = true;
+
+    public boolean getEnableRuntimeDesignLayers()
+    {
+        return enableRuntimeDesignLayers;
+    }
+
+    @Config
+    @Mapping({"compiler", "enable-runtime-design-layers"})
+    @FlexOnly
+    public void setCompilerEnableRuntimeDesignLayers(ConfigurationValue cv, boolean enable)
+    {
+        enableRuntimeDesignLayers = enable;
+    }
+
+    //
+    // 'compiler.enable-swc-version-filtering' option
+    //
+
+    private boolean enableSwcVersionFiltering = true;
+
+    public boolean getEnableSwcVersionFiltering()
+    {
+        return enableSwcVersionFiltering;
+    }
+
+    @Config(advanced = true, hidden = true)
+    @Mapping({"compiler", "enable-swc-version-filtering"})
+    public void setCompilerEnableSwcVersionFiltering(ConfigurationValue cv, boolean enable)
+    {
+        this.enableSwcVersionFiltering = enable;
+    }
+
+    //
+    // 'compiler.library-path' option
+    //
+
+    private final List<String> libraryPath = new ArrayList<String>();
+    private boolean reportMissingCompilerLibraries = true;
+
+    /**
+     * Sets whether to report missing libraries in the configuration.  If this is false
+     * any missing libraries will not be warned about, and the filename will also be added to list
+     * of libraries in the project when it doesn't exist.  If reportMissingCompilerLibraries
+     * is true, any missing libraries will not be added to the project.
+     * 
+     * @param reportMissingCompilerLibraries true to report missing libraries
+     */
+    public void setReportMissingCompilerLibraries(boolean reportMissingCompilerLibraries)
+    {
+        this.reportMissingCompilerLibraries = reportMissingCompilerLibraries;
+    }
+
+    public List<String> getCompilerLibraryPath()
+    {
+        return libraryPath;
+    }
+
+    /**
+     * Links SWC files to the resulting application SWF file. The compiler only
+     * links in those classes for the SWC file that are required. You can
+     * specify a directory or individual SWC files.
+     */
+    @Config(allowMultiple = true, isPath = true)
+    @Mapping({"compiler", "library-path"})
+    @Arguments(Arguments.PATH_ELEMENT)
+    @InfiniteArguments
+    @SoftPrerequisites({"locale", "target-player"})
+    public void setCompilerLibraryPath(ConfigurationValue cv, String[] pathlist) throws CannotOpen
+    {
+        final ImmutableList<String> resolvedPaths = expandTokens(
+                Arrays.asList(pathlist),
+                locales,
+                cv, !reportMissingCompilerLibraries);
+        libraryPath.addAll(resolvedPaths);
+    }
+
+    //
+    // 'compiler.locale' option
+    //
+
+    private final List<String> locales = new ArrayList<String>();
+
+    public List<String> getCompilerLocales()
+    {
+        return locales;
+    }
+
+    /**
+     * Specifies one or more locales to be compiled into the SWF file. If you do
+     * not specify a locale, then the compiler uses the default locale from the
+     * flex-config.xml file. The default value is en_US. You can append
+     * additional locales to the default locale by using the += operator. If you
+     * remove the default locale from the flex-config.xml file, and do not
+     * specify one on the command line, then the compiler will use the machine's
+     * locale.
+     */
+    @Config(allowMultiple = true)
+    @Mapping({"compiler", "locale"})
+    @Arguments("locale-element")
+    @InfiniteArguments
+    @FlexOnly
+    public void setCompilerLocale(ConfigurationValue cv, String[] newLocales)
+    {
+        locales.addAll(Arrays.asList(newLocales));
+    }
+
+    //
+    // 'compiler.metadata-export' option (incomplete)
+    //
+
+    private boolean metadataExport;
+
+    public boolean metadataExport()
+    {
+        return metadataExport;
+    }
+
+    // metadataExport does not have the normal configuration setCompilerter because it is not
+    // a normal configuration value but rather something setCompiler by the compiler
+    public void setCompilerMetadataExport(boolean metadataExport)
+    {
+        this.metadataExport = metadataExport;
+    }
+
+    //
+    // 'compiler.mxml.children-as-data' option
+    //
+    private Boolean childrenAsData = false;
+    
+    public Boolean getCompilerMxmlChildrenAsData()
+    {
+        return childrenAsData;
+    }
+
+    @Config
+    @Mapping({"compiler", "mxml", "children-as-data"})
+    @FlexOnly
+    public void setCompilerMxmlChildrenAsData(ConfigurationValue cv, Boolean asData) throws ConfigurationException
+    {
+        childrenAsData = asData;
+    }
+
+    //
+    // 'compiler.mxml.implicitImports' option
+    //
+    private String[] implicitImports;
+    
+    public String[] getCompilerMxmlImplicitImports()
+    {
+        return implicitImports;
+    }
+
+    @Config(allowMultiple = true)
+    @Mapping({"compiler", "mxml", "imports"})
+    @Arguments("implicit-import")
+    @InfiniteArguments
+    @FlexOnly
+    public void setCompilerMxmlImplicitImports(ConfigurationValue cv, String[] imports) throws ConfigurationException
+    {
+        implicitImports = imports;
+    }
+
+    //
+    // 'compiler.mxml.compatibility-version' option
+    //
+
+    public String getCompilerCompatibilityVersionString()
+    {
+        return getCompilerMxmlCompatibilityVersionString();
+    }
+
+    public int getCompilerCompatibilityVersion()
+    {
+        return getCompilerMxmlCompatibilityVersion();
+    }
+
+    //
+    // 'compiler.mxml.minimum-supported-version' option
+    //
+
+    public String getCompilerMinimumSupportedVersionString()
+    {
+        return getCompilerMxmlMinimumSupportedVersionString();
+    }
+
+    public int getCompilerMinimumSupportedVersion()
+    {
+        return getCompilerMxmlMinimumSupportedVersion();
+    }
+
+    @Config
+    @Mapping({"compiler", "minimum-supported-version"})
+    @FlexOnly
+    public void setCompilerMinimumSupportedVersion(ConfigurationValue cv, String version) throws ConfigurationException
+    {
+        setCompilerMxmlMinimumSupportedVersion(cv, version);
+    }
+
+    //
+    // 'qualified-type-selectors' option
+    //
+    @Config(advanced = true, removed = true)
+    @Mapping({"compiler", "mxml", "qualified-type-selectors"})
+    public void setCompilerMxmlQualifiedTypeSelectors(ConfigurationValue cv, boolean b)
+    {
+    }
+
+    //
+    // 'compiler.omit-trace-statements' option
+    //
+
+    private boolean omitTraceStatements = true;
+
+    public boolean omitTraceStatements()
+    {
+        return omitTraceStatements;
+    }
+
+    @Config
+    @Mapping({"compiler", "omit-trace-statements"})
+    public void setCompilerOmitTraceStatements(ConfigurationValue cv, boolean b)
+    {
+        omitTraceStatements = b;
+    }
+
+    //
+    // 'compiler.optimize' option
+    //
+
+    private boolean optimize = false;
+
+    public boolean optimize()
+    {
+        return optimize;
+    }
+
+    public boolean getCompilerOptimize()
+    {
+        return optimize;
+    }
+
+    @Config
+    @Mapping({"compiler", "optimize"})
+    public void setCompilerOptimize(ConfigurationValue cv, boolean b)
+    {
+        optimize = b;
+    }
+    
+    
+    //
+    // 'compiler.preloader' option
+    //
+
+    private String preloader = null;
+
+    /**
+     * 
+     * @return Returns the preloader class configured by the user. If the 
+     * user did not configure a preloader, the
+     * "mx.preloader.DownloaderProgressBar" preloader will be returned if the
+     * compatibility version is less than 4.0. Otherwise the 
+     * "mx.preloaders.SparkDownloadProgressBar" preloader will be returned. 
+     */
+    public String getPreloader()
+    {
+        if (preloader != null)
+            return preloader;
+        
+        if (getCompilerMxmlCompatibilityVersion() < MXML_VERSION_4_0)
+            return IMXMLTypeConstants.DownloadProgressBar;
+        else
+            return IMXMLTypeConstants.SparkDownloadProgressBar;
+    }
+    
+    public String getCompilerPreloader()
+    {
+        return preloader;
+    }
+    
+    @Config
+    @Mapping({"compiler", "preloader"})
+    @FlexOnly
+    public void setCompilerPreloader(ConfigurationValue cv, String value)
+    {
+        preloader = value;
+    }
+
+    //
+    // 'compiler.services' option
+    //
+
+    private File servicesConfigFile;
+
+    //protected ServicesDependencies servicesDependencies;
+
+    public File getCompilerServices()
+    {
+        return servicesConfigFile;
+    }
+
+    /**
+     * Used by the compiler to record the client dependencies from the Flex Data
+     * Services configuration file.
+     */
+    /*
+     * public ServicesDependencies getCompilerServicesDependencies() { if
+     * (servicesDependencies == null && servicesConfigFile != null) { String
+     * servicesPath = servicesConfigFile.getName(); servicesDependencies = new
+     * ServicesDependencies(servicesPath, null, getCompilerContextRoot()); }
+     * return servicesDependencies; } public void
+     * setCompilerServicesDependencies(ServicesDependencies deps) {
+     * servicesDependencies = deps; }
+     */
+
+    @Config
+    @Mapping({"compiler", "services"})
+    @Arguments("filename")
+    @FlexOnly
+    public void setCompilerServices(ConfigurationValue cv, String servicesPath) throws ConfigurationException
+    {
+        try
+        {
+            servicesConfigFile = new File(resolvePathStrict(servicesPath, cv));
+        }
+        catch (Throwable t)
+        {
+            throw new ConfigurationException.CannotOpen(servicesPath, cv.getVar(), cv.getSource(), cv.getLine());
+        }
+    }
+
+    //
+    // 'compiler.show-actionscript-warnings' option
+    //
+
+    /**
+     * Enable asc -warnings
+     */
+    private boolean ascWarnings;
+
+    public boolean warnings()
+    {
+        return this.ascWarnings;
+    }
+
+    @Config
+    @Mapping({"compiler", "show-actionscript-warnings"})
+    public void setCompilerShowActionscriptWarnings(ConfigurationValue cv, boolean ascWarnings)
+    {
+        this.ascWarnings = ascWarnings;
+    }
+
+    //
+    // 'compiler.show-binding-warnings' option
+    //
+
+    /**
+     * Controls whether binding warnings are displayed.
+     */
+    private boolean showBindingWarnings = true;
+
+    public boolean showBindingWarnings()
+    {
+        return showBindingWarnings;
+    }
+
+    @Config
+    @Mapping({"compiler", "show-binding-warnings"})
+    public void setCompilerShowBindingWarnings(ConfigurationValue cv, boolean show)
+    {
+        this.showBindingWarnings = show;
+    }
+
+    @Config
+    @Mapping({"compiler", "show-multiple-definition-warnings"})
+    public void setCompilerShowMultipleDefinitionWarnings(ConfigurationValue cv, boolean show)
+    {
+        this.showMultipleDefinitionWarnings = show;
+    }
+    //
+    // 'compiler.show-dependency-warnings' option (hidden)
+    //
+
+    private boolean showDependencyWarnings = false;
+
+    public boolean showDependencyWarnings()
+    {
+        return showDependencyWarnings;
+    }
+
+    @Config(advanced = true, hidden = true)
+    @Mapping({"compiler", "show-dependency-warnings"})
+    public void setCompilerShowDependencyWarnings(ConfigurationValue cv, boolean show)
+    {
+        this.showDependencyWarnings = show;
+    }
+
+    //
+    // 'compiler.report-invalid-styles-as-warnings' option
+    //
+    
+    /**
+     * Controls whether invalid styles are report as errors or warnings.
+     */
+    private boolean reportInvalidStylesAsWarnings = false;
+
+    /**
+     * Get value of {@code compiler.report-invalid-styles-as-warnings} option
+     * value.
+     * <p>
+     * <h2>What's "invalid styles"?</h2> The term "invalid style" only applies
+     * to MXML style specifier (a.k.a. inline style). If a style of a component
+     * is defined with "theme" attribute, the style is only effective with such
+     * theme. If a theme-specific style is used in an application who doesn't
+     * use the required theme, the style is considered invalid.
+     * <p>
+     * For example, style "fooStyle" is defined to used only with theme called
+     * "fooTheme":
+     * 
+     * <pre>
+     * [Style(name="fooStyle", type="uint", format="Color", inherit="yes", theme="fooTheme")]
+     * public class MyComponent extends UIComponent
+     * </pre>
+     * 
+     * If "fooTheme" isn't used by the current application, the following style
+     * specifier is considered "invalid styles". <br>
+     * {@code <local:MyComponent fooStyle="white" />}
+     * 
+     * @return True if invalid styles are reported as warnings instead of
+     * errors.
+     */
+    public boolean getReportInvalidStylesAsWarnings()
+    {
+        return reportInvalidStylesAsWarnings;
+    }
+
+    @Config
+    @Mapping({"compiler", "report-invalid-styles-as-warnings"})
+    @FlexOnly
+    public void setCompilerReportInvalidStylesAsWarnings(ConfigurationValue cv, boolean show)
+    {
+        this.reportInvalidStylesAsWarnings = show;
+    }
+
+    //
+    // 'compiler.report-missing-required-skin-parts-as-warnings' option
+    //
+
+    private boolean reportMissingRequiredSkinPartsAsWarnings = false;
+
+    /**
+     * Allow the user to configure whether it should be considered an error to
+     * not create a required skin part or if it should just be a warning.
+     */
+    public boolean reportMissingRequiredSkinPartsAsWarnings()
+    {
+        return reportMissingRequiredSkinPartsAsWarnings;
+    }
+
+    @Config(advanced = true)
+    @Mapping({"compiler", "report-missing-required-skin-parts-as-warnings"})
+    @FlexOnly
+    public void setCompilerReportMissingRequiredSkinPartsAsWarnings(ConfigurationValue cv, boolean b)
+    {
+        reportMissingRequiredSkinPartsAsWarnings = b;
+    }
+
+    //
+    // 'compiler.show-invalid-css-property-warnings' option
+    //
+    
+    private boolean showInvalidCSSPropertyWarnings = true;
+
+    /**
+     * Controls whether warnings are displayed when styles, which don't apply to
+     * the current theme(s), are used in CSS.
+     * <p>
+     * See {@link #getReportInvalidStylesAsWarnings()} for definition of
+     * "invalid style".
+     * <p>
+     * This option applies to <i>invalid styles</i> in a {@code <fx:Style>}
+     * block.
+     */
+    public boolean getShowInvalidCSSPropertyWarnings()
+    {
+        return showInvalidCSSPropertyWarnings;
+    }
+
+    @Config
+    @Mapping({"compiler", "show-invalid-css-property-warnings"})
+    @FlexOnly
+    public void setShowInvalidCssPropertyWarnings(ConfigurationValue cv, boolean show)
+    {
+        this.showInvalidCSSPropertyWarnings = show;
+    }
+
+    //
+    // 'compiler.show-deprecation-warnings' option
+    //
+
+    /**
+     * Controls whether warnings are displayed when a deprecated API is used.
+     */
+    private boolean showDeprecationWarnings = false;
+
+    public boolean showDeprecationWarnings()
+    {
+        return showDeprecationWarnings;
+    }
+
+    @Config(advanced = true, hidden = true)
+    @Mapping({"compiler", "show-deprecation-warnings"})
+    public void setCompilerShowDeprecationWarnings(ConfigurationValue cv, boolean show)
+    {
+        this.showDeprecationWarnings = show;
+    }
+
+    //
+    // 'compiler.show-shadowed-device-font-warnings' option
+    //
+    @Config
+    @Mapping({"compiler", "show-shadowed-device-font-warnings"})
+    @FlexOnly
+    public void setCompilerShowShadowedDeviceFontWarnings(ConfigurationValue cv, boolean show)
+    {
+        // intentionally do nothing here as feature removed, but don't annotate as removed
+        // as to not generate warnings for flex-config's which still set this options
+    }
+
+    //
+    // 'compiler.show-unused-type-selector-warnings' option
+    //
+
+    private boolean showUnusedTypeSelectorWarnings = true;
+
+    public boolean showUnusedTypeSelectorWarnings()
+    {
+        return showUnusedTypeSelectorWarnings;
+    }
+
+    //
+    // 'compiler.show-multiple-definition-warnings' option
+    //
+
+    private boolean showMultipleDefinitionWarnings = true;
+
+    public boolean showMultipleDefinitionWarnings()
+    {
+        return showMultipleDefinitionWarnings;
+    }
+    
+    @Config
+    @Mapping({"compiler", "show-unused-type-selector-warnings"})
+    @FlexOnly
+    public void setCompilerShowUnusedTypeSelectorWarnings(ConfigurationValue cv, boolean show)
+    {
+        this.showUnusedTypeSelectorWarnings = show;
+    }
+
+    //
+    // 'compiler.source-path' option
+    //
+
+    /**
+     * Source path elements searched for ActionScript class files, possibly
+     * containing a {locale} token.
+     */
+    private final List<String> unexpandedSourcePath = new ArrayList<String>();
+
+    /**
+     * Directories searched for ActionScript class files. The specified
+     * compiler.source-path can have path elements which contain a special
+     * {locale} token. If you compile for a single locale, this token is
+     * replaced by the specified locale. If you compile for multiple locales,
+     * any path element with the {locale} token is ignored, because we do not
+     * support compiling, for example, both en_US and ja_JP versions of
+     * MyComponent into the same SWF. A path element with {locale} is similarly
+     * ignored if you compile for no locale.
+     */
+    private final List<String> sourcePath = new ArrayList<String>();
+
+    /** Context object for "source-path" option. */
+    private ConfigurationValue sourcePathContext = null;
+
+    public List<String> getCompilerSourcePath()
+    {
+        return sourcePath;
+    }
+
+    /**
+     * Get the source paths computed from the given {@code locale}. The locale
+     * must be included in the configuration.
+     * 
+     * @param locale Locale name.
+     * @return Source paths computed from the given {@code locale}.
+     * @throws CannotOpen Error resolving one of the paths from this locale.
+     */
+    public ImmutableList<String> getCompilerResourceBundlePathForLocale(String locale) throws CannotOpen
+    {
+        assert locales.contains(locale) : "Locale is not configured: " + locale;
+        return expandTokens(unexpandedSourcePath, ImmutableSet.of(locale), 
+                sourcePathContext, !reportMissingCompilerLibraries);
+    }
+
+    @Config(allowMultiple = true)
+    @Arguments(Arguments.PATH_ELEMENT)
+    @SoftPrerequisites("locale")
+    public void setCompilerSourcePath(ConfigurationValue cv, String[] paths) throws ConfigurationException
+    {
+        final List<String> pathList = Arrays.asList(paths);
+        unexpandedSourcePath.addAll(pathList);
+
+        final ImmutableList<String> resolvedSourcePaths = expandTokens(pathList, locales, cv);
+        assertThatAllPathsAreDirectories(resolvedSourcePaths, cv);
+        sourcePath.addAll(resolvedSourcePaths);
+
+        sourcePathContext = cv;
+    }
+
+    /**
+     * Check that all paths in the path list are directories.
+     * 
+     * @param paths A list of paths.
+     * @param cv Context.
+     * @throws NotDirectory Path is not a directory exception.
+     */
+    public static void assertThatAllPathsAreDirectories(
+            final List<String> paths,
+            final ConfigurationValue cv)
+            throws NotDirectory
+    {
+        assert paths != null : "Expected path list.";
+        assert cv != null : "Expected ConfigurationValue as context.";
+
+        for (final String path : paths)
+        {
+            final File file = new File(path);
+            if (!file.isDirectory())
+                throw new NotDirectory(path, cv.getVar(), cv.getSource(), cv.getLine());
+        }
+    }
+
+    public static ConfigurationInfo getCompilerSourcePathInfo()
+    {
+        return new ConfigurationInfo(-1, new String[] {"path-element"})
+        {
+            @Override
+            public boolean allowMultiple()
+            {
+                return true;
+            }
+
+            @Override
+            public boolean isPath()
+            {
+                return true;
+            }
+        };
+    }
+
+    //
+    // 'compiler.strict' option
+    //
+
+    /**
+     * Run the AS3 compiler in strict mode
+     */
+    private boolean strict;
+
+    public boolean strict()
+    {
+        return this.strict;
+    }
+
+    @Config
+    @Mapping({"compiler", "stri

<TRUNCATED>