You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ah...@apache.org on 2014/04/06 07:39:29 UTC

[07/26] fork a bunch of files from SDK's FB compiler integration. Several files are intact, but many have been gutted to reduce the number of files required. It appears that the Report isn't used for basic compilation, so removing all of the compilatio

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dff3a518/flex-compiler-oem/src/flex2/tools/oem/internal/OEMConfiguration.java
----------------------------------------------------------------------
diff --git a/flex-compiler-oem/src/flex2/tools/oem/internal/OEMConfiguration.java b/flex-compiler-oem/src/flex2/tools/oem/internal/OEMConfiguration.java
new file mode 100644
index 0000000..d48f8fd
--- /dev/null
+++ b/flex-compiler-oem/src/flex2/tools/oem/internal/OEMConfiguration.java
@@ -0,0 +1,2813 @@
+/*
+ *
+ *  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 flex2.tools.oem.internal;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.Map.Entry;
+
+import macromedia.asc.embedding.ConfigVar;
+import macromedia.asc.util.ObjectList;
+import flex2.compiler.common.CompilerConfiguration;
+import flex2.compiler.common.FontsConfiguration;
+import flex2.compiler.common.FramesConfiguration;
+import flex2.compiler.common.NamespacesConfiguration;
+import flex2.compiler.common.RuntimeSharedLibrarySettingsConfiguration;
+import flex2.compiler.common.Configuration.RslPathInfo;
+import flex2.compiler.common.FramesConfiguration.FrameInfo;
+import flex2.compiler.config.ConfigurationBuffer;
+import flex2.compiler.io.FileUtil;
+import flex2.compiler.io.LocalFile;
+import flex2.compiler.io.VirtualFile;
+import flex2.tools.LicensesConfiguration;
+import flex2.tools.ToolsConfiguration;
+import flex2.tools.oem.Configuration;
+
+/**
+ * A ToolsConfiguration wrapper, which provides strongly typed
+ * configuration getters and setters, which internally storing them
+ * loosely typed for later processing.  This is part of a complex
+ * scheme to only expose some of the compiler's configurability while
+ * supporting merging with configuration defaults.
+ *
+ * @version 2.0.1
+ * @author Clement Wong
+ */
+public class OEMConfiguration implements Configuration, ConfigurationConstants, Cloneable
+{
+	/**
+	 *  Created to enable picking out cross-domain args by type.
+	 */
+	class RslPathList extends ArrayList<String[]>
+    {
+		private static final long serialVersionUID = 0L;
+	}
+	
+    /**
+     *  Ditto for conditional compilation
+     */
+    class CompilerDefinitionList extends ArrayList<String>
+    {
+        private static final long serialVersionUID = 0L;
+    }
+	
+    /**
+     *  Ditto for application-domains
+     */
+    class ApplicationDomainsList extends ArrayList<String[]>
+    {
+        private static final long serialVersionUID = 0L;
+    }
+    
+	OEMConfiguration(ConfigurationBuffer cfgbuf, ToolsConfiguration configuration)
+	{
+		this.cfgbuf = cfgbuf;
+		this.configuration = configuration;
+		
+		args = new LinkedHashMap<String, Object>();
+		more = new LinkedHashMap<String, Object>();
+		linker_args = new LinkedHashMap<String, Object>();
+		linker_more = new LinkedHashMap<String, Object>();
+		newLinkerOptionsAfterCompile = new HashSet<String>();
+		
+		if (configuration != null)
+		{
+			populateDefaults(configuration);
+		}
+		
+		defaults = args;
+		args = new LinkedHashMap<String, Object>();
+		linker_args = new LinkedHashMap<String, Object>();
+		newLinkerOptionsAfterCompile.clear();
+		
+		keepLinkReport = false;
+		keepSizeReport = false;
+		keepConfigurationReport = false;
+		
+		tokens = new TreeMap<String, String>();
+	}
+
+	public ConfigurationBuffer cfgbuf;
+	public final ToolsConfiguration configuration;
+	
+	private Map<String, Object> args, defaults, more, linker_args, linker_more;
+	private String[] extras;
+	public final Set<String> newLinkerOptionsAfterCompile;
+	private boolean keepLinkReport, keepSizeReport, keepConfigurationReport;
+	
+	private Map<String, String> tokens;
+
+	/**
+	 * 
+	 * @param c
+	 */
+	void importDefaults(OEMConfiguration c)
+	{
+		args.putAll(c.defaults);
+	}
+	
+	/**
+	 * 
+	 * @return
+	 */
+	public String[] getCompilerOptions()
+	{
+		return getOptions(args, more, true);
+	}
+	
+	/**
+	 * 
+	 * @return
+	 */
+	public String[] getLinkerOptions()
+	{
+		return getOptions(linker_args, linker_more, false);
+	}
+	
+	/**
+	 * 
+	 * @return
+	 */
+    
+    //TEST ME
+	private String[] getOptions(Map<String, Object> args, Map<String, Object> more, boolean processExtras)
+	{
+		ArrayList<String> buffer = new ArrayList<String>();
+		
+        //TODO this can be optimized to use the entrySet
+		for (Iterator<String> i = tokens.keySet().iterator(); i.hasNext(); )
+		{
+			String key = i.next();
+			String value = tokens.get(key);
+			buffer.add("+" + key + "=" + value);
+		}
+		
+		for (Iterator<String> i = args.keySet().iterator(); i.hasNext(); )
+		{
+			String key = (String) i.next();
+			Object value = args.get(key);
+
+			if (value instanceof Boolean)
+			{
+				buffer.add(key + "=" + value);
+			}
+			else if (value instanceof Number)
+			{
+				buffer.add(key);
+				buffer.add(value.toString());
+			}
+			else if (COMPILER_CONTEXT_ROOT.equals(key) && value instanceof String)
+			{				
+				buffer.add(key);
+				buffer.add((String)value);
+			}
+			else if (value instanceof String)
+			{				
+				if (!"".equals(value))
+				{
+					buffer.add(key);
+					buffer.add((String)value);
+				}
+				else
+				{
+					buffer.add(key + "=");
+				}
+			}
+			else if (value instanceof File)
+			{
+				String p = ((File) value).getPath();
+				if (!"".equals(p))
+				{
+					buffer.add(key);
+					buffer.add(p);
+				}
+				else
+				{
+					buffer.add(key + "=");
+				}
+			}
+			else if (value instanceof URL)
+			{
+				String u = ((URL) value).toExternalForm();
+				if (!"".equals(u))
+				{
+					buffer.add(key);
+					buffer.add(u);
+				}
+				else
+				{
+					buffer.add(key + "=");
+				}
+			}
+			else if (value instanceof java.util.Date)
+			{
+				buffer.add(key);
+				buffer.add(value.toString());
+			}
+			else if (value instanceof Map)
+			{
+				Map m = (Map) value;
+				for (Iterator j = m.keySet().iterator(); j.hasNext(); )
+				{
+					String k = (String) j.next();
+					Object v = m.get(k);
+					
+					if (v instanceof String)
+					{
+						buffer.add(key);
+						buffer.add(k);
+						buffer.add((String)v);
+					}
+					else if (v instanceof File)
+					{
+						buffer.add(key);
+						buffer.add(k);
+						buffer.add(((File) v).getPath());
+					}
+					else if (v instanceof String[])
+					{
+						buffer.add(key);
+						buffer.add(k);
+						buffer.add(toCommaSeparatedString((String[]) v));
+					}
+					else if (v instanceof List)
+					{
+						buffer.add(key);
+						buffer.add(k);
+						Iterator it = ((List)v).iterator();
+						while (it.hasNext())
+						{
+							Object next = it.next();
+							if (next != null)
+								buffer.add(next.toString());
+						}
+					}
+					else if (v != null)
+					{
+						assert false;
+					}
+				}
+			}
+			else if (value instanceof int[])
+			{
+				int[] a = (int[]) value;
+				buffer.add(key);
+				buffer.add(String.valueOf(a[0]));
+				buffer.add(String.valueOf(a[1]));
+			}
+			else if (value instanceof String[])
+			{
+				String[] a = merge((String[]) args.get(key), (String[]) more.get(key));
+				int length = a == null ? 0 : a.length;
+				if (length > 0)
+				{
+					buffer.add(key);
+				}
+				else
+				{
+					buffer.add(key + "=");
+				}
+				for (int j = 0; j < length; j++)
+				{
+					if (a[j] != null)
+					{
+						buffer.add(a[j]);
+					}
+				}
+			}
+			else if (LOAD_CONFIG.equals(key) && value instanceof File[])
+			{
+				File[] a = merge((File[]) args.get(key), (File[]) more.get(key));
+				for (int j = 0, length = a == null ? 0 : a.length; j < length; j++)
+				{
+					if (a[j] != null)
+					{
+						buffer.add(key);
+						buffer.add(a[j].getPath());
+					}
+				}
+			}
+			else if (value instanceof File[])
+			{
+				File[] a = merge((File[]) args.get(key), (File[]) more.get(key));
+				int length = a == null ? 0 : a.length;
+				if (length > 0)
+				{
+					buffer.add(key);
+				}
+				else
+				{
+					buffer.add(key + "=");
+				}
+				for (int j = 0; j < length; j++)
+				{
+					if (a[j] != null)
+					{
+						buffer.add(a[j].getPath());
+					}
+				}
+			}
+			else if (value instanceof URL[])
+			{
+				URL[] a = merge((URL[]) args.get(key), (URL[]) more.get(key));
+				int length = a == null ? 0 : a.length;
+				if (length > 0)
+				{
+					buffer.add(key);
+				}
+				else
+				{
+					buffer.add(key + "=");
+				}
+				for (int j = 0; j < length; j++)
+				{
+					if (a[j] != null)
+					{
+						buffer.add(a[j].toExternalForm());
+					}
+				}
+			}
+			else if (value instanceof RslPathList)
+			{
+				RslPathList valueList = (RslPathList)value;
+				for (Iterator<String[]> iter = valueList.iterator(); iter.hasNext();) 
+				{
+					StringBuilder sb = new StringBuilder(RUNTIME_SHARED_LIBRARY_PATH);
+					sb.append("=");
+					String[] cdArgs = iter.next();
+					sb.append(cdArgs[0]);
+					for (int j = 1; j < cdArgs.length; j++)
+					{
+						sb.append(",");
+						sb.append(cdArgs[j]);
+					}
+					buffer.add(sb.toString());
+				}
+			}
+            else if (value instanceof CompilerDefinitionList)
+            {
+                final CompilerDefinitionList defs = (CompilerDefinitionList)value;
+                for (Iterator<String> iter = defs.iterator(); iter.hasNext();)
+                {
+                    // String.valueOf will help turn null into "null"
+                    String name = String.valueOf(iter.next());
+                    String val  = String.valueOf(iter.next());
+                    
+                    // handle empty-string values
+                    
+                    // technically, name should not ever be empty length (value can be),
+                    // but we don't want to do error handling, CompilerConfiguration.cfgDefine()
+                    // will do it for us later
+                    if (name.length() == 0)
+                    {
+                        name = "\"\"";
+                    }
+                    
+                    if (val.length() == 0)
+                    {
+                        val = "\"\"";
+                    }
+                    
+                    /* note '+=': defines from all flex-config.xmls will be collected (just '=' would
+                     * always ignore all but the most recent definitions), hopefully in a meaningful
+                     * order (flex-config, user-config, commandline) since we now allow re-definitions.
+                     */
+                    buffer.add(COMPILER_DEFINE + "+=" + name + "," + val);
+                }
+            }
+            else if (value instanceof ApplicationDomainsList)
+            {
+                ApplicationDomainsList valueList = (ApplicationDomainsList)value;
+                
+                if (valueList.size() == 0)
+                    buffer.add(key + "=");  // we should only ever come here for the first and only key.
+                else
+                    buffer.add(key);
+                
+                for (String[] adArgs : valueList) 
+                {
+                    for (int j = 0; j < adArgs.length; j++)
+                    {
+                        buffer.add(adArgs[j]);
+                    }
+                }
+            }
+			else if (value != null)
+			{
+				assert false;
+			}
+			else
+			{
+				// System.err.println("unprocessed compiler options: " + key + "=" + value);
+			}
+		}
+		
+		for (Iterator<String> i = more.keySet().iterator(); i.hasNext(); )
+		{
+			String key = (String) i.next();
+			Object value = more.get(key);
+
+			if (value instanceof String[])
+			{
+				if (!args.containsKey(key))
+				{
+					buffer.add(key + "+=" + toCommaSeparatedString((String[]) value));
+				}
+			}
+			/*
+			else if (LOAD_CONFIG.equals(key) && value instanceof File[])
+			{
+				if (!args.containsKey(key))
+				{
+					File[] a = merge(null, (File[]) more.get(key));
+					for (int j = 0, length = a == null ? 0 : a.length; j < length; j++)
+					{
+						if (a[j] != null)
+						{
+							buffer.add(key);
+							buffer.add(a[j].getPath());
+						}
+					}
+				}
+			}
+			*/
+			else if (value instanceof File[])
+			{
+				if (!args.containsKey(key))
+				{
+					buffer.add(key + "+=" + toCommaSeparatedString((File[]) value));
+				}
+			}
+			else if (value instanceof URL[])
+			{
+				if (!args.containsKey(key))
+				{
+					buffer.add(key + "+=" + toCommaSeparatedString((URL[]) value));
+				}
+			}
+			else if (value instanceof Map)
+			{
+				Map m = (Map) value;
+				for (Iterator j = m.keySet().iterator(); j.hasNext(); )
+				{
+					String k = (String) j.next();
+					Object v = m.get(k);
+					
+					if (v instanceof List)
+					{
+						Iterator it = ((List)v).iterator();
+						while (it.hasNext())
+						{
+							Object next = it.next();
+							if (next != null)
+                                buffer.add(key + "+=" + k + "," + next.toString());
+						}
+					}
+					else if (v != null)
+					{
+						assert false;
+					}
+				}
+			}
+			else if (value instanceof Map)
+			{
+				Map m = (Map) value;
+				for (Iterator j = m.keySet().iterator(); j.hasNext(); )
+				{
+					String k = (String) j.next();
+					Object v = m.get(k);
+					
+					if (v instanceof List)
+					{
+						Iterator it = ((List)v).iterator();
+						while (it.hasNext())
+						{
+							Object next = it.next();
+							if (next != null)
+                                buffer.add(key + "+=" + k + "," + next.toString());
+						}
+					}
+					else if (v != null)
+					{
+						assert false;
+					}
+				}
+			}
+			else if (value != null)
+			{
+				assert false;
+			}
+			else
+			{
+				// System.err.println("unprocessed compiler options: " + key + "=" + value);
+			}
+		}
+
+		for (int i = 0, length = extras == null ? 0 : extras.length; processExtras && i < length; i++)
+		{
+			if (extras[i] != null)
+			{
+				buffer.add(extras[i]);
+			}
+		}
+		
+		String[] options = new String[buffer.size()];
+		buffer.toArray(options);
+		
+		return options;
+	}
+	
+	/**
+	 * Enables accessibility in the application.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.accessible</code>.<p>
+	 * By default, this is disabled.
+	 * 
+	 * @param b boolean value
+	 */
+	public void enableAccessibility(boolean b)
+	{
+		args.put(COMPILER_ACCESSIBLE, b ? Boolean.TRUE : Boolean.FALSE);
+		linker_args.put(COMPILER_ACCESSIBLE, b ? Boolean.TRUE : Boolean.FALSE);
+		newLinkerOptionsAfterCompile.add(COMPILER_ACCESSIBLE);
+	}
+	
+	/**
+	 * Sets the ActionScript file encoding. The compiler will use this encoding to read
+	 * the ActionScript source files.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.actionscript-file-encoding</code>.<p>
+	 * By default, the encoding is <code>UTF-8</code>.
+	 * 
+	 * @param encoding charactere encoding, e.g. <code>UTF-8</code>, <code>Big5</code>
+	 */
+	public void setActionScriptFileEncoding(String encoding)
+	{
+		args.put(COMPILER_ACTIONSCRIPT_FILE_ENCODING, encoding);
+	}
+	
+	/**
+	 * Allows some source path directories to be subdirectories of the other.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.allow-source-path-overlap</code>.<p>
+	 * By default, this is disabled.<p>
+	 * 
+	 * In some J2EE settings, directory overlapping should be allowed. For example,
+	 * 
+	 * <pre>
+	 * wwwroot/MyAppRoot
+	 * wwwroot/WEB-INF/flex/source_path1
+	 * </pre>
+	 * 
+	 * @param b boolean value
+	 */
+	public void allowSourcePathOverlap(boolean b)
+	{
+		args.put(COMPILER_ALLOW_SOURCE_PATH_OVERLAP, b ? Boolean.TRUE : Boolean.FALSE);
+	}
+	
+	/**
+	 * Uses the ActionScript 3 class based object model for greater performance and better error reporting.
+	 * In the class based object model, most built-in functions are implemented as fixed methods of classes.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.as3</code>.<p>
+	 * By default, this is enabled.
+	 * 
+	 * @param b boolean value
+	 */
+	public void useActionScript3(boolean b)
+	{
+		args.put(COMPILER_AS3, b ? Boolean.TRUE : Boolean.FALSE);
+	}
+	
+	/**
+     * Sets the context root path so that the compiler can replace <code>{context.root}</code> tokens for
+     * service channel endpoints. This is equivalent to using the <code>compiler.context-root</code> option
+     * for the mxmlc or compc compilers.
+     * 
+     * <p>
+     * By default, this value is undefined.
+     * 
+     * @param path An instance of String.
+	 */
+	public void setContextRoot(String path)
+	{
+		args.put(COMPILER_CONTEXT_ROOT, path);
+	}
+
+	/**
+	 * Enables debugging in the application.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.debug</code> and <code>--debug-password</code>.<p>
+	 * By default, debug is <code>false</code> and the debug password is "".
+	 * 
+	 * @param b boolean value
+	 * @param debugPassword a password that is embedded in the application.
+	 */
+	public void enableDebugging(boolean b, String debugPassword)
+	{
+		args.put(COMPILER_DEBUG, b ? Boolean.TRUE : Boolean.FALSE);
+		args.put(DEBUG_PASSWORD, debugPassword);
+		
+		linker_args.put(COMPILER_DEBUG, b ? Boolean.TRUE : Boolean.FALSE);
+		linker_args.put(DEBUG_PASSWORD, debugPassword);
+		
+		newLinkerOptionsAfterCompile.add(COMPILER_DEBUG);
+		newLinkerOptionsAfterCompile.add(DEBUG_PASSWORD);
+	}
+
+	/**
+	 * Sets the location of the default CSS file.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.defaults-css-url</code>.
+	 * 
+	 * @param url an instance of <code>java.io.File</code>.
+	 */
+	public void setDefaultCSS(File url)
+	{
+		args.put(COMPILER_DEFAULTS_CSS_URL, url);
+	}
+	
+	/**
+	 * Uses the ECMAScript edition 3 prototype based object model to allow dynamic overriding
+	 * of prototype properties. In the prototype based object model built-in functions are
+	 * implemented as dynamic properties of prototype objects.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.es</code>.<p>
+	 * By default, this is disabled.
+	 * 
+	 * @param b boolean value
+	 */
+	public void useECMAScript(boolean b)
+	{
+		args.put(COMPILER_ES, b ? Boolean.TRUE : Boolean.FALSE);
+	}
+
+	/**
+	 * Sets the list of SWC files or directories to compile against but to omit from linking.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.external-library-path</code>.
+	 * 
+	 * @param paths <code>File.isDirectory()</code> should return <code>true</code> or <code>File</code> instances should represent SWC files.
+	 */
+	public void setExternalLibraryPath(File[] paths)
+	{
+		args.put(COMPILER_EXTERNAL_LIBRARY_PATH, paths);
+		more.remove(COMPILER_EXTERNAL_LIBRARY_PATH);
+	}
+
+	/**
+	 * Adds to the existing list of SWC files.
+	 * 
+	 * @see #setExternalLibraryPath(File[])
+	 * @param paths <code>File.isDirectory()</code> should return <code>true</code> or <code>File</code> instances should represent SWC files.
+	 */
+	public void addExternalLibraryPath(File[] paths)
+	{
+		addFiles(COMPILER_EXTERNAL_LIBRARY_PATH, paths);
+	}
+
+	/**
+	 * Sets a range to restrict the number of font glyphs embedded into the application.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.fonts.languages.language-range</code>.
+	 * For example,
+	 * 
+	 * <pre>
+	 * setFontLanguageRange("englishRange", "U+0020-U+007E");
+	 * </pre>
+	 * 
+	 * @param language language name
+	 * @param range a range of glyphs
+	 */
+    public void setFontLanguageRange(String language, String range)
+	{
+		if (!args.containsKey(COMPILER_FONTS_LANGUAGES_LANGUAGE_RANGE))
+		{
+			args.put(COMPILER_FONTS_LANGUAGES_LANGUAGE_RANGE, new TreeMap<String, String>());
+		}
+		
+        // I am ONLY doing this because we set it three lines above
+		@SuppressWarnings("unchecked")
+		Map<String, String> map = (Map<String, String>) args.get(COMPILER_FONTS_LANGUAGES_LANGUAGE_RANGE);
+		map.put(language, range);
+	}
+	
+	/**
+	 * Sets the location of the local font snapshot file. The file contains system font data produced by
+	 * <code>flex2.tools.FontSnapshot</code>. This is equivalent to using <code>mxmlc/compc --compiler.fonts.local-fonts-snapshot</code>.
+	 * 
+	 * @param file file
+	 */
+	public void setLocalFontSnapshot(File file)
+	{
+		args.put(COMPILER_FONTS_LOCAL_FONTS_SNAPSHOT, file);
+	}
+
+   /**
+     * Sets the local font file paths to be searched by the compiler.
+     * This is equivalent to using <code>mxmlc/compc --compiler.fonts.local-font-paths</code>.
+     * 
+     * @param paths an array of file paths.
+     */
+    public void setLocalFontPaths(String[] paths)
+    {
+        args.put(COMPILER_FONTS_LOCAL_FONT_PATHS, paths);
+        more.remove(COMPILER_FONTS_LOCAL_FONT_PATHS);
+    }
+
+    /**
+     * Adds local font paths to the existing local font path list.
+     * 
+     * @see #setLocalFontPaths(String[])
+     * @param paths an array of local font file paths.
+     */
+    public void addLocalFontPaths(String[] paths)
+    {
+        addStrings(COMPILER_FONTS_LOCAL_FONT_PATHS, paths);
+    }
+
+	/**
+	 * Sets the font managers used by the compiler.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.fonts.managers</code>.
+	 * 
+	 * @param classNames an array of Java class names.
+	 */
+	public void setFontManagers(String[] classNames)
+	{
+		args.put(COMPILER_FONTS_MANAGERS, classNames);
+		more.remove(COMPILER_FONTS_MANAGERS);
+	}
+	
+	/**
+	 * Adds font managers to the existing font manager list.
+	 * 
+	 * @see #setFontManagers(String[])
+	 * @param classNames an array of Java class names.
+	 */
+	public void addFontManagers(String[] classNames)
+	{
+		addStrings(COMPILER_FONTS_MANAGERS, classNames);
+	}
+	
+	/**
+	 * Sets the maximum number of embedded font faces that can be cached.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.fonts.max-cached-fonts</code>.
+	 * By default, it's 20.
+	 * 
+	 * @param size an integer
+	 */
+	public void setMaximumCachedFonts(int size)
+	{
+		if (size > 0)
+		{
+			args.put(COMPILER_FONTS_MAX_CACHED_FONTS, new Integer(size));
+		}
+	}
+	
+	/**
+	 * Sets the maximum number of character glyph outlines to cache for each font face.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.fonts.max-glyphs-per-face</code>.
+	 * By default, it's 1000.
+	 *  
+	 * @param size an integer
+	 */
+	public void setMaximumGlyphsPerFace(int size)
+	{
+		if (size > 0)
+		{
+			args.put(COMPILER_FONTS_MAX_GLYPHS_PER_FACE, new Integer(size));
+		}
+	}
+	
+	/**
+	 * Sets the compiler when it runs on a server without a display.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.headless-server</code>.
+	 * 
+	 * @param b boolean value
+	 */
+	public void useHeadlessServer(boolean b)
+	{
+		args.put(COMPILER_HEADLESS_SERVER, b ? Boolean.TRUE : Boolean.FALSE);
+	}
+	
+	/**
+	 * Sets the AS3 metadata the compiler should keep in the SWF.
+	 * This is equivalent to using <code>mxmlc --compiler.keep-as3-metadata</code>.
+	 * 
+	 * <p>
+	 * The default value is <code>{Bindable, Managed, ChangeEvent, NonCommittingChangeEvent, Transient}</code>.
+	 * 
+	 * @param md an array of AS3 metadata names
+	 */
+	public void setActionScriptMetadata(String[] md)
+	{
+		args.put(COMPILER_KEEP_AS3_METADATA, md);
+		more.remove(COMPILER_KEEP_AS3_METADATA);
+		
+		linker_args.put(COMPILER_KEEP_AS3_METADATA, md);
+		linker_more.remove(COMPILER_KEEP_AS3_METADATA);
+		
+		newLinkerOptionsAfterCompile.add(COMPILER_KEEP_AS3_METADATA);
+	}
+	
+	/**
+	 * Adds the list of AS3 metadata names to the existing list of AS3 metadata the compiler should
+	 * keep in the SWF.
+	 * 
+	 * @param md an array of AS3 metadata names
+	 */
+	public void addActionScriptMetadata(String[] md)
+	{
+		addStrings(COMPILER_KEEP_AS3_METADATA, md);
+		addStrings(linker_more, COMPILER_KEEP_AS3_METADATA, md);
+
+		newLinkerOptionsAfterCompile.add(COMPILER_KEEP_AS3_METADATA);
+	}
+
+	/**
+	 * Disables the pruning of unused type selectors.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.keep-all-type-selectors</code>.
+	 * By default, it is set to <code>false</code>.
+	 * 
+	 * @param b boolean value
+	 */
+	public void keepAllTypeSelectors(boolean b)
+	{
+		args.put(COMPILER_KEEP_ALL_TYPE_SELECTORS, b ? Boolean.TRUE : Boolean.FALSE);
+	}
+	
+	/**
+	 * Saves temporary source files generated during MXML compilation.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.keep-generated-actionscript</code>.
+	 * By default, it is set to <code>false</code>.
+	 * 
+	 * @param b boolean value
+	 */
+	public void keepCompilerGeneratedActionScript(boolean b)
+	{
+		args.put(COMPILER_KEEP_GENERATED_ACTIONSCRIPT, b ? Boolean.TRUE : Boolean.FALSE);
+	}
+
+	/**
+	 * Instructs the linker to keep a report of the content that is included in the application.
+	 * Callers may use <code>Report.writeLinkReport()</code> to retrieve the linker report.
+	 * 
+	 * @param b boolean value
+	 */
+	public void keepLinkReport(boolean b)
+	{
+		keepLinkReport = b;
+		newLinkerOptionsAfterCompile.add(LINK_REPORT);
+	}
+	
+	public boolean keepLinkReport()
+	{
+		return keepLinkReport;
+	}
+	
+	/**
+	 * Instructs the linker to keep a SWF size report.
+	 * Callers may use <code>Report.writeSizeReport()</code> to retrieve the size report.
+	 * 
+	 * @param b boolean value
+	 */
+	public void keepSizeReport(boolean b)
+	{
+		keepSizeReport = b;
+		newLinkerOptionsAfterCompile.add(SIZE_REPORT);
+	}
+	
+	public boolean keepSizeReport()
+	{
+		return keepSizeReport;
+	}
+	
+	/**
+	 * Instructs the compiler to keep a report of the compiler configuration settings.
+	 * Callers may use <code>Report.writeConfigurationReport()</code> to retrieve the configuration report.
+	 * 
+	 * @param b boolean value
+	 */
+	public void keepConfigurationReport(boolean b)
+	{
+		keepConfigurationReport = b;
+	}
+	
+	public boolean keepConfigurationReport()
+	{
+		return keepConfigurationReport;
+	}
+
+	
+	/**
+	 * Includes a list of libraries (SWCs) to completely include in the application
+	 * This is equivalent to using <code>mxmlc/compc --compiler.include-libraries</code>.
+	 * 
+	 * @param libraries an array of <code>java.io.File</code> (<code>File.isDirectory()</code> should return <code>true</code> or instances must represent SWC files).
+	 * @see #setIncludes(String[])
+	 * @see #setExterns(File[])
+	 * @see #setExterns(String[])
+	 * @see #setExternalLibraryPath(File[])
+	 */
+	public void includeLibraries(File[] libraries)
+	{
+		args.put(COMPILER_INCLUDE_LIBRARIES, libraries);
+	}
+
+    /**
+     * Sets a list of resource bundles to include in the swf.
+     * This is equivalent to using <code>mxmlc/compc --include-resource-bundle</code>.
+     * 
+     * @param bundles an array of <code>java.lang.String</code>
+    */
+    public void setIncludeResourceBundles(String[] bundles)
+    {
+        args.put(INCLUDE_RESOURCE_BUNDLES, bundles);        
+    }   
+
+    /**
+     * Adds a list of resource bundles to the existing list.
+     * 
+     * @see #setIncludeResourceBundles(String[])
+     * @param bundles an array of <code>java.lang.String</code>
+     */
+    public void addIncludeResourceBundles(String[] bundles)
+    {
+        addStrings(INCLUDE_RESOURCE_BUNDLES, bundles);
+    }
+    
+    /**
+	 * Sets a list of SWC files or directories that contain SWC files.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.library-path</code>.
+	 * 
+	 * @param paths an array of <code>File</code>. <code>File.isDirectory()</code> should return <code>true</code> or instances must represent SWC files.
+	 */
+	public void setLibraryPath(File[] paths)
+	{
+		args.put(COMPILER_LIBRARY_PATH, paths);
+		more.remove(COMPILER_LIBRARY_PATH);
+	}
+
+	/**
+	 * Adds a list of SWC files or directories to the default library path.
+	 * 
+	 * @param paths an array of <code>File</code>. <code>File.isDirectory()</code> should return <code>true</code> or instances must represent SWC files.
+	 * @see #setLibraryPath(File[])
+	 */
+	public void addLibraryPath(File[] paths)
+	{
+		addFiles(COMPILER_LIBRARY_PATH, paths);
+	}
+	
+	/**
+	 * Sets the locales that the compiler would use to replace <code>{locale}</code> tokens that appear in some configuration values.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.locale</code>.
+	 * For example,
+	 * 
+	 * <pre>
+	 * addSourcePath(new File[] { "locale/{locale}" });
+	 * addLocale(new String[] { "en_US" });
+	 * </pre>
+	 * 
+	 * The <code>locale/en_US</code> directory will be added to the source path.
+	 *
+	 * @param locale String
+	 * 
+	 * @since 3.0
+	 */
+	public void setLocale(String[] locales)
+	{
+		args.put(COMPILER_LOCALE, locales);
+	}
+	
+	/**
+	 * Sets the locale that the compiler would use to replace <code>{locale}</code> tokens that appear in some configuration values.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.locale</code> to set a single locale.
+	 * For example,
+	 * 
+	 * <pre>
+	 * addSourcePath(new File[] { "locale/{locale}" });
+	 * setLocale(Locale.US);
+	 * </pre>
+	 * 
+	 * The <code>locale/en_US</code> directory will be added to the source path.
+	 *
+	 * @param locale java.util.Locale
+	 * 
+	 * @deprecated As of 3.0, use setLocale(String[])
+	 */
+	public void setLocale(Locale locale)
+	{
+		setLocale(new String[] { locale.toString() });
+	}
+
+    /**
+     * Specifies a URI to associate with a manifest of components for use as
+     * MXML elements. This is equivalent to using:
+     * <code>mxmlc/compc --compiler.namespaces.namespace</code>.
+     * 
+     * @param namespaceURI a namespace URI
+     * @param manifest a component manifest file (XML)
+     */
+    public void setComponentManifest(String namespaceURI, File manifest)
+    {
+        List<File> manifests = new ArrayList<File>(2);
+        manifests.add(manifest);
+        setComponentManifests(namespaceURI, manifests);
+    }
+
+    /**
+     * Specifies a URI to associate with a list of potentially several manifests
+     * which map MXML elements to component implementations. This is equivalent
+     * to using: <code>mxmlc/compc --compiler.namespaces.namespace</code>.
+     * 
+     * @param namespaceURI a namespace URI
+     * @param manifests A List of component manifest files (XML)
+     */
+    public void setComponentManifests(String namespaceURI, List<File> manifests)
+    {
+        if (!more.containsKey(COMPILER_NAMESPACES_NAMESPACE))
+        {
+            more.put(COMPILER_NAMESPACES_NAMESPACE, new LinkedHashMap<String, List<File>>());
+        }
+
+        // I am ONLY doing this because we set it three lines above
+        @SuppressWarnings("unchecked")
+        Map<String, List<File>> map = (Map<String, List<File>>) more.get(COMPILER_NAMESPACES_NAMESPACE);
+        map.put(namespaceURI, manifests);
+    }
+
+	/**
+	 * Enables post-link optimization. This is equivalent to using <code>mxmlc/compc --compiler.optimize</code>.
+	 * Application sizes are usually smaller with this option enabled.
+	 * By default, it is set to <code>true</code>.
+	 * 
+	 * @param b boolean value
+	 */
+	public void optimize(boolean b)
+	{
+		args.put(COMPILER_OPTIMIZE, b ? Boolean.TRUE : Boolean.FALSE);
+		linker_args.put(COMPILER_OPTIMIZE, b ? Boolean.TRUE : Boolean.FALSE);
+		newLinkerOptionsAfterCompile.add(COMPILER_OPTIMIZE);
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	public void compress(boolean b)
+	{
+        args.put(COMPILER_COMPRESS, b ? Boolean.TRUE : Boolean.FALSE);
+        linker_args.put(COMPILER_COMPRESS, b ? Boolean.TRUE : Boolean.FALSE);
+        newLinkerOptionsAfterCompile.add(COMPILER_COMPRESS);	    
+	}
+
+	/**
+	 * Sets the location of the FDS service configuration file.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.services</code>
+	 * @param file file
+	 */
+	public void setServiceConfiguration(File file)
+	{
+		args.put(COMPILER_SERVICES, file);
+	}
+	
+	/**
+	 * Runs the ActionScript compiler in a mode that detects legal but potentially incorrect code.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.show-actionscript-warnings</code>.
+	 * By default, it is set to <code>true</code>.
+	 * 
+	 * @param b boolean value
+	 * @see #checkActionScriptWarning(int, boolean)
+	 */
+	public void showActionScriptWarnings(boolean b)
+	{
+		args.put(COMPILER_SHOW_ACTIONSCRIPT_WARNINGS, b ? Boolean.TRUE : Boolean.FALSE);
+	}
+	
+	/**
+	 * Toggles whether warnings generated from data binding code are displayed.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.show-binding-warnings</code>.
+	 * By default, it is set to <code>true</code>.
+	 * 
+	 * @param b boolean value
+	 */
+	public void showBindingWarnings(boolean b)
+	{
+		args.put(COMPILER_SHOW_BINDING_WARNINGS, b ? Boolean.TRUE : Boolean.FALSE);
+	}
+
+	/**
+	 * Toggles whether the use of deprecated APIs generates a warning.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.show-deprecation-warnings</code>.
+	 * By default, it is set to <code>true</code>.
+	 * 
+	 * @param b boolean value
+	 */
+	public void showDeprecationWarnings(boolean b)
+	{
+		args.put(COMPILER_SHOW_DEPRECATION_WARNINGS, b ? Boolean.TRUE : Boolean.FALSE);
+	}
+
+    /**
+     * Toggles whether warnings are displayed when an embedded font name shadows
+     * a device font name.
+     * This is equivalent to using <code>mxmlc/compc --compiler.show-shadowed-device-font-warnings</code>.
+     * By default, it is set to <code>true</code>.
+     * 
+     * @param b boolean value
+     */
+    public void showShadowedDeviceFontWarnings(boolean b)
+    {
+        args.put(COMPILER_SHOW_SHADOWED_DEVICE_FONT_WARNINGS, b ? Boolean.TRUE : Boolean.FALSE);
+    }
+
+	/**
+	 * Toggles whether warnings generated from unused type selectors are displayed.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.show-unused-type-selector-warnings</code>.
+	 * By default, it is set to <code>true</code>.
+	 * 
+	 * @param b boolean value
+	 */
+	public void showUnusedTypeSelectorWarnings(boolean b)
+	{
+		args.put(COMPILER_SHOW_UNUSED_TYPE_SELECTOR_WARNINGS, b ? Boolean.TRUE : Boolean.FALSE);
+	}
+
+	/**
+	 * Sets a list of path elements that form the roots of ActionScript class hierarchies.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.source-path</code>.
+	 * 
+	 * @param paths an array of <code>java.io.File</code> (<code>File.isDirectory()</code> must return <code>true</code>).
+	 */
+	public void setSourcePath(File[] paths)
+	{
+		args.put(COMPILER_SOURCE_PATH, paths);
+		more.remove(COMPILER_SOURCE_PATH);
+	}
+
+	/**
+	 * Adds a list of path elements to the existing source path list.
+	 * 
+	 * @param paths an array of <code>java.io.File</code> (<code>File.isDirectory()</code> must return <code>true</code>).
+	 * @see #setSourcePath(File[])
+	 */
+	public void addSourcePath(File[] paths)
+	{
+		addFiles(COMPILER_SOURCE_PATH, paths);
+	}
+	
+	/**
+	 * Runs the ActionScript compiler in strict error checking mode.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.strict</code>.
+	 * By default, it is set to <code>true</code>.
+	 * 
+	 * @param b boolean value
+	 */
+	public void enableStrictChecking(boolean b)
+	{
+		args.put(COMPILER_STRICT, b ? Boolean.TRUE : Boolean.FALSE);
+	}
+	
+	/**
+	 * Sets a list of CSS or SWC files to apply as a theme.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.theme</code>.
+	 * 
+	 * @param files an array of <code>java.io.File</code>
+	 */
+	public void setTheme(File[] files)
+	{
+		args.put(COMPILER_THEME, files);
+		more.remove(COMPILER_THEME);
+	}
+
+	/**
+	 * Adds a list of CSS or SWC files to the existing list of theme files.
+	 * 
+	 * @param files an array of <code>java.io.File</code>
+	 * @see #setTheme(File[])
+	 */
+	public void addTheme(File[] files)
+	{
+		addFiles(COMPILER_THEME, files);
+	}
+    
+	/**
+	 * Determines whether resources bundles are included in the application.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.use-resource-bundle-metadata</code>.
+	 * By default, it is set to <code>true</code>.
+	 * 
+	 * @param b boolean value
+	 */
+	public void useResourceBundleMetaData(boolean b)
+	{
+		args.put(COMPILER_USE_RESOURCE_BUNDLE_METADATA, b ? Boolean.TRUE : Boolean.FALSE);
+	}
+	
+	/**
+	 * Generates bytecodes that include line numbers. When a run-time error occurs,
+	 * the stacktrace shows these line numbers. Enabling this option generates larger SWF files.
+	 * This is equivalent to using <code>mxmlc/compc --compiler.verbose-stacktraces</code>.
+	 * By default, it is set to <code>false</code>.
+	 * 
+	 * @param b boolean value
+	 */
+	public void enableVerboseStacktraces(boolean b)
+	{
+		args.put(COMPILER_VERBOSE_STACKTRACES, b ? Boolean.TRUE : Boolean.FALSE);
+		linker_args.put(COMPILER_VERBOSE_STACKTRACES, b ? Boolean.TRUE : Boolean.FALSE);
+		newLinkerOptionsAfterCompile.add(COMPILER_VERBOSE_STACKTRACES);
+	}
+	 
+	/**
+	 * Enables FlashType for embedded fonts, which provides greater clarity for small fonts.
+	 * This is equilvalent to using <code>mxmlc/compc --compiler.fonts.flash-type</code>.
+	 * By default, it is set to <code>true</code>.
+	 * 
+	 * @param b boolean value
+	 */
+	public void enableFlashType(boolean b)
+	{
+		args.put(COMPILER_FONTS_FLASH_TYPE, b ? Boolean.TRUE : Boolean.FALSE);
+	}
+
+	/**
+	 * Enables advanced anti-aliasing for embedded fonts, which provides greater clarity for small fonts.
+	 * This is equilvalent to using <code>mxmlc/compc --compiler.fonts.advanced-anti-aliasing</code>.
+	 * By default, it is set to <code>false</code>.
+	 * 
+	 * @param b boolean value
+	 */
+	public void enableAdvancedAntiAliasing(boolean b)
+	{
+		args.put(COMPILER_FONTS_ADVANCED_ANTI_ALIASING, b ? Boolean.TRUE : Boolean.FALSE);
+	}
+
+    /**
+     * Enables the removal of RSLs associated with libraries
+     * that are not used by an application.
+     * This is equivalent to using the
+     * <code>remove-unused-rsls</code> option of the mxmlc compiler.
+     * 
+     * <p>
+     * The default value is <code>false</code>.
+     * 
+     * @param b Boolean value that enables or disables the removal.
+     *    
+     * @since 4.5
+     */
+    public void removeUnusedRuntimeSharedLibraryPaths(boolean b)
+    {
+        args.put(REMOVE_UNUSED_RSLS, b ? Boolean.TRUE : Boolean.FALSE);
+    }
+	
+	/**
+	 * Enables checking of ActionScript warnings. They are:
+	 * 
+	 * <pre>
+	 * --compiler.warn-array-tostring-changes
+	 * --compiler.warn-assignment-within-conditional
+	 * --compiler.warn-bad-array-cast
+	 * --compiler.warn-bad-bool-assignment
+	 * --compiler.warn-bad-date-cast
+	 * --compiler.warn-bad-es3-type-method
+	 * --compiler.warn-bad-es3-type-prop
+	 * --compiler.warn-bad-nan-comparison
+	 * --compiler.warn-bad-null-assignment
+	 * --compiler.warn-bad-null-comparison
+	 * --compiler.warn-bad-undefined-comparison
+	 * --compiler.warn-boolean-constructor-with-no-args
+	 * --compiler.warn-changes-in-resolve
+	 * --compiler.warn-class-is-sealed
+	 * --compiler.warn-const-not-initialized
+	 * --compiler.warn-constructor-returns-value
+	 * --compiler.warn-deprecated-event-handler-error
+	 * --compiler.warn-deprecated-function-error
+	 * --compiler.warn-deprecated-property-error
+	 * --compiler.warn-duplicate-argument-names
+	 * --compiler.warn-duplicate-variable-def
+	 * --compiler.warn-for-var-in-changes
+	 * --compiler.warn-import-hides-class
+	 * --compiler.warn-instance-of-changes
+	 * --compiler.warn-internal-error
+	 * --compiler.warn-level-not-supported
+	 * --compiler.warn-missing-namespace-decl
+	 * --compiler.warn-negative-uint-literal
+	 * --compiler.warn-no-constructor
+	 * --compiler.warn-no-explicit-super-call-in-constructor
+	 * --compiler.warn-no-type-decl
+	 * --compiler.warn-number-from-string-changes
+	 * --compiler.warn-scoping-change-in-this
+	 * --compiler.warn-slow-text-field-addition
+	 * --compiler.warn-unlikely-function-value
+	 * --compiler.warn-xml-class-has-changed
+	 * </pre>
+	 * 
+	 * @param warningCode warning code
+	 * @param b boolean value
+	 * @see #WARN_ARRAY_TOSTRING_CHANGES
+	 * @see #WARN_ASSIGNMENT_WITHIN_CONDITIONAL
+	 * @see #WARN_BAD_ARRAY_CAST
+	 * @see #WARN_BAD_BOOLEAN_ASSIGNMENT
+	 * @see #WARN_BAD_DATE_CAST
+	 * @see #WARN_BAD_ES3_TYPE_METHOD
+	 * @see #WARN_BAD_ES3_TYPE_PROP
+	 * @see #WARN_BAD_NAN_COMPARISON
+	 * @see #WARN_BAD_NULL_ASSIGNMENT
+	 * @see #WARN_BAD_NULL_COMPARISON
+	 * @see #WARN_BAD_UNDEFINED_COMPARISON
+	 * @see #WARN_BOOLEAN_CONSTRUCTOR_WITH_NO_ARGS
+	 * @see #WARN_CHANGES_IN_RESOLVE
+	 * @see #WARN_CLASS_IS_SEALED
+	 * @see #WARN_CONST_NOT_INITIALIZED
+	 * @see #WARN_CONSTRUCTOR_RETURNS_VALUE
+	 * @see #WARN_DEPRECATED_EVENT_HANDLER_ERROR
+	 * @see #WARN_DEPRECATED_FUNCTION_ERROR
+	 * @see #WARN_DEPRECATED_PROPERTY_ERROR
+	 * @see #WARN_DUPLICATE_ARGUMENT_NAMES
+	 * @see #WARN_DUPLICATE_VARIABLE_DEF
+	 * @see #WARN_FOR_VAR_IN_CHANGES
+	 * @see #WARN_IMPORT_HIDES_CLASS
+	 * @see #WARN_INSTANCEOF_CHANGES
+	 * @see #WARN_INTERNAL_ERROR
+	 * @see #WARN_LEVEL_NOT_SUPPORTED
+	 * @see #WARN_MISSING_NAMESPACE_DECL
+	 * @see #WARN_NEGATIVE_UINT_LITERAL
+	 * @see #WARN_NO_CONSTRUCTOR
+	 * @see #WARN_NO_EXPLICIT_SUPER_CALL_IN_CONSTRUCTOR
+	 * @see #WARN_NO_TYPE_DECL
+	 * @see #WARN_NUMBER_FROM_STRING_CHANGES
+	 * @see #WARN_SCOPING_CHANGE_IN_THIS
+	 * @see #WARN_SLOW_TEXTFIELD_ADDITION
+	 * @see #WARN_UNLIKELY_FUNCTION_VALUE
+	 * @see #WARN_XML_CLASS_HAS_CHANGED
+	 */
+	public void checkActionScriptWarning(int warningCode, boolean b)
+	{
+		String key = null;
+		
+		switch (warningCode)
+		{
+		case WARN_ARRAY_TOSTRING_CHANGES:
+			key = COMPILER_WARN_ARRAY_TOSTRING_CHANGES;
+			break;
+		case WARN_ASSIGNMENT_WITHIN_CONDITIONAL:
+			key = COMPILER_WARN_ASSIGNMENT_WITHIN_CONDITIONAL;
+			break;
+		case WARN_BAD_ARRAY_CAST:
+			key = COMPILER_WARN_BAD_ARRAY_CAST;
+			break;
+		case WARN_BAD_BOOLEAN_ASSIGNMENT:
+			key = COMPILER_WARN_BAD_BOOL_ASSIGNMENT;
+			break;
+		case WARN_BAD_DATE_CAST:
+			key = COMPILER_WARN_BAD_DATE_CAST;
+			break;
+		case WARN_BAD_ES3_TYPE_METHOD:
+			key = COMPILER_WARN_BAD_ES3_TYPE_METHOD;
+			break;
+		case WARN_BAD_ES3_TYPE_PROP:
+			key = COMPILER_WARN_BAD_ES3_TYPE_PROP;
+			break;
+		case WARN_BAD_NAN_COMPARISON:
+			key = COMPILER_WARN_BAD_NAN_COMPARISON;
+			break;
+		case WARN_BAD_NULL_ASSIGNMENT:
+			key = COMPILER_WARN_BAD_NULL_ASSIGNMENT;
+			break;
+		case WARN_BAD_NULL_COMPARISON:
+			key = COMPILER_WARN_BAD_NULL_COMPARISON;
+			break;
+		case WARN_BAD_UNDEFINED_COMPARISON:
+			key = COMPILER_WARN_BAD_UNDEFINED_COMPARISON;
+			break;
+		case WARN_BOOLEAN_CONSTRUCTOR_WITH_NO_ARGS:
+			key = COMPILER_WARN_BOOLEAN_CONSTRUCTOR_WITH_NO_ARGS;
+			break;
+		case WARN_CHANGES_IN_RESOLVE:
+			key = COMPILER_WARN_CHANGES_IN_RESOLVE;
+			break;
+		case WARN_CLASS_IS_SEALED:
+			key = COMPILER_WARN_CLASS_IS_SEALED;
+			break;
+		case WARN_CONST_NOT_INITIALIZED:
+			key = COMPILER_WARN_CONST_NOT_INITIALIZED;
+			break;
+		case WARN_CONSTRUCTOR_RETURNS_VALUE:
+			key = COMPILER_WARN_CONSTRUCTOR_RETURNS_VALUE;
+			break;
+		case WARN_DEPRECATED_EVENT_HANDLER_ERROR:
+			key = COMPILER_WARN_DEPRECATED_EVENT_HANDLER_ERROR;
+			break;
+		case WARN_DEPRECATED_FUNCTION_ERROR:
+			key = COMPILER_WARN_DEPRECATED_FUNCTION_ERROR;
+			break;
+		case WARN_DEPRECATED_PROPERTY_ERROR:
+			key = COMPILER_WARN_DEPRECATED_PROPERTY_ERROR;
+			break;
+		case WARN_DUPLICATE_ARGUMENT_NAMES:
+			key = COMPILER_WARN_DUPLICATE_ARGUMENT_NAMES;
+			break;
+		case WARN_DUPLICATE_VARIABLE_DEF:
+			key = COMPILER_WARN_DUPLICATE_VARIABLE_DEF;
+			break;
+		case WARN_FOR_VAR_IN_CHANGES:
+			key = COMPILER_WARN_FOR_VAR_IN_CHANGES;
+			break;
+		case WARN_IMPORT_HIDES_CLASS:
+			key = COMPILER_WARN_IMPORT_HIDES_CLASS;
+			break;
+		case WARN_INSTANCEOF_CHANGES:
+			key = COMPILER_WARN_INSTANCE_OF_CHANGES;
+			break;
+		case WARN_INTERNAL_ERROR:
+			key = COMPILER_WARN_INTERNAL_ERROR;
+			break;
+		case WARN_LEVEL_NOT_SUPPORTED:
+			key = COMPILER_WARN_LEVEL_NOT_SUPPORTED;
+			break;
+		case WARN_MISSING_NAMESPACE_DECL:
+			key = COMPILER_WARN_MISSING_NAMESPACE_DECL;
+			break;
+		case WARN_NEGATIVE_UINT_LITERAL:
+			key = COMPILER_WARN_NEGATIVE_UINT_LITERAL;
+			break;
+		case WARN_NO_CONSTRUCTOR:
+			key = COMPILER_WARN_NO_CONSTRUCTOR;
+			break;
+		case WARN_NO_EXPLICIT_SUPER_CALL_IN_CONSTRUCTOR:
+			key = COMPILER_WARN_NO_EXPLICIT_SUPER_CALL_IN_CONSTRUCTOR;
+			break;
+		case WARN_NO_TYPE_DECL:
+			key = COMPILER_WARN_NO_TYPE_DECL;
+			break;
+		case WARN_NUMBER_FROM_STRING_CHANGES:
+			key = COMPILER_WARN_NUMBER_FROM_STRING_CHANGES;
+			break;
+		case WARN_SCOPING_CHANGE_IN_THIS:
+			key = COMPILER_WARN_SCOPING_CHANGE_IN_THIS;
+			break;
+		case WARN_SLOW_TEXTFIELD_ADDITION:
+			key = COMPILER_WARN_SLOW_TEXT_FIELD_ADDITION;
+			break;
+		case WARN_UNLIKELY_FUNCTION_VALUE:
+			key = COMPILER_WARN_UNLIKELY_FUNCTION_VALUE;
+			break;
+		case WARN_XML_CLASS_HAS_CHANGED:
+			key = COMPILER_WARN_XML_CLASS_HAS_CHANGED;
+			break;
+		}
+		
+		if (key != null)
+		{
+			args.put(key, b ? Boolean.TRUE : Boolean.FALSE);
+		}
+	}
+	
+	/**
+	 * Sets the default background color (may be overridden by the application code).
+	 * This is equivalent to using <code>mxmlc/compc --default-background-color</code>.
+	 * The default value is <code>0x869CA7</code>.
+	 * 
+	 * @param color RGB value
+	 */
+	public void setDefaultBackgroundColor(int color)
+	{
+		args.put(DEFAULT_BACKGROUND_COLOR, new Integer(color));
+		linker_args.put(DEFAULT_BACKGROUND_COLOR, new Integer(color));
+		newLinkerOptionsAfterCompile.add(DEFAULT_BACKGROUND_COLOR);
+	}
+	
+	/**
+	 * Sets the default frame rate to be used in the application.
+	 * This is equivalent to using <code>mxmlc/compc --default-frame-rate</code>.
+	 * The default value is <code>24</code>.
+	 * 
+	 * @param rate frames per second
+	 */
+	public void setDefaultFrameRate(int rate)
+	{
+		args.put(DEFAULT_FRAME_RATE, new Integer(rate));
+		linker_args.put(DEFAULT_FRAME_RATE, new Integer(rate));
+		newLinkerOptionsAfterCompile.add(DEFAULT_FRAME_RATE);
+	}
+	
+	/**
+	 * Sets the default script execution limits (may be overridden by root attributes).
+	 * This is equivalent to using <code>mxmlc/compc --default-script-limits</code>.
+	 * The default maximum recursion depth is <code>1000</code>.
+	 * The default maximum execution time is <code>60</code>.
+	 * 
+	 * @param maxRecursionDepth recursion depth
+	 * @param maxExecutionTime execution time in seconds. 
+	 */
+	public void setDefaultScriptLimits(int maxRecursionDepth, int maxExecutionTime)
+	{
+		args.put(DEFAULT_SCRIPT_LIMITS, new int[] { maxRecursionDepth, maxExecutionTime });
+		linker_args.put(DEFAULT_SCRIPT_LIMITS, new int[] { maxRecursionDepth, maxExecutionTime });
+		newLinkerOptionsAfterCompile.add(DEFAULT_SCRIPT_LIMITS);
+	}
+	
+	/**
+	 * Sets the default window size.
+	 * This is equivalent to using <code>mxmlc/compc --default-size</code>.
+	 * The default width is <code>500</code>.
+	 * The default height is <code>375</code>.
+	 * 
+	 * @param width width in pixels
+	 * @param height height in pixels
+	 */
+	public void setDefaultSize(int width, int height)
+	{
+		args.put(DEFAULT_SIZE, new int[] { width, height });
+		linker_args.put(DEFAULT_SIZE, new int[] { width, height });
+		newLinkerOptionsAfterCompile.add(DEFAULT_SIZE);
+	}
+	
+	/**
+	 * Sets a list of definitions to omit from linking when building an application.
+	 * This is equivalent to using <code>mxmlc/compc --externs</code>.
+	 * 
+	 * @param definitions An array of definitions (e.g. classes, functions, variables, namespaces, etc.)
+	 */
+	public void setExterns(String[] definitions)
+	{
+		args.put(EXTERNS, definitions);
+		more.remove(EXTERNS);
+		linker_args.put(EXTERNS, definitions);
+		linker_more.remove(EXTERNS);
+		newLinkerOptionsAfterCompile.add(EXTERNS);
+	}
+	
+	/**
+	 * Adds a list of definitions to the existing list of definitions.
+	 *
+	 * @see #setExterns(File[])
+	 * @see #setExterns(String[])
+	 * @param definitions an array of definitions (e.g. classes, functions, variables, namespaces, etc.)
+	 */
+	public void addExterns(String[] definitions)
+	{
+		addStrings(EXTERNS, definitions);
+		addStrings(linker_more, EXTERNS, definitions);
+		newLinkerOptionsAfterCompile.add(EXTERNS);
+	}
+
+	/**
+	 * Loads a file containing configuration options. The file format follows the format of <code>flex-config.xml</code>.
+	 * This is equivalent to using <code>mxmlc/compc --load-config</code>.
+	 * 
+	 * @param file an instance of <code>java.io.File</code>
+	 */
+	public void setConfiguration(File file)
+	{
+		args.put(LOAD_CONFIG, new File[] {file});
+		more.remove(LOAD_CONFIG);
+	}
+	
+	/**
+	 * Adds a file to the existing list of configuration files.
+	 * 
+	 * @see #setConfiguration(File)
+	 * @param file a configuration file
+	 */
+	public void addConfiguration(File file)
+	{
+		addFiles(LOAD_CONFIG, new File[] {file});
+	}
+
+	/**
+	 * Sets the configuration parameters. The input should be valid <code>mxmlc/compc</code> command-line arguments.<p>
+	 * 
+	 * @param args <code>mxmlc/compc</code> command-line arguments
+	 */
+	public void setConfiguration(String[] args)
+	{
+		extras = args;
+	}
+	
+	/**
+	 * Sets a list of definitions to omit from linking when building an application.
+	 * This is equivalent to using <code>mxmlc/compc --load-externs</code>.
+	 * This option is similar to <code>setExterns(String[])</code>. The following is an example of
+	 * the file format:
+	 * 
+	 * <pre>
+	 * &lt;script>
+	 *     &lt;!-- use 'dep', 'pre' or 'dep' to specify a definition to be omitted from linking. -->
+	 *     &lt;def id="mx.skins:ProgrammaticSkin"/>
+	 *     &lt;pre id="mx.core:IFlexDisplayObject"/>
+	 *     &lt;dep id="String"/>
+	 * &lt;/script>
+	 * </pre>
+	 * 
+	 * @param files an array of <code>java.io.File</code>
+	 */
+	public void setExterns(File[] files)
+	{
+		args.put(LOAD_EXTERNS, files);
+		more.remove(LOAD_EXTERNS);
+		linker_args.put(LOAD_EXTERNS, files);
+		linker_more.remove(LOAD_EXTERNS);
+		newLinkerOptionsAfterCompile.add(LOAD_EXTERNS);
+	}
+	
+	/**
+	 * Adds a list of files to the existing list of definitions to be omitted from linking.
+	 * 
+	 * @see #setExterns(File[])
+	 * @see #setExterns(String[])
+	 * @param files an array of <code>java.io.File</code>.
+	 */
+	public void addExterns(File[] files)
+	{
+		addFiles(LOAD_EXTERNS, files);
+		addFiles(linker_more, LOAD_EXTERNS, files);
+		newLinkerOptionsAfterCompile.add(LOAD_EXTERNS);
+	}
+
+	/**
+	 * Sets a SWF frame label with a sequence of classnames that will be linked onto the frame.
+	 * This is equivalent to using <code>mxmlc/compc --frames.frame</code>.
+	 * 
+	 * @param label A string
+	 * @param classNames an array of class names
+	 */
+	public void setFrameLabel(String label, String[] classNames)
+	{
+		if (!args.containsKey(FRAMES_FRAME))
+		{
+			args.put(FRAMES_FRAME, new TreeMap<String, String[]>());
+		}
+		
+        // I am ONLY doing this because we set it three lines above
+        @SuppressWarnings("unchecked")
+		Map<String, String[]> map = (Map<String, String[]>) args.get(FRAMES_FRAME);
+		map.put(label, classNames);
+
+		if (!linker_args.containsKey(FRAMES_FRAME))
+		{
+			linker_args.put(FRAMES_FRAME, new TreeMap());
+		}
+		
+        // I am ONLY doing this because we set it three lines above
+        @SuppressWarnings("unchecked")
+		Map<String, String[]> map2 = (Map<String, String[]>) linker_args.get(FRAMES_FRAME);
+		map2.put(label, classNames);
+		
+		newLinkerOptionsAfterCompile.add(FRAMES_FRAME);
+	}
+	
+	/**
+	 * Sets a list of definitions to always link in when building an application.
+	 * This is equivalent to using <code>mxmlc/compc --includes</code>.
+	 * 
+	 * @param definitions an array of definitions (e.g. classes, functions, variables, namespaces, etc).
+	 */
+	public void setIncludes(String[] definitions)
+	{
+		args.put(INCLUDES, definitions);
+		more.remove(INCLUDES);
+		linker_args.put(INCLUDES, definitions);
+		linker_more.remove(INCLUDES);
+		newLinkerOptionsAfterCompile.add(INCLUDES);
+	}
+	
+	/**
+	 * Adds a list of definitions to the existing list of definitions.
+	 *
+	 * @see #setIncludes(String[])
+	 * @param definitions an array of definitions (e.g. classes, functions, variables, namespaces, etc.)
+	 */
+	public void addIncludes(String[] definitions)
+	{
+		addStrings(INCLUDES, definitions);
+		addStrings(linker_more, INCLUDES, definitions);
+		newLinkerOptionsAfterCompile.add(INCLUDES);
+	}
+	
+	/**
+	 * Specifies the licenses that the compiler has to validate before compiling.
+	 * This is equivalent to using <code>mxmlc/compc --licenses.license</code>
+	 * 
+	 * @param productName a string
+	 * @param serialNumber a serial number
+	 */
+	public void setLicense(String productName, String serialNumber)
+	{
+		if (!args.containsKey(LICENSES_LICENSE))
+		{
+			args.put(LICENSES_LICENSE, new TreeMap<String, String>());
+		}
+		
+        // I am ONLY doing this because we set it three lines above
+        @SuppressWarnings("unchecked")
+		Map<String, String> map = (Map<String, String>) args.get(LICENSES_LICENSE);
+		map.put(productName, serialNumber);		
+	}
+
+	/**
+	 * Sets the metadata section of the application SWF. This option is equivalent to using the following <code>mxmlc/compc</code>
+	 * command-line options:
+	 * 
+	 * <pre>
+	 * --metadata.contributor
+	 * --metadata.creator
+	 * --metadata.date
+	 * --metadata.description
+	 * --metadata.language
+	 * --metadata.localized-description
+	 * --metadata.localized-title
+	 * --metadata.publisher
+	 * --metadata.title
+	 * </pre>
+	 * 
+	 * The valid fields and types of value are specified below:
+	 * 
+	 * <pre>
+	 * CONTRIBUTOR      java.lang.String
+	 * CREATOR          java.lang.String
+	 * DATE             java.util.Date
+	 * DESCRIPTION      java.util.Map<String, String>
+	 * TITLE            java.util.Map<String, String>
+	 * LANGUAGE         java.lang.String
+	 * PUBLISHER        java.lang.String
+	 * </pre>
+	 * 
+	 * For example,
+	 * 
+	 * <pre>
+	 * Map titles = new HashMap();
+	 * titles.put("EN", "Adobe Flex 2 Application");
+	 * 
+	 * Map descriptions = new HashMap();
+	 * descriptions.put("EN", "http://www.adobe.com/products/flex");
+	 * 
+	 * setSWFMetaData(Configuration.LANGUAGE, "EN");
+	 * setSWFMetaData(Configuration.TITLE, titles);
+	 * setSWFMetaData(Configuration.DESCRIPTION, descriptions);
+	 * </pre>
+	 * 
+	 * @param field CONTRIBUTOR, CREATOR, DATE, DESCRIPTION, TITLE, LANGUAGE, PUBLISHER
+	 * @param value String, Date or Map
+	 * @see #CONTRIBUTOR
+	 * @see #CREATOR
+	 * @see #DATE
+	 * @see #DESCRIPTION
+	 * @see #TITLE
+	 * @see #LANGUAGE
+	 * @see #PUBLISHER
+	 */
+	public void setSWFMetaData(int field, Object value)
+	{
+		switch (field)
+		{
+		case CONTRIBUTOR:
+			args.put(METADATA_CONTRIBUTOR, value);
+			break;
+		case CREATOR:
+			args.put(METADATA_CREATOR, value);
+			break;
+		case DATE:
+			args.put(METADATA_DATE, value);
+			break;
+		case DESCRIPTION:
+			args.put(METADATA_LOCALIZED_DESCRIPTION, value);
+			break;
+		case TITLE:
+			args.put(METADATA_LOCALIZED_TITLE, value);
+			break;
+		case LANGUAGE:
+			args.put(METADATA_LANGUAGE, value);
+			break;
+		case PUBLISHER:
+			args.put(METADATA_PUBLISHER, value);
+			break;
+		}
+
+		switch (field)
+		{
+		case CONTRIBUTOR:
+			linker_args.put(METADATA_CONTRIBUTOR, value);
+			break;
+		case CREATOR:
+			linker_args.put(METADATA_CREATOR, value);
+			break;
+		case DATE:
+			linker_args.put(METADATA_DATE, value);
+			break;
+		case DESCRIPTION:
+			linker_args.put(METADATA_LOCALIZED_DESCRIPTION, value);
+			break;
+		case TITLE:
+			linker_args.put(METADATA_LOCALIZED_TITLE, value);
+			break;
+		case LANGUAGE:
+			linker_args.put(METADATA_LANGUAGE, value);
+			break;
+		case PUBLISHER:
+			linker_args.put(METADATA_PUBLISHER, value);
+			break;
+		}
+		
+		newLinkerOptionsAfterCompile.add(METADATA_CONTRIBUTOR);
+		newLinkerOptionsAfterCompile.add(METADATA_CREATOR);
+		newLinkerOptionsAfterCompile.add(METADATA_DATE);
+		newLinkerOptionsAfterCompile.add(METADATA_LOCALIZED_DESCRIPTION);
+		newLinkerOptionsAfterCompile.add(METADATA_LOCALIZED_TITLE);
+		newLinkerOptionsAfterCompile.add(METADATA_LANGUAGE);
+		newLinkerOptionsAfterCompile.add(METADATA_PUBLISHER);
+		
+		args.remove(RAW_METADATA);
+		linker_args.remove(RAW_METADATA);
+		newLinkerOptionsAfterCompile.remove(RAW_METADATA);
+	}
+
+	/**
+	 * Sets the path to the Flash Player executable when building a projector. For example,
+	 * 
+	 * <pre>
+	 * setProjector(new File("C:/.../SAFlashPlayer.exe")) {}
+	 * </pre>
+	 * 
+	 * This is equivalent to using <code>mxmlc/compc --projector</code>.
+	 * 
+	 * @param file the Flash Player executable.
+	 */
+	public void setProjector(File file)
+	{
+		args.put(PROJECTOR, file);
+	}
+	
+	/**
+	 * Sets the metadata section of the application SWF.
+	 * This is equivalent to using <code>mxmlc/compc --raw-metadata</code>.
+	 * This option overrides everything set by the <code>setSWFMetaData</code> method.
+	 * 
+	 * @see #setSWFMetaData(int, Object)
+	 * @param xml a well-formed XML fragment
+	 */
+	public void setSWFMetaData(String xml)
+	{
+		args.put(RAW_METADATA, xml);
+		linker_args.put(RAW_METADATA, xml);
+		
+		args.remove(METADATA_CONTRIBUTOR);
+		args.remove(METADATA_CREATOR);
+		args.remove(METADATA_DATE);
+		args.remove(METADATA_LOCALIZED_DESCRIPTION);
+		args.remove(METADATA_LOCALIZED_TITLE);
+		args.remove(METADATA_LANGUAGE);
+		args.remove(METADATA_PUBLISHER);
+
+		linker_args.remove(METADATA_CONTRIBUTOR);
+		linker_args.remove(METADATA_CREATOR);
+		linker_args.remove(METADATA_DATE);
+		linker_args.remove(METADATA_LOCALIZED_DESCRIPTION);
+		linker_args.remove(METADATA_LOCALIZED_TITLE);
+		linker_args.remove(METADATA_LANGUAGE);
+		linker_args.remove(METADATA_PUBLISHER);
+		
+		newLinkerOptionsAfterCompile.remove(METADATA_CONTRIBUTOR);
+		newLinkerOptionsAfterCompile.remove(METADATA_CREATOR);
+		newLinkerOptionsAfterCompile.remove(METADATA_DATE);
+		newLinkerOptionsAfterCompile.remove(METADATA_LOCALIZED_DESCRIPTION);
+		newLinkerOptionsAfterCompile.remove(METADATA_LOCALIZED_TITLE);
+		newLinkerOptionsAfterCompile.remove(METADATA_LANGUAGE);
+		newLinkerOptionsAfterCompile.remove(METADATA_PUBLISHER);
+	}
+	
+	/**
+	 * Sets a list of runtime shared library URLs to be loaded before the application starts.
+	 * This is equivalent to using <code>mxmlc/compc --runtime-shared-libraries</code>.
+	 * 
+	 * @param libraries an array of <code>java.lang.String</code>.
+	 */
+	public void setRuntimeSharedLibraries(String[] libraries)
+	{
+		args.put(RUNTIME_SHARED_LIBRARIES, libraries);
+		more.remove(RUNTIME_SHARED_LIBRARIES);
+	}
+
+	/**
+	 * Adds a list of runtime shared library URLs to the existing list.
+	 * 
+	 * @see #setRuntimeSharedLibraries(String[])
+	 * @param libraries an array of <code>java.lang.String</code>
+	 */
+	public void addRuntimeSharedLibraries(String[] libraries)
+	{
+		addStrings(RUNTIME_SHARED_LIBRARIES, libraries);
+	}
+
+	/**
+	 * Toggles whether the application SWF is flagged for access to network resources.
+	 * This is equivalent to using <code>mxmlc/compc --use-network</code>.
+	 * By default, it is set to <code>true</code>.
+	 * 
+	 * @param b boolean value
+	 */
+	public void useNetwork(boolean b)
+	{
+		args.put(USE_NETWORK, b ? Boolean.TRUE : Boolean.FALSE);
+		linker_args.put(USE_NETWORK, b ? Boolean.TRUE : Boolean.FALSE);
+		newLinkerOptionsAfterCompile.add(USE_NETWORK);
+	}
+	
+	/**
+	 * Defines a token. mxmlc and compc support token substitutions. For example,
+	 * 
+	 * <pre>
+	 * mxmlc +flexlib=path1 +foo=bar --var=${foo}
+	 * </pre>
+	 * 
+	 * <code>var=bar</code> after the substitution of <code>${foo}</code>.
+	 * 
+	 * @param name
+	 * @param value
+	 */
+	public void setToken(String name, String value)
+	{
+		tokens.put(name, value);
+	}
+
+	/**
+	 * 
+	 * @param key
+	 * @param files
+	 */
+	private void addFiles(String key, File[] files)
+	{
+		addFiles(more, key, files);
+	}
+
+	/**
+	 * 
+	 * @param more
+	 * @param key
+	 * @param files
+	 */
+	private void addFiles(Map<String, Object> more, String key, File[] files)
+	{
+		File[] existing = null;
+		
+		if (more.containsKey(key))
+		{
+			existing = (File[]) more.get(key);
+		}
+		
+		if (existing != null)
+		{
+			int length1 = existing.length, length2 = files == null ? 0 : files.length;
+			
+			File[] newPaths = new File[length1 + length2];
+			System.arraycopy(existing, 0, newPaths, 0, length1);
+			System.arraycopy(files, 0, newPaths, length1, length2);
+			
+			files = newPaths;
+		}
+		
+		more.put(key, files);
+	}
+	
+	/**
+	 * 
+	 * @param a1
+	 * @param a2
+	 * @return
+	 */
+	private String[] merge(String[] a1, String[] a2)
+	{
+		int l1 = a1 == null ? 0 : a1.length;
+		int l2 = a2 == null ? 0 : a2.length;
+		
+		String[] a3 = new String[l1 + l2];
+		if (a1 != null)
+		{
+			System.arraycopy(a1, 0, a3, 0, l1);			
+		}
+		if (a2 != null)
+		{
+			System.arraycopy(a2, 0, a3, l1, l2);
+		}
+		
+		return a3;
+	}
+	
+	/**
+	 * 
+	 * @param a1
+	 * @param a2
+	 * @return
+	 */
+	private File[] merge(File[] a1, File[] a2)
+	{
+		int l1 = a1 == null ? 0 : a1.length;
+		int l2 = a2 == null ? 0 : a2.length;
+		
+		File[] a3 = new File[l1 + l2];
+		if (a1 != null)
+		{
+			System.arraycopy(a1, 0, a3, 0, l1);
+		}
+		if (a2 != null)
+		{
+			System.arraycopy(a2, 0, a3, l1, l2);
+		}
+		
+		return a3;
+	}
+
+	/**
+	 * 
+	 * @param a1
+	 * @param a2
+	 * @return
+	 */
+	private URL[] merge(URL[] a1, URL[] a2)
+	{
+		int l1 = a1 == null ? 0 : a1.length;
+		int l2 = a2 == null ? 0 : a2.length;
+		
+		URL[] a3 = new URL[l1 + l2];
+		if (a1 != null)
+		{
+			System.arraycopy(a1, 0, a3, 0, l1);
+		}
+		if (a2 != null)
+		{
+			System.arraycopy(a2, 0, a3, l1, l2);
+		}
+		
+		return a3;
+	}
+
+	
+	/**
+	 * 
+	 * @param key
+	 * @param strings
+	 */
+	private void addStrings(String key, String[] strings)
+	{
+		addStrings(more, key, strings);
+	}
+	
+	/**
+	 * 
+	 * @param more
+	 * @param key
+	 * @param strings
+	 */
+	private void addStrings(Map<String, Object> more, String key, String[] strings)
+	{
+		String[] existing = null;
+		
+		if (more.containsKey(key))
+		{
+			existing = (String[]) more.get(key);
+		}
+		
+		if (existing != null)
+		{
+			int length1 = existing.length, length2 = strings == null ? 0 : strings.length;
+			
+			String[] newStrings = new String[length1 + length2];
+			System.arraycopy(existing, 0, newStrings, 0, length1);
+			System.arraycopy(strings, 0, newStrings, length1, length2);
+			
+			strings = newStrings;
+		}
+		
+		more.put(key, strings);
+	}
+
+	/**
+	 * 
+	 * @param key
+	 * @param urls
+	 */
+	private void addURLs(String key, URL[] urls)
+	{
+		URL[] existing = null;
+		
+		if (more.containsKey(key))
+		{
+			existing = (URL[]) more.get(key);
+		}
+		
+		if (existing != null)
+		{
+			int length1 = existing.length, length2 = urls == null ? 0 : urls.length;
+			
+			URL[] newURLs = new URL[length1 + length2];
+			System.arraycopy(existing, 0, newURLs, 0, length1);
+			System.arraycopy(urls, 0, newURLs, length1, length2);
+			
+			urls = newURLs;
+		}
+		
+		more.put(key, urls);
+	}
+
+	/**
+	 * 
+	 */
+	public String toString()
+	{
+		String[] args = getCompilerOptions();
+		StringBuilder b = new StringBuilder();
+		for (int i = 0; i < args.length; i++)
+		{
+			b.append(args[i]);
+			b.append(' ');
+		}
+		return b.toString();
+	}
+	
+	/**
+	 * 
+	 * @param f
+	 * @return
+	 */
+	private File toFile(VirtualFile f)
+	{
+		return (f instanceof LocalFile) ? new File(f.getName()) : null;
+	}
+
+	/**
+	 * 
+	 * @param f
+	 * @return
+	 */
+	private URL toURL(VirtualFile f)
+	{
+		try
+		{
+			return (f instanceof LocalFile) ? new File(f.getName()).toURL() : null;
+		}
+		catch (MalformedURLException ex)
+		{
+			return null;
+		}
+	}
+
+	/**
+	 * 
+	 * @param p
+	 * @return
+	 */
+	private File toFile(String p)
+	{
+		return (p != null) ? new File(p) : null;
+	}
+	
+	/**
+	 * 
+	 * @param files
+	 * @return
+	 */
+	private File[] toFiles(VirtualFile[] files)
+	{
+		File[] newFiles = new File[files == null ? 0 : files.length];
+		for (int i = 0, length = newFiles.length; i < length; i++)
+		{
+			newFiles[i] = toFile(files[i]);
+		}
+		
+		return newFiles;
+	}
+	
+	/**
+	 * 
+	 * @param list
+	 * @return
+	 */
+	private String[] toStrings(List list)
+	{
+		String[] strings = new String[list == null ? 0 : list.size()];
+		for (int i = 0, length = strings.length; i < length; i++)
+		{
+			strings[i] = (String) list.get(i);
+		}
+		return strings;
+	}
+
+	/**
+	 * 
+	 * @param list
+	 * @return
+	 */
+	private URL[] toURLs(List list)
+	{
+		URL[] urls = new URL[list == null ? 0 : list.size()];
+		for (int i = 0, length = urls.length; i < length; i++)
+		{
+			try
+			{
+				urls[i] = new URL((String) list.get(i));
+			}
+			catch (MalformedURLException ex)
+			{
+				urls[i] = null;
+			}
+		}
+		return urls;
+	}
+
+	/**
+	 * 
+	 * @param set
+	 * @return
+	 */
+	private String[] toStrings(Set set)
+	{
+		String[] strings = new String[set == null ? 0 : set.size()];
+		if (set != null)
+		{
+			int k = 0;
+			for (Iterator i = set.iterator(); i.hasNext(); k++)
+			{
+				strings[k] = (String) i.next();
+			}
+		}
+		return strings;		
+	}
+	
+	/**
+	 * 
+	 * @param num
+	 * @return
+	 */
+	private int toInteger(String num)
+	{
+		try
+		{
+			return Integer.parseInt(num);
+		}
+		catch (NumberFormatException ex)
+		{
+			return -1;
+		}
+	}
+
+	private String toCommaSeparatedString(String[] strings)
+	{
+		StringBuilder b = new StringBuilder();
+		for (int i = 0, length = strings == null ? 0 : strings.length; i < length; i++)
+		{
+			b.append(strings[i]);
+			if (i < length - 1)
+			{
+				b.append(',');
+			}
+		}
+		return b.toString();
+	}
+
+	private String toCommaSeparatedString(File[] files)
+	{
+		StringBuilder b = new StringBuilder();
+		for (int i = 0, length = files == null ? 0 : files.length; i < length; i++)
+		{
+			b.append(files[i].getPath());
+			if (i < length - 1)
+			{
+				b.append(',');
+			}
+		}
+		return b.toString();
+	}
+
+	private String toCommaSeparatedString(URL[] urls)
+	{
+		StringBuilder b = new StringBuilder();
+		for (int i = 0, length = urls == null ? 0 : urls.length; i < length; i++)
+		{
+			b.append(urls[i].toExternalForm());
+			if (i < length - 1)
+			{
+				b.append(',');
+			}
+		}
+		return b.toString();
+	}
+
+    /**
+	 * 
+     * @param c
+     */
+	private void populateDefaults(ToolsConfiguration c)
+	{
+		setDefaultBackgroundColor(c.backgroundColor());
+		setDefaultFrameRate(c.getFrameRate());
+		setDefaultScriptLimits(c.getScriptRecursionLimit(), c.getScriptTimeLimit());
+		setDefaultSize(c.defaultWidth(), c.defaultHeight());
+		setExterns(toStrings(c.getExterns()));
+		setIncludes(toStrings(c.getIncludes()));
+		setTargetPlayer(c.getTargetPlayerMajorVersion(), c.getTargetPlayerMinorVersion(), 
+						c.getTargetPlayerRevision());
+		enableDigestVerification(c.getVerifyDigests());
+		removeUnusedRuntimeSharedLibraryPaths(c.getRemoveUnusedRsls());
+		
+		List<RslPathInfo> rslList = c.getRslPathInfo();
+		boolean first = true;
+		for (Iterator<RslPathInfo> iter = rslList.iterator(); iter.hasNext();) {
+			RslPathInfo info = (RslPathInfo)iter.next();
+			String[] rslUrls = info.getRslUrls().toArray(new String[0]);
+			String[] policyUrls = info.getPolicyFileUrls().toArray(new String[0]);
+			if (first) {
+				setRuntimeSharedLibraryPath(info.getSwcPath(),
+						rslUrls,
+						policyUrls);
+				first = false;
+			}
+			else {
+				addRuntimeSharedLibraryPath(info.getSwcPath(),
+						rslUrls,
+						policyUrls);
+			}
+		}
+		
+		// TODO
+		// setSWFMetaData();
+		// setProjector();
+		
+		setSWFMetaData(c.getMetadata());
+		setRuntimeSharedLibraries(toStrings(c.getRuntimeSharedLibraries()));
+		useNetwork(c.useNetwork());
+		
+		// useMobileFramework();
+		
+		populateDefaults(c.getCompilerConfiguration());
+		populateDefaults(c.getFramesConfiguration());
+		populateDefaults(c.getLicensesConfiguration());
+		populateDefaults(c.getRuntimeSharedLibrarySettingsConfiguration());
+	}
+
+	/**
+	 * 
+	 * @param cc
+	 */
+	private void populateDefaults(CompilerConfiguration cc)
+	{
+		enableAccessibility(cc.accessible());
+		setActionScriptMetadata(cc.getKeepAs3Metadata());
+		setActionScriptFileEncoding(cc.getActionscriptFileEncoding());
+		allowSourcePathOverlap(cc.allowSourcePathOverlap());
+		useActionScript3(cc.dialect() == CompilerConfiguration.AS3Dialect);
+		setContextRoot(cc.getContextRoot());
+		enableDebugging(cc.debug(), configuration.debugPassword());
+		
+		if (cc.getDefaultsCssUrl() != null)
+		{
+			setDefaultCSS(FileUtil.openFile(cc.getDefaultsCssUrl().getName()));
+		}
+		
+		useECMAScript(cc.dialect() == CompilerConfiguration.ESDialect);
+		setExternalLibraryPath(toFiles(cc.getExternalLibraryPath()));
+		useHeadlessServer(cc.headlessServer());
+		keepAllTypeSelectors(cc.keepAllTypeSelectors());
+		keepCompilerGeneratedActionScript(cc.keepGeneratedActionScript());
+		includeLibraries(toFiles(cc.getIncludeLibraries()));
+		setLibraryPath(toFiles(cc.getLibraryPath()));
+		setLocale(cc.getLocales());
+		optimize(cc.optimize());
+		setServiceConfiguration(toFile(cc.getServices()));
+		showActionScriptWarnings(cc.warnings());
+		showBindingWarnings(cc.showBindingWarnings());
+		showDeprecationWarnings(cc.showDeprecationWarnings());
+        showShadowedDeviceFontWarnings(cc.showShadowedDeviceFontWarnings());
+		showUnusedTypeSelectorWarnings(cc.showUnusedTypeSelectorWarnings());
+		setSourcePath(cc.getUnexpandedSourcePath());
+		enableStrictChecking(cc.strict());
+		setTheme(toFiles(cc.getThemeFiles()));
+		useResourceBundleMetaData(cc.useResourceBundleMetadata());
+		enableVerboseStacktraces(cc.debug());
+        setDefineDirective(cc.getDefine());
+        setCompatibilityVersion(cc.getMxmlConfiguration().getMajorCompatibilityVersion(),
+        						cc.getMxmlConfiguration().getMinorCompatibilityVersion(),
+        						cc.getMxmlConfiguration().getRevisionCompatibilityVersion());
+
+		checkActionScriptWarning(WARN_ARRAY_TOSTRING_CHANGES, cc.warn_array_tostring_changes());
+		checkActionScriptWarning(WARN_ASSIGNMENT_WITHIN_CONDITIONAL, cc.warn_assignment_within_conditional());
+		checkActionScriptWarning(WARN_BAD_ARRAY_CAST, cc.warn_bad_array_cast());
+		checkActionScriptWarning(WARN_BAD_BOOLEAN_ASSIGNMENT, cc.warn_bad_bool_assignment());
+		checkActionScriptWarning(WARN_BAD_DATE_CAST, cc.warn_bad_date_cast());
+		checkActionScriptWarning(WARN_BAD_ES3_TYPE_METHOD, cc.warn_bad_es3_type_method());
+		checkActionScriptWarning(WARN_BAD_ES3_TYPE_PROP, cc.warn_bad_es3_type_prop());
+		checkActionScriptWarning(WARN_BAD_NAN_COMPARISON, cc.warn_bad_nan_comparison());
+		checkActionScriptWarning(WARN_BAD_NULL_ASSIGNMENT, cc.warn_bad_null_assignment());
+		checkActionScriptWarning(WARN_BAD_NULL_COMPARISON, cc.warn_bad_null_comparison());
+		checkActionScriptWarning(WARN_BAD_UNDEFINED_COMPARISON, cc.warn_bad_undefined_comparison());
+		checkActionScriptWarning(WARN_BOOLEAN_CONSTRUCTOR_WITH_NO_ARGS, cc.warn_boolean_constructor_with_no_args());
+		checkActionScriptWarning(WARN_CHANGES_IN_RESOLVE, cc.warn_changes_in_resolve());
+		checkActionScriptWarning(WARN_CLASS_IS_SEALED, cc.warn_class_is_sealed());
+		checkActionScriptWarning(WARN_CONST_NOT_INITIALIZED, cc.warn_const_not_initialized());
+		checkActionScriptWarning(WARN_CONSTRUCTOR_RETURNS_VALUE, cc.warn_constructor_returns_value());
+		checkActionScriptWarning(WARN_DEPRECATED_EVENT_HANDLER_ERROR, cc.warn_deprecated_event_handler_error());
+		checkActionScriptWarning(WARN_DEPRECATED_FUNCTION_ERROR, cc.warn_deprecated_function_error());
+		checkActionScriptWarning(WARN_DEPRECATED_PROPERTY_ERROR, cc.warn_deprecated_property_error());
+		checkActionScriptWarning(WARN_DUPLICATE_ARGUMENT_NAMES, cc.warn_duplicate_argument_names());
+		checkActionScriptWarning(WARN_DUPLICATE_VARIABLE_DEF, cc.warn_duplicate_variable_def());
+		checkActionScriptWarning(WARN_FOR_VAR_IN_CHANGES, cc.warn_for_var_in_changes());
+		checkActionScriptWarning(WARN_IMPORT_HIDES_CLASS, cc.warn_import_hides_class());
+		checkActionScriptWarning(WARN_INSTANCEOF_CHANGES, cc.warn_instance_of_changes());
+		checkActionScriptWarning(WARN_INTERNAL_ERROR, cc.warn_internal_error());
+		checkActionScriptWarning(WARN_LEVEL_NOT_SUPPORTED, cc.warn_level_not_supported());
+		checkActionScriptWarning(WARN_MISSING_NAMESPACE_DECL, cc.warn_missing_namespace_decl());
+		checkActionScriptWarning(WARN_NEGATIVE_UINT_LITERAL, cc.warn_negative_uint_literal());
+		checkActionScriptWarning(WARN_NO_CONSTRUCTOR, cc.warn_no_constructor());
+		checkActionScriptWarning(WARN_NO_EXPLICIT_SUPER_CALL_IN_CONSTRUCTOR, cc.warn_no_explicit_super_call_in_constructor());
+		checkActionScriptWarning(WARN_NO_TYPE_DECL, cc.warn_no_type_decl());
+		checkActionScriptWarning(WARN_NUMBER_FROM_STRING_CHANGES, cc.warn_number_from_string_changes());
+		checkActionScriptWarning(WARN_SCOPING_CHANGE_IN_THIS, cc.warn_scoping_change_in_this());
+		checkActionScriptWarning(WARN_SLOW_TEXTFIELD_ADDITION, cc.warn_slow_text_field_addition());
+		checkActionScriptWarning(WARN_UNLIKELY_FUNCTION_VALUE, cc.warn_unlikely_function_value());
+		checkActionScriptWarning(WARN_XML_CLASS_HAS_CHANGED, cc.warn_xml_class_has_changed());
+
+		populateDefaults(cc.getFontsConfiguration());
+		populateDefaults(cc.getNamespacesConfiguration());
+	}
+
+	/**
+	 * 
+	 * @param fc
+	 */
+	private void populateDefaults(FontsConfiguration fc)
+	{
+		FontsConfiguration.Languages lc = fc.getLanguagesConfiguration();
+		
+		for (Iterator i = lc.keySet().iterator(); i.hasNext(); )
+		{
+			String key = (String) i.next();
+			setFontLanguageRange(key, lc.getProperty(key));
+		}
+		setLocalFontSnapshot(toFile(fc.getLocalFontsSnapshot()));
+		setLocalFontPaths(toStrings(fc.getLocalFontPaths()));
+		setFontManagers(toStrings(fc.getManagers()));
+		setMaximumCachedFonts(toInteger(fc.getMaxCachedFonts()));
+		setMaximumGlyphsPerFace(toInteger(fc.getMaxGlyphsPerFace()));
+		enableAdvancedAntiAliasing(fc.getFlashType());
+	}
+
+	/**
+	 * 
+	 * @param nc
+	 */
+	private void populateDefaults(NamespacesConfiguration nc)
+	{
+	    Map<String, List<VirtualFile>> manifestMappings = nc.getManifestMappings();
+
+		if (manifestMappings != null)
+		{
+		    Iterator<Entry<String, List<VirtualFile>>> iterator = manifestMappings.entrySet().iterator();
+			while (iterator.hasNext())
+			{
+				Entry<String, List<VirtualFile>> entry = iterator.next();
+			    String uri = entry.getKey();
+			    List<VirtualFile> virtualFiles = entry.getValue();
+			    List<File> files = new ArrayList<File>(virtualFiles.size());
+
+			    Iterator<VirtualFile> vi = virtualFiles.iterator();
+			    while (vi.hasNext())
+			    {
+	                files.add(toFile(vi.next()));
+			    }
+                setComponentManifests(uri, files);
+			}
+		}
+	}
+	
+	/**
+	 * 
+	 * @param frc
+	 */
+	private void populateDefaults(FramesConfiguration frc)
+	{
+		List frList = frc.getFrameList();
+
+		for (int i = 0, length = frList == null ? 0 : frList.size(); i < length; i++)
+		{
+			FrameInfo info = (FrameInfo) frList.get(i);
+			setFrameLabel(info.label, toStrings(info.frameClasses));
+		}
+	}
+	
+	/**
+	 * 
+	 * @param lic
+	 */
+	private void populateDefaults(LicensesConfiguration lic)
+	{
+		Map licenseMap = lic.getLicenseMap();
+
+		if (licenseMap != null)
+		{
+			for (Iterator i = licenseMap.keySet().iterator(); i.hasNext(); )
+			{
+				String name = (String) i.next();
+				setLicense(name, (String) licenseMap.get(name));
+			}
+		}
+	}
+	
+    /**
+     * 
+     * @param configuration - runtime shared library settings.
+     */
+    private void populateDefaults(RuntimeSharedLibrarySettingsConfiguration configuration)
+    {
+        setForceRuntimeSharedLibraryPaths(toFiles(configuration.getForceRsls()));
+        
+        Map<VirtualFile, String>adMap = configuration.getApplicationDomains();
+        boolean first = true;
+        
+        for (Map.Entry<VirtualFile, String>entry : adMap.entrySet())
+        {
+            File file = toFile(entry.getKey());
+            if (first)
+            {
+                setApplicationDomainForRuntimeSharedLibraryPath(
+                        file,
+                        entry.getValue());
+                first = false;
+            }
+            else
+            {
+                addApplicationDomainForRuntimeSharedLibraryPath(
+                        file,
+                        entry.getValue());
+            }
+        }
+        
+    }
+
+    public boolean hasChanged()
+	{
+		return newLinkerOptionsAfterCompile.size() > 0;
+	}
+	
+	public void reset()
+	{
+		newLinkerOptionsAfterCompile.clear();
+	}
+	
+	public void setTargetPlayer(int major, int minor, int revision)
+	{
+		args.put(TARGET_PLAYER, major + "." + minor + "." + revision);
+	}
+
+	public void setCompatibilityVersion(int major, int minor, int revision)
+	{
+		if (!(major == 0 && minor == 0 && revision == 0))
+		{
+			args.put(COMPILER_MXML_COMPATIBILITY, major + "." + minor + "." + revision);
+		}
+	}
+
+	private String[] createCrossDomainArray(String swc, String[] rslUrls, String[] policyFileUrls)
+	{
+		if (swc == null || rslUrls == null || policyFileUrls == null) 
+		{
+			throw new NullPointerException();
+		}
+		
+		if (rslUrls.length != policyFileUrls.length)
+		{
+			throw new IllegalArgumentException();
+		}
+		
+		List<String> rslList = new ArrayList<String>();
+		
+		rslList.add(swc);
+		
+		int argCount = rslUrls.length;
+		for (int i = 0; i < argCount; i++) 
+		{
+			rslList.add(rslUrls[i]);
+			rslList.add(policyFileUrls[i]);
+		}
+		
+		return rslList.toArray(new String[0]);
+	}
+	
+	
+	public void enableDigestComputation(boolean compute)
+	{
+		args.put(COMPILER_COMPUTE_DIGEST, compute ? Boolean.TRUE : Boolean.FALSE);				
+	}
+
+	
+	public void addRuntimeSharedLibraryPath(String swc, String[] rslUrls, String[] policyFileUrls)
+	{
+		String[] rslArray = createCrossDomainArray(swc, rslUrls, policyFileUrls);
+
+		RslPathList value = (RslPathList) args.get(RUNTIME_SHARED_LIBRARY_PATH);
+		if (value == null)
+		{
+			value = new RslPathList();
+			args.put(RUNTIME_SHARED_LIBRARY_PATH, value);
+		}
+
+		value.add(rslArray);			
+	}
+
+	public void setRuntimeSharedLibraryPath(String swc, String[] rslUrls, String[] policyFileUrls)
+	{
+		String[] rslArray = createCrossDomainArray(swc, rslUrls, policyFileUrls);
+
+		RslPathList list = new RslPathList();
+		list.add(rslArray);
+		
+		args.put(RUNTIME_SHARED_LIBRARY_PATH, list);
+	}
+
+	public void enableDigestVerification(boolean verify)
+	{
+		args.put(VERIFY_DIGESTS, verify ? Boolean.TRUE : Boolean.FALSE);	
+	}
+
+    public void addDefineDirective(String name, String value)
+    {
+        // error checking on the values themsevles will be handled later,
+        // in CompilerConfiguration.cfgDefine()
+        CompilerDefinitionList defs = (CompilerDefinitionList) args.get(COMPILER_DEFINE);
+        if (defs == null)
+        {
+            defs = new CompilerDefinitionList();
+            args.put(COMPILER_DEFINE, defs);
+        }
+
+        defs.add(name);
+        defs.add(value);
+    }
+    
+    public void setDefineDirective(String[] names, String[] values)
+    {
+        if ((names == null) || (values == null) || (names.length != values.length))
+        {
+            args.remove(COMPILER_DEFINE);
+        }
+        else
+        {
+            final CompilerDefinitionList defs = new CompilerDefinitionList();
+            args.put(COMPILER_DEFINE, defs);
+            
+            for(int i = 0; i < values.length; i++)
+            {
+                defs.add(names[i]);
+                defs.add(values[i]);
+            }
+        }
+    }
+
+    /**
+     * hacky non-API helper method for populateDefaults
+     */
+    private void setDefineDirective(ObjectList<ConfigVar> configVars)
+    {
+        if (configVars != null)
+        {
+            final CompilerDefinitionList defs = new CompilerDefinitionList();
+            args.put(COMPILER_DEFINE, defs);
+            for(ConfigVar var : configVars)
+            {
+                // by this point, error checking should already have been
+                // performed on the ConfigVars
+                assert (var       != null &&
+                        var.ns    != null &&
+                        var.name  != null &&
+                        var.value != null &&
+                        var.ns.length()    > 0 &&
+                        var.name.length()  > 0 &&
+                        var.value.length() > 0);
+                
+                defs.add(var.ns + "::" + var.name);
+                defs.add(var.value);
+            }
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    public Map<String, List<String>> getExtensions() {
+        if( !args.containsKey( COMPILER_EXTENSIONS ) ) {
+            args.put( COMPILER_EXTENSIONS, new LinkedHashMap<String, List<String>>() );
+        }
+        return (Map<String, List<String>>) args.get( COMPILER_EXTENSIONS );
+    }
+
+    public void addExtensionLibraries( File extension, List<String> parameter )
+    {
+        getExtensions().put( extension.getAbsolutePath(), parameter );
+    }
+
+    public void setExtensionLibraries( Map<File, List<String>> extensions)
+    {
+        getExtensions().clear();
+        Set<File> keys = extensions.keySet();
+        for ( File key : keys )
+        {
+            addExtensionLibraries( key, extensions.get( key ) );
+        }
+    }
+    
+    @Override
+    public OEMConfiguration clone()
+    {
+        OEMConfiguration cloneConfig;
+        try
+        {
+            cloneConfig = (OEMConfiguration) super.clone();
+        }
+        catch ( CloneNotSupportedException e )
+        {
+            throw new RuntimeException(e);//wont happen
+        }
+        cloneConfig.args = new LinkedHashMap<String, Object>(args);
+        cloneConfig.defaults = new LinkedHashMap<String, Object>(defaults);
+        cloneConfig.more = new LinkedHashMap<String, Object>(more);
+        cloneConfig.linker_args = new LinkedHashMap<String, Object>(linker_args);
+        cloneConfig.linker_more = new LinkedHashMap<String, Object>(linker_more);
+        return cloneConfig;
+    }
+
+    public void addForceRuntimeSharedLibraryPaths(File[] paths)
+    {
+        if (paths == null)
+            throw new NullPointerException("paths may not be null");
+
+        addFiles(RUNTIME_SHARED_LIBRARY_SETTINGS_FORCE_RSLS, paths);
+    }
+
+    public void setForceRuntimeSharedLibraryPaths(File[] paths)
+    {
+        if (paths == null)
+            throw new NullPointerException("paths may not be null");
+        
+        args.put(RUNTIME_SHARED_LIBRARY_SETTINGS_FORCE_RSLS, paths);
+        more.remove(RUNTIME_SHARED_LIBRARY_SETTINGS_FORCE_RSLS);
+    }
+    
+    public void addApplicationDomainForRuntimeSharedLibraryPath(File path, String applicationDomainTarget)
+    {
+        validateApplicationDomainArguments(path, applicationDomainTarget);
+        
+        ApplicationDomainsList value = (ApplicationDomainsList) args.get(RUNTIME_SHARED_LIBRARY_SETTINGS_APPLICATION_DOMAIN);
+        if (value == null)
+        {
+            value = new ApplicationDomainsList();
+            args.put(RUNTIME_SHARED_LIBRARY_SETTINGS_APPLICATION_DOMAIN, value);
+        }
+
+        value.add(new String[]{path.getPath(), applicationDomainTarget});                        
+    }
+    
+    public void setApplicationDomainForRuntimeSharedLibraryPath(File path, String applicationDomainTarget)
+    {
+        ApplicationDomainsList list = new ApplicationDomainsList();
+        if (path == null)
+        {
+            args.put(RUNTIME_SHARED_LIBRARY_SETTINGS_APPLICATION_DOMAIN, list);
+            return;
+        }
+        
+        validateApplicationDomainArguments(path, applicationDomainTarget);
+
+        list.add(new String[]{path.getPath(), applicationDomainTarget});            
+
+        args.put(RUNTIME_SHARED_LIBRARY_SETTINGS_APPLICATION_DOMAIN, list);
+    }
+
+    /**
+     *  Validate the arguments to the application domain methods.
+     *  Throw exceptions if the arguments do not pass the tests. 
+     */
+    private void validateApplicationDomainArguments(File path, String applicationDomainTarget)
+    {
+        if (path == null)
+            throw new NullPointerException("paths may not be null");
+        
+        if (applicationDomainTarget == null)
+            throw new NullPointerException("applicationDomains may not be null");
+    }
+
+}