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:31 UTC

[09/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/Library.java
----------------------------------------------------------------------
diff --git a/flex-compiler-oem/src/flex2/tools/oem/Library.java b/flex-compiler-oem/src/flex2/tools/oem/Library.java
new file mode 100644
index 0000000..38a93d3
--- /dev/null
+++ b/flex-compiler-oem/src/flex2/tools/oem/Library.java
@@ -0,0 +1,1061 @@
+/*
+ *
+ *  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;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.net.URI;
+
+import org.apache.flex.compiler.clients.COMPC;
+
+import flex2.compiler.CompilerAPI;
+import flex2.compiler.CompilerException;
+import flex2.compiler.Source;
+import flex2.compiler.SourceList;
+import flex2.compiler.SourcePath;
+import flex2.compiler.SymbolTable;
+import flex2.compiler.common.CompilerConfiguration;
+import flex2.compiler.config.ConfigurationException;
+import flex2.compiler.io.FileUtil;
+import flex2.compiler.io.LocalFile;
+import flex2.compiler.io.VirtualFile;
+import flex2.compiler.util.Benchmark;
+import flex2.compiler.util.CompilerControl;
+import flex2.compiler.util.MimeMappings;
+import flex2.compiler.util.NameFormatter;
+import flex2.compiler.util.PerformanceData;
+import flex2.compiler.util.QName;
+import flex2.compiler.util.ThreadLocalToolkit;
+import flex2.linker.LinkerConfiguration;
+import flex2.linker.SimpleMovie;
+import flex2.tools.ToolsConfiguration;
+import flex2.tools.oem.internal.OEMConfiguration;
+import flex2.tools.oem.internal.OEMReport;
+import flex2.tools.oem.internal.OEMUtil;
+
+/**
+ * The <code>Library</code> class represents a SWC archive or a RSL. It implements the <code>Builder</code> interface
+ * which allows for building the library incrementally. The following example defines a SWC archive or RSL:
+ *
+ * <pre>
+ * Library lib = new Library();
+ * </pre>
+ *
+ * You can add components to the <code>Library</code> object in the following ways:
+ *
+ * <pre>
+ * 1. String              - Specify a fully-qualified name.
+ * 2. File                - Specify a source file.
+ * 3. VirtualLocalFile    - Specify an in-memory source object.
+ * 4. URI                 - Specify a namespace URI.
+ * </pre>
+ *
+ * <p>
+ * To add resource bundles to the <code>Library</code>, you can use the <code>addResourceBundle()</code> method,
+ * as the following example shows:
+ *
+ * <pre>
+ * lib.addResourceBundle("mx.controls"));
+ * </pre>
+ *
+ * <p>
+ * To add archive files to the <code>Library</code>, you can use the <code>addArchiveFile()</code> method, as the following
+ * example shows:
+ *
+ * <pre>
+ * lib.addArchiveFile("defaults.css", new File("path1/myStyle.css"));
+ * </pre>
+ *
+ * Before you can compile with a <code>Library</code> object, you must configure it. The following
+ * four methods are the most common methods you use to configure the <code>Library</code> object:
+ *
+ * <pre>
+ * 1. setLogger()        - Use this to set a Logger so that the client can be notified of events that occurred during the compilation.
+ * 2. setConfiguration() - Optional. Use this to specify compiler options.
+ * 3. setOutput()        - Optional. Use this to specify an output file name.
+ * 4. setDirectory()     - Optional. Use this to specify an RSL output directory.
+ * </pre>
+ *
+ * You must implement the <code>flex2.tools.oem.Logger</code> interface and use the implementation as the <code>Logger</code>
+ * for the compilation. The following is an example <code>Logger</code> implementation:
+ *
+ * <pre>
+ * lib.setLogger(new flex2.tools.oem.Logger()
+ * {
+ *     public void log(Message message, int errorCode, String source)
+ *     {
+ *         System.out.println(message);
+ *     }
+ * });
+ * </pre>
+ *
+ * To specify compiler options for the <code>Library</code> object, you
+ * must get a <code>Configuration</code> object that is populated with default values. Then, you set
+ * compiler options programmatically using methods of the <code>Configuration</code> class.
+ *
+ * <p>
+ * The <code>setOutput()</code> method lets you specify where the <code>Library</code> object writes
+ * the output to. If you call the <code>setOutput()</code> method, the <code>build(boolean)</code> method
+ * writes directly to the specified location; for example:
+ *
+ * <pre>
+ * lib.setOutput(new File("MyLib.swc"));
+ * lib.build(true);
+ * </pre>
+ *
+ * If you do not call the <code>setOutput()</code> method, you can use the <code>build(OutputStream, boolean)</code>
+ * method. This requires that you provide a buffered output stream; for example:
+ *
+ * <pre>
+ * lib.build(new BufferedOutputStream(new FileOutputStream("MyLib.swc")), true);
+ * </pre>
+ *
+ * The <code>setDirectory()</code> method lets you output RSLs to the specified directory; for example:
+ *
+ * <pre>
+ * lib.setDirectory(new File("dir1"));
+ * lib.build(true);
+ * </pre>
+ *
+ * You can save the <code>Library</code> object compilation
+ * data for reuse. You do this using the <code>save(OutputStream)</code> method. Subsequent compilations can use
+ * the <code>load(OutputStream)</code> method to get the old data into the <code>Library</code> object; for example:
+ *
+ * <pre>
+ * lib.save(new BufferedOutputStream(new FileOutputStream("MyLib.incr")));
+ * </pre>
+ *
+ * When a cache file (for example, <code>MyLib.incr</code>) from a previous compilation is available before the
+ * compilation, you can call the <code>load(OutputStream)</code> method before you call the <code>build()</code> method; for example:
+ *
+ * <pre>
+ * lib.load(new BufferedInputStream(FileInputStream("MyLib.incr")));
+ * lib.build(true);
+ * </pre>
+ *
+ * The <code>build(false)</code> and <code>build(OutputStream, false)</code> methods always rebuild the library.
+ * The first time you build the <code>Library</code>
+ * object, the <code>build(true)/build(OutputStream, true)</code> methods do a complete build, which
+ * is equivalent to the <code>build(false)/build(OutputStream, false)</code> methods, respectively. After you call the
+ * <code>clean()</code> method, the <code>Library</code> object always does a full build.
+ *
+ * <p>
+ * The <code>clean()</code> method cleans up compilation data in the <code>Library</code> object the output
+ * file, if the <code>setOutput()</code> method was called.
+ *
+ * <p>
+ * You can use the <code>Library</code> class to build a library from a combination of source
+ * files in the file system and in-memory, dynamically-generated source objects. You
+ * must use the <code>addComponent(VirtualLocalFile)</code>, <code>addResourceBundle(VirtualLocalFile)</code>, and
+ * <code>addArchiveFile(String, VirtualLocalFile)</code> methods to use in-memory objects.
+ *
+ * <p>
+ * The <code>Library</code> class can be part of a <code>Project</code>.
+ *
+ * @see flex2.tools.oem.Configuration
+ * @see flex2.tools.oem.Project
+ * @version 2.0.1
+ * @author Clement Wong
+ */
+public class Library implements Builder, Cloneable
+{
+    static
+    {
+        // This "should" trigger the static initialization of Application which locates
+        // flex-compiler-oem.jar and set application.home correctly.
+        try
+        {
+            // in Java 1.4, simply saying Application.class would load the class
+            // Java 1.5 is much smarter, and you have to coax the JVM to actually load it
+            Class.forName("flex2.tools.oem.Application");
+        }
+        catch (ClassNotFoundException e)
+        {
+            // I guess it didn't work *shrug*
+            e.printStackTrace();
+            assert false;
+        }
+    }
+
+    /**
+     * Constructor.
+     */
+    public Library()
+    {
+        sources = new TreeSet<VirtualFile>(new Comparator<VirtualFile>()
+        {
+            public int compare(VirtualFile f0, VirtualFile f1)
+            {
+                return f0.getName().compareTo(f1.getName());
+            }
+        });
+        classes = new TreeSet<String>();
+        namespaces = new TreeSet<URI>();
+        resourceBundles = new TreeSet<String>();
+        files = new TreeMap<String, VirtualFile>();
+        stylesheets = new TreeMap<String, VirtualFile>();
+
+        oemConfiguration = null;
+        logger = null;
+        output = null;
+        directory = null;
+        mimeMappings = new MimeMappings();
+        meter = null;
+        resolver = null;
+        cc = new CompilerControl();
+
+        //data = null;
+        cacheName = null;
+        configurationReport = null;
+        messages = new ArrayList<Message>();
+    }
+
+    private Set<VirtualFile> sources;
+    private Set<String> classes, resourceBundles;
+    private Set<URI> namespaces;
+    private Map<String, VirtualFile> files, stylesheets;
+    private OEMConfiguration oemConfiguration;
+    private Logger logger;
+    private File output, directory;
+    private MimeMappings mimeMappings;
+    private ProgressMeter meter;
+    protected PathResolver resolver;
+    private CompilerControl cc;
+    private ApplicationCache applicationCache;
+    private LibraryCache libraryCache;
+
+    // clean() would null out the following variables
+    //LibraryData data;
+    private String cacheName, configurationReport;
+    private List<Message> messages;
+    private HashMap<String, PerformanceData[]> compilerBenchmarks;
+    private Benchmark benchmark;
+
+    /**
+     * Adds a class, function, variable, or namespace to this <code>Library</code> object.
+     *
+     * This is the equilvalent of the <code>include-classes</code> option of the compc compiler.
+     *
+     * @param includeClass A fully-qualified name.
+     */
+    public void addComponent(String includeClass)
+    {
+        classes.add(includeClass);
+    }
+
+    /**
+     * Adds a component to this <code>Library</code> object.
+     * This is the equilvalent of the <code>include-sources</code> option of the compc compiler.
+     *
+     * @param includeSource A source file.
+     */
+    public void addComponent(File includeSource)
+    {
+        sources.add(new LocalFile(includeSource));
+    }
+
+    /**
+     * Adds a component to this <code>Library</code> object.
+     *
+     * This is equilvalent to the <code>include-sources</code> option of the compc compiler.
+     *
+     * @param includeSource An in-memory source object.
+     */
+    public void addComponent(VirtualLocalFile includeSource)
+    {
+        sources.add(includeSource);
+    }
+
+    /**
+     * Adds a list of components to this <code>Library</code> object.
+     *
+     * This is equilvalent to the <code>include-namespaces</code> option of the compc compiler.
+     *
+     * @param includeNamespace A namespace URI.
+     */
+    public void addComponent(URI includeNamespace)
+    {
+        namespaces.add(includeNamespace);
+    }
+
+    /**
+     * Removes the specified component from this <code>Library</code> object.
+     * The name can be a class, a function, a variable, or a namespace.
+     *
+     * @param includeClass A fully-qualified name.
+     */
+    public void removeComponent(String includeClass)
+    {
+        classes.remove(includeClass);
+    }
+
+    /**
+     * Removes the specified component from this <code>Library</code> object.
+     *
+     * @param includeSource A source file.
+     */
+    public void removeComponent(File includeSource)
+    {
+        sources.remove(new LocalFile(includeSource));
+    }
+
+    /**
+     * Removes the specified component from this <code>Library</code> object.
+     *
+     * @param includeSource An in-memory source object.
+     */
+    public void removeComponent(VirtualLocalFile includeSource)
+    {
+        sources.remove(includeSource);
+    }
+
+    /**
+     * Removes the specified list of components from this <code>Library</code> object. The input argument is a namespace URI.
+     *
+     * @param includeNamespace A namespace URI.
+     */
+    public void removeComponent(URI includeNamespace)
+    {
+        namespaces.remove(includeNamespace);
+    }
+
+    /**
+     * Removes all the components from this <code>Library</code> object.
+     */
+    public void removeAllComponents()
+    {
+        sources.clear();
+        classes.clear();
+        namespaces.clear();
+    }
+
+    /**
+     * Adds a resource bundle to this <code>Library</code> object.
+     *
+     * This is equilvalent to the <code>include-resource-bundles</code> option of the compc compiler.
+     *
+     * @param resourceBundle A resource bundle name.
+     */
+    public void addResourceBundle(String resourceBundle)
+    {
+        resourceBundles.add(resourceBundle);
+    }
+
+    /**
+     * Removes the specified resource bundle name from this <code>Library</code> object.
+     *
+     * @param resourceBundle A resource bundle name.
+     */
+    public void removeResourceBundle(String resourceBundle)
+    {
+        resourceBundles.remove(resourceBundle);
+    }
+
+    /**
+     * Removes all the resource bundles from this <code>Library</code> object.
+     *
+     */
+    public void removeAllResourceBundles()
+    {
+        resourceBundles.clear();
+    }
+
+    /**
+     * Adds a file to this <code>Library</code> object. This is equilvalent to the <code>include-file</code> option of the compc compiler.
+     *
+     * @param name The name in the archive.
+     * @param file The file to be added.
+     */
+    public void addArchiveFile(String name, File file)
+    {
+        files.put(name, new LocalFile(file));
+    }
+
+    /**
+     * Adds an in-memory source object to this <code>Library</code> object. This is equilvalent to the <code>
+     * include-file</code> option of the compc compiler.
+     *
+     * @param name The name in the archive.
+     * @param file The in-memory source object to be added.
+     */
+    public void addArchiveFile(String name, VirtualLocalFile file)
+    {
+        files.put(name, file);
+    }
+
+    /**
+     * Removes the specified file from this <code>Library</code> object.
+     *
+     * @param name The name in the archive.
+     */
+    public void removeArchiveFile(String name)
+    {
+        files.remove(name);
+    }
+
+    /**
+     * Removes all the archive files from this <code>Library</code> object.
+     */
+    public void removeAllArchiveFiles()
+    {
+        files.clear();
+    }
+
+    /**
+     * Adds a CSS stylesheet to this <code>Library</code> object. This is equilvalent to the <code>include-stylesheet</code> option of the compc compiler.
+     *
+     * @param name The name in the archive.
+     * @param file The file to be added.
+     * @since 3.0
+     */
+    public void addStyleSheet(String name, File file)
+    {
+        stylesheets.put(name, new LocalFile(file));
+    }
+
+    /**
+     * Adds an in-memory CSS stylesheet object to this <code>Library</code> object. This is equilvalent to the <code>
+     * include-stylesheet</code> option of the compc compiler.
+     *
+     * @param name The name in the archive.
+     * @param file The in-memory source object to be added.
+     * @since 3.0
+     */
+    public void addStyleSheet(String name, VirtualLocalFile file)
+    {
+        stylesheets.put(name, file);
+    }
+
+    /**
+     * Removes the specified CSS stylesheet from this <code>Library</code> object.
+     *
+     * @param name The name in the archive.
+     * @since 3.0
+     */
+    public void removeStyleSheet(String name)
+    {
+        stylesheets.remove(name);
+    }
+
+    /**
+     * Removes all the CSS stylesheets from this <code>Library</code> object.
+     * @since 3.0
+     */
+    public void removeAllStyleSheets()
+    {
+        stylesheets.clear();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public void setConfiguration(Configuration configuration)
+    {
+        oemConfiguration = (OEMConfiguration) configuration;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public Configuration getDefaultConfiguration()
+    {
+        return getDefaultConfiguration(false);
+    }
+
+    /**
+     *
+     * @param processDefaults
+     * @return
+     */
+    private Configuration getDefaultConfiguration(boolean processDefaults)
+    {
+        return OEMUtil.getLibraryConfiguration(constructCommandLine(null), false, false,
+                                               OEMUtil.getLogger(logger, messages), resolver,
+                                               mimeMappings, processDefaults);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public HashMap<String, PerformanceData[]> getCompilerBenchmarks()
+    {
+        return compilerBenchmarks;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public Benchmark getBenchmark()
+    {
+        return benchmark;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public Configuration getConfiguration()
+    {
+        return oemConfiguration;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public void setLogger(Logger logger)
+    {
+        this.logger = logger;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public Logger getLogger()
+    {
+        return logger;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public void setSupportedFileExtensions(String mimeType, String[] extensions)
+    {
+        mimeMappings.set(mimeType, extensions);
+    }
+
+    /**
+     * Sets the output destination. This method is necessary if you use the <code>build(boolean)</code> method.
+     * If you use the <code>build(OutputStream, boolean)</code> method, there is no need to use this method.
+     *
+     * @param output An instance of the <code>java.io.File</code> class.
+     */
+    public void setOutput(File output)
+    {
+        this.output = output;
+    }
+
+    /**
+     * Gets the output destination. This method returns <code>null</code> if you did not call the
+     * <code>setOutput()</code> method.
+     *
+     * @return An instance of the <code>java.io.File</code> class, or <code>null</code> if you did not
+     * call the <code>setOutput()</code> method.
+     */
+    public File getOutput()
+    {
+        return output;
+    }
+
+    /**
+     * Sets the RSL output directory.
+     *
+     * @param directory An RSL directory.
+     */
+    public void setDirectory(File directory)
+    {
+        this.directory = directory;
+    }
+
+    /**
+     * Gets the RSL output directory.
+     *
+     * @return A <code>java.io.File</code>, or <code>null</code> if you did not call the <code>setDirectory()</code> method.
+     */
+    public File getDirectory()
+    {
+        return directory;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public void setProgressMeter(ProgressMeter meter)
+    {
+        this.meter = meter;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public void setPathResolver(PathResolver resolver)
+    {
+        this.resolver = resolver;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    // IMPORTANT: If you make changes here, you probably want to mirror them in Application.build()
+    public long build(boolean incremental) throws IOException
+    {
+        // I know that directory is not referenced anywhere in here...
+        // if you setDirectory but do not setOutput, then output==null but dirctory!=null
+        // so this silly looking IF needs to be like this...
+        if (output != null || directory != null)
+        {
+            long size = 0;
+
+            //TODO PERFORMANCE: A lot of unnecessary recopying and buffering here
+            try
+            {
+                int result = compile(incremental);
+
+                return size;
+            }
+            finally
+            {                
+                //runExtensions();
+                
+                clean(false /* cleanData */,
+                      false /* cleanCache */,
+                      false /* cleanOutput */,
+                      true /* cleanConfig */,
+                      false /* cleanMessages */,
+                      true /* cleanThreadLocals */);
+            }
+        }
+        else
+        {
+            return 0;
+        }
+    }
+
+    /*
+    private void runExtensions()
+    {
+        if (oemConfiguration != null)
+        {
+            Set<ILibraryExtension> extensions = ExtensionManager.getLibraryExtensions( oemConfiguration.getExtensions() );
+
+            for ( ILibraryExtension extension : extensions )
+            {
+                if (ThreadLocalToolkit.errorCount() == 0)
+                {
+                    extension.run( this.clone(), oemConfiguration.clone() );
+                }
+            }
+        }
+    }
+    */
+    
+    /**
+     * @inheritDoc
+     * 
+     * Note: If the OutputStream is written to a File,
+     * refreshLastModified() should be called to update the timestamp
+     * in the SwcCache.  Otherwise, subsequent builds in this Project
+     * will think the Library has been externally updated and will
+     * force a reload.
+     */
+    public long build(OutputStream out, boolean incremental) throws IOException
+    {
+        try
+        {
+            int result = compile(incremental);
+
+            /*
+            if (result == SKIP || result == LINK || result == OK)
+            {
+                return link(out);
+            }
+            else
+            {
+            */
+                return 0;
+            //}
+        }
+        finally
+        {
+            //runExtensions();
+            
+            clean(false /* cleanData */,
+                  false /* cleanCache */,
+                  false /* cleanOutput */,
+                  true /* cleanConfig */,
+                  false /* cleanMessages */,
+                  true /* cleanThreadLocals */);
+        }
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public void stop()
+    {
+        cc.stop();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public void clean()
+    {
+        clean(true /* cleanData */,
+              true /* cleanCache */,
+              true /* cleanOutput */,
+              true /* cleanConfig */,
+              true /* cleanMessages */,
+              true /* cleanThreadLocals */);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public void load(InputStream in) throws IOException
+    {
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public long save(OutputStream out) throws IOException
+    {
+        return 1;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public Report getReport()
+    {
+        //OEMUtil.setupLocalizationManager();
+        return new OEMReport(null,
+                             null,
+                             null,
+                             null,
+                             configurationReport,
+                             messages, files);
+    }
+
+    /**
+     *
+     * @param c
+     * @return
+     */
+    private String[] constructCommandLine(OEMConfiguration localOEMConfiguration)
+    {
+        String[] commandLine = (localOEMConfiguration != null) ? localOEMConfiguration.getCompilerOptions() : 
+                                                                 new String[0];
+        
+        // Translate "classes" into "-include-classes" so the CompcConfiguration can
+        // properly validate the configuration.
+        if (classes.size() > 0)
+        {
+            StringBuilder buffer = new StringBuilder("-include-classes=");
+
+            for (Iterator<String> iter = classes.iterator(); iter.hasNext();)
+            {
+                String className = iter.next();
+                buffer.append(className);
+                if (iter.hasNext())
+                {
+                    buffer.append(",");
+                }
+            }
+            
+            String[] newCommandLine = new String[commandLine.length + 1];
+            System.arraycopy(commandLine, 0, newCommandLine, 0, commandLine.length);
+            newCommandLine[commandLine.length] = buffer.toString();
+            
+            return newCommandLine;
+        }
+
+        return commandLine;
+    }
+
+
+    /**
+     * Compiles the <code>Library</code>. This method does not link the <code>Library</code>.
+     *
+     * @param incremental If <code>true</code>, build incrementally; if <code>false</code>, rebuild.
+     * @return  {@link Builder#OK} if this method call resulted in compilation of some/all parts of the application;
+     *          {@link Builder#LINK} if this method call did not compile anything in the application but advise the caller to link again;
+     *          {@link Builder#SKIP} if this method call did not compile anything in the application;
+     *          {@link Builder#FAIL} if this method call encountered errors during compilation.
+     */
+    protected int compile(boolean incremental)
+    {
+        try 
+        {
+        messages.clear();
+
+        // if there is no configuration, use the default... but don't populate this.configuration.
+        OEMConfiguration tempOEMConfiguration;
+
+        if (oemConfiguration == null)
+        {
+            tempOEMConfiguration = (OEMConfiguration) getDefaultConfiguration(true);
+        }
+        else
+        {
+            tempOEMConfiguration = OEMUtil.getLibraryConfiguration(constructCommandLine(oemConfiguration),
+                                                                   oemConfiguration.keepLinkReport(),
+                                                                   oemConfiguration.keepSizeReport(),
+                                                                   OEMUtil.getLogger(logger, messages),
+                                                                   resolver, mimeMappings);
+        }
+
+        // if c is null, which indicates problems, this method will return.
+        if (tempOEMConfiguration == null)
+        {
+            clean(false /* cleanData */, false /* cleanCache */, false /* cleanOutput */);
+            return FAIL;
+        }
+        else if (oemConfiguration != null && oemConfiguration.keepConfigurationReport())
+        {
+            configurationReport = OEMUtil.formatConfigurationBuffer(tempOEMConfiguration.cfgbuf);
+        }
+
+        if (oemConfiguration != null)
+        {
+            oemConfiguration.cfgbuf = tempOEMConfiguration.cfgbuf;
+        }
+
+        // add archive files to the link checksum
+        for (Map.Entry<String, VirtualFile>entry : files.entrySet())
+        {
+            tempOEMConfiguration.cfgbuf.calculateLinkChecksum(entry.getKey(), entry.getValue().getLastModified());
+        }            
+
+        // initialize some ThreadLocal variables...
+        cc.run();
+        OEMUtil.init(OEMUtil.getLogger(logger, messages), mimeMappings, meter, resolver, cc);
+
+        // if there is any problem getting the licenses, this method will return.
+        Map licenseMap = OEMUtil.getLicenseMap(tempOEMConfiguration.configuration);
+
+        // if there are no SWC inputs, output an error and return -1
+        VirtualFile[] includeLibs = (tempOEMConfiguration.configuration == null) ? null : tempOEMConfiguration.configuration.getCompilerConfiguration().getIncludeLibraries();
+        if (sources.size() == 0 && classes.size() == 0 && namespaces.size() == 0 &&
+            resourceBundles.size() == 0 && files.size() == 0 && stylesheets.size() == 0 &&
+            (includeLibs == null || includeLibs.length == 0))
+        {
+            ThreadLocalToolkit.log(new ConfigurationException.NoSwcInputs( null, null, -1 ));
+            clean(false /* cleanData */, false /* cleanCache */, false /* cleanOutput */);
+            return FAIL;
+        }
+
+
+        CompilerConfiguration compilerConfig = tempOEMConfiguration.configuration.getCompilerConfiguration();
+        compilerConfig.setMetadataExport(true);
+
+
+        clean(true /* cleanData */,
+              false /* cleanCache */,
+              false /* cleanOutput */,
+              true /* cleanConfig */,
+              false /* cleanMessages */,
+              false /* cleanThreadLocals */);
+        int returnValue = COMPC.staticMainNoExit(constructCommandLine(tempOEMConfiguration));
+
+        clean(returnValue != OK, false, false);
+        return returnValue;
+
+        }
+        finally
+        {
+            // clean thread locals
+            OEMUtil.clean();
+        }
+    }
+        
+
+    /**
+     *
+     * @param cleanData
+     * @param cleanCache
+     * @param cleanOutput
+     */
+    private void clean(boolean cleanData, boolean cleanCache, boolean cleanOutput)
+    {
+        clean(cleanData,
+              cleanCache,
+              cleanOutput,
+              true /* cleanConfig */,
+              false /* cleanMessages */,
+              false /* cleanThreadLocals */);
+    }
+
+    /**
+     *
+     * @param cleanData
+     * @param cleanCache
+     * @param cleanOutput
+     * @param cleanConfig
+     * @param cleanMessages
+     * @param cleanThreadLocals
+     */
+    private void clean(boolean cleanData, boolean cleanCache, boolean cleanOutput,
+                       boolean cleanConfig, boolean cleanMessages, boolean cleanThreadLocals)
+    {
+        if (cleanThreadLocals)
+        {
+            OEMUtil.clean();
+        }
+        
+        if (oemConfiguration != null && cleanConfig)
+        {
+            oemConfiguration.reset();
+        }
+
+        if (cleanData)
+        {
+            //data = null;
+            configurationReport = null;
+        }
+
+        if (cleanCache)
+        {
+            if (cacheName != null)
+            {
+                File dead = FileUtil.openFile(cacheName);
+                if (dead != null && dead.exists())
+                {
+                    dead.delete();
+                }
+                cacheName = null;
+            }
+        }
+
+        if (cleanOutput)
+        {
+            if (output != null && output.exists())
+            {
+                output.delete();
+            }
+        }
+
+        if (cleanMessages)
+        {
+            messages.clear();
+        }
+    }
+
+    /**
+     *
+     * @param s1
+     * @param s2
+     * @return
+     */
+    private <T> boolean isDifferent(Collection<T> s1, Collection<T> s2)
+    {
+        for (Iterator<T> i = s2.iterator(); i.hasNext(); )
+        {
+            if (!s1.contains(i.next()))
+            {
+                return true;
+            }
+        }
+
+        return s1.size() > s2.size();
+    }
+
+    
+    /**
+     * Returns the cache of sources in the source list and source
+     * path.  After building this Application object, the cache may be
+     * used to compile another Application object with common sources.
+     *
+     * @return The active cache. May be null.
+     *
+     * @since 4.5
+     */
+    public ApplicationCache getApplicationCache()
+    {
+        return applicationCache;
+    }
+
+    /**
+     * Sets the cache for sources in the source list and source path.
+     * After compiling an Application object, the cache may be reused
+     * to build another Application object with common sources.
+     *
+     * @param applicationCache A reference to the application cache.
+     *
+     * @since 4.5
+     */
+    public void setApplicationCache(ApplicationCache applicationCache)
+    {
+        this.applicationCache = applicationCache;
+    }
+
+    // TODO: deprecate getSwcCache() and setSwcCache(), then add
+    // getLibraryCache() and setLibraryCache().
+    /**
+     * Get the cache of swcs in the library path. After building this Application
+     * object the cache may be saved and used to compile another Application object
+     * that uses the same library path.
+     *
+     * @return The active cache. May be null.
+     *
+     * @since 3.0
+     */
+    public LibraryCache getSwcCache()
+    {
+        return libraryCache;
+    }
+
+    /**
+     * Set the cache for swcs in the library path. After compiling an
+     * Application object the cache may be reused to build another Application
+     * object that uses the same library path.
+     *
+     * @param swcCache A reference to an allocated swc cache.
+     *
+     * @since 3.0
+     */
+    public void setSwcCache(LibraryCache libraryCache)
+    {
+        this.libraryCache = libraryCache;
+    }
+
+    @Override
+    public Library clone()
+    {
+        Library clone;
+        try
+        {
+            clone = (Library) super.clone();
+        }
+        catch ( CloneNotSupportedException e )
+        {
+            throw new RuntimeException( e ); //wont happen
+        }
+        clone.oemConfiguration = oemConfiguration.clone();
+        return clone;
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dff3a518/flex-compiler-oem/src/flex2/tools/oem/LibraryCache.java
----------------------------------------------------------------------
diff --git a/flex-compiler-oem/src/flex2/tools/oem/LibraryCache.java b/flex-compiler-oem/src/flex2/tools/oem/LibraryCache.java
new file mode 100644
index 0000000..60ae11f
--- /dev/null
+++ b/flex-compiler-oem/src/flex2/tools/oem/LibraryCache.java
@@ -0,0 +1,33 @@
+/*
+ *
+ *  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;
+
+/**
+ * A cache of library files that is designed to be used to compile
+ * Application and Library objects, which ideally have some common
+ * library path elements.
+ *
+ * @since 3.0
+ * @author dloverin
+ */
+public class LibraryCache
+{
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dff3a518/flex-compiler-oem/src/flex2/tools/oem/Logger.java
----------------------------------------------------------------------
diff --git a/flex-compiler-oem/src/flex2/tools/oem/Logger.java b/flex-compiler-oem/src/flex2/tools/oem/Logger.java
new file mode 100644
index 0000000..ca5c63f
--- /dev/null
+++ b/flex-compiler-oem/src/flex2/tools/oem/Logger.java
@@ -0,0 +1,53 @@
+/*
+ *
+ *  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;
+
+/**
+ * The <code>Logger</code> interface is the Flex compiler logging mechanism for OEM applications.
+ * You implement this interface and provide an instance of the implementation to the 
+ * <code>Application.setLogger()</code> and/or <code>Library.setLogger()</code> methods.
+ * 
+ * <p>
+ * The Flex compiler API exposes warnings and errors as <code>Message</code> objects.
+ * You can use the <code>Message.getClass().getName()</code> method to differentiate
+ * between message types programmatically.
+ * 
+ * <p>
+ * The compiler utilizes some third-party libraries that use error-code-based
+ * logging systems. As a result, the <code>log()</code> method also supports error codes.
+ * 
+ * @version 2.0.1
+ * @author Clement Wong
+ */
+public interface Logger
+{
+    // C: Ideally, errorCode and source should be in Message...
+    // void log(Message message);
+    
+    /**
+     * Logs a compiler message.
+     *  
+     * @param message An object that implements the <code>flex2.tools.oem.Message</code> interface.
+     * @param errorCode Error code. -1 if an error code is not available.
+     * @param source Source code line number specified by the <code>message.getLine()</code> method.
+     *               <code>null</code> if the compiler message is not associated with any source file.
+     */
+    void log(Message message, int errorCode, String source);
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dff3a518/flex-compiler-oem/src/flex2/tools/oem/Message.java
----------------------------------------------------------------------
diff --git a/flex-compiler-oem/src/flex2/tools/oem/Message.java b/flex-compiler-oem/src/flex2/tools/oem/Message.java
new file mode 100644
index 0000000..77f8b4b
--- /dev/null
+++ b/flex-compiler-oem/src/flex2/tools/oem/Message.java
@@ -0,0 +1,93 @@
+/*
+ *
+ *  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;
+
+/**
+ * The <code>Message</code> interface lets you discover
+ * the following information about a compiler message.
+ * 
+ * <pre>
+ * 1. getLevel()    - Error level: error, warning or info.
+ * 2. getPath()     - Location.
+ * 3. getLine()     - Line number.
+ * 4. getColumn()   - Column number.
+ * 5. toString()    - Message string.
+ * </pre>
+ *
+ * The <code>Message.toString()</code> method returns the message text.
+ * 
+ * @version 2.0.1
+ * @author Clement Wong
+ */
+public interface Message
+{
+    /**
+     * Indicates that the severity of this <code>Message</code> is "<code>error</code>".
+     */
+    String ERROR = "error";
+    
+    /**
+     * Indicates that the severity of this <code>Message</code> is "<code>warning</code>".
+     */
+    String WARNING = "warning";
+    
+    /**
+     * Indicates that the severity of this <code>Message</code> is "<code>info</code>".
+     */
+    String INFO = "info";
+    
+    /**
+     * Returns the compiler message severity level.
+     * 
+     * @return One of <code>Message.ERROR</code>, <code>Message.WARNING</code>, or <code>Message.INFO</code>.
+     * @see #ERROR
+     * @see #WARNING
+     * @see #INFO
+     */
+    String getLevel();
+
+    /**
+     * Returns the location of the file that contains the error.
+     * 
+     * @return String; <code>null</code> if the path is not applicable.
+     */
+    String getPath();
+    
+    /**
+     * Returns the line number of the file that contains the error.
+     * 
+     * @return An integer; <code>-1</code> if the line number is not applicable.
+     */
+    int getLine();
+    
+    /**
+     * Returns the column number of the file that contains the error.
+     * 
+     * @return An integer; <code>-1</code> if the column number is not applicable.
+     */
+    int getColumn();
+    
+    /**
+     * Returns the message.
+     * 
+     * @return A string.
+     */
+    String toString();
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dff3a518/flex-compiler-oem/src/flex2/tools/oem/PathResolver.java
----------------------------------------------------------------------
diff --git a/flex-compiler-oem/src/flex2/tools/oem/PathResolver.java b/flex-compiler-oem/src/flex2/tools/oem/PathResolver.java
new file mode 100644
index 0000000..a30900e
--- /dev/null
+++ b/flex-compiler-oem/src/flex2/tools/oem/PathResolver.java
@@ -0,0 +1,39 @@
+/*
+ *
+ *  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;
+
+import java.io.File;
+
+/**
+ * Defines the API for path resolution.
+ *
+ * @version 3.0
+ * @author Clement Wong
+ * @author Brian Deitte
+ */
+public interface PathResolver
+{
+	/**
+	 * 
+	 * @param relative
+	 * @return
+	 */
+	File resolve(String relative);
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dff3a518/flex-compiler-oem/src/flex2/tools/oem/ProgressMeter.java
----------------------------------------------------------------------
diff --git a/flex-compiler-oem/src/flex2/tools/oem/ProgressMeter.java b/flex-compiler-oem/src/flex2/tools/oem/ProgressMeter.java
new file mode 100644
index 0000000..dc641da
--- /dev/null
+++ b/flex-compiler-oem/src/flex2/tools/oem/ProgressMeter.java
@@ -0,0 +1,52 @@
+/*
+ *
+ *  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;
+
+/**
+ * The <code>ProgressMeter</code> interface lets you get periodic updates from the compiler
+ * about the compilation progress.
+ * 
+ * <p>
+ * Providing a progress meter to the compiler is optional. If you want to
+ * know about compilation progress, you must implement this interface and provide an
+ * instance of the implementation to the <code>Application.setProgressMeter()</code> and/or
+ * <code>Library.setProgressMeter()</code> methods.
+ * 
+ * @version 2.0.1
+ * @author Clement Wong
+ */
+public interface ProgressMeter
+{
+    /**
+     * Notifies the caller that the compilation has begun. 
+     */
+    void start();
+    
+    /**
+     * Notifies the caller that the compilation has ended.
+     */
+    void end();
+    
+    /**
+     * Notifies the caller of the percentage of compilation done by the compiler.
+     * @param n An integer. Valid values are <code>0</code> through <code>100</code>.
+     */
+    void percentDone(int n);
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dff3a518/flex-compiler-oem/src/flex2/tools/oem/Report.java
----------------------------------------------------------------------
diff --git a/flex-compiler-oem/src/flex2/tools/oem/Report.java b/flex-compiler-oem/src/flex2/tools/oem/Report.java
new file mode 100644
index 0000000..eb31f7f
--- /dev/null
+++ b/flex-compiler-oem/src/flex2/tools/oem/Report.java
@@ -0,0 +1,353 @@
+/*
+ *
+ *  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;
+
+import java.io.IOException;
+import java.io.Writer;
+
+/**
+ * The <code>Report</code> interface provides information about the composition
+ * of an <code>Application</code> or a <code>Library</code>.
+ * 
+ * @see flex2.tools.oem.Builder#getReport()
+ * @version 2.0.1
+ * @author Clement Wong
+ */
+public interface Report
+{
+    /**
+     * Use this constant when querying information from the compiler.
+     */
+    Object COMPILER = "COMPILER";
+    
+    /**
+     * Use this constant when querying information from the linker.
+     */
+    Object LINKER = "LINKER";
+    
+    /**
+     * Gets the name of all the sources that are involved in the <code>Application</code> or <code>Library</code>.
+     * The <code>getSourceNames(Report.COMPILER)</code> method returns the name of all the source files
+     * that are involved in the compilation.
+     * 
+     * <p>
+     * The <code>getSourceNames(Report.LINKER)</code> method returns the name of all the source files
+     * that are eventually output by the linker. 
+     * 
+     * <p>
+     * The <code>getSourceNames(Report.COMPILER)</code> 
+     * and <code>getSourceNames(Report.LINKER)</code> methods can yield different results if the linker is
+     * instructed to exclude certain definitions from the final output.
+     * 
+     * @see #COMPILER
+     * @see #LINKER
+     * 
+     * @param report The <code>COMPILER</code> or <code>LINKER</code>.
+     * 
+     * @return A list of source names.
+     */
+    String[] getSourceNames(Object report);
+    
+    /**
+     * Gets the names of all the assets that are involved in the <code>Application</code> or <code>Library</code>.
+     * The <code>getAssetNames(Report.COMPILER)</code> method returns the names of all the asset files
+     * that are involved in the compilation.
+     * 
+     * <p>
+     * The <code>getAssetNames(Report.LINKER)</code> method returns the names of all the asset files
+     * that are eventually output by the linker. 
+     * 
+     * <p>
+     * The <code>getAssetNames(Report.COMPILER)</code> 
+     * and <code>getAssetNames(Report.LINKER)</code> methods can yield different results if the linker is
+     * instructed to exclude certain definitions from the final output.
+     * 
+     * @see #COMPILER
+     * @see #LINKER
+     * 
+     * @param report The <code>COMPILER</code> or <code>LINKER</code>.
+     * 
+     * @return A list of asset names.
+     */
+    String[] getAssetNames(Object report);
+    
+    /**
+     * Gets the names of all the assets that are in the specified frame.
+     * The number of frames in the movie can be obtained by invoking <code>getFrameCount()</code>.
+     * 
+     * <p>
+     * If the compilation did not generate a movie, this method returns <code>null</code>.
+     * 
+     * @see #getFrameCount()
+     * @param frame frame number. The number is 1-based.
+     * @return an array of asset file names
+     */
+    String[] getAssetNames(int frame);
+
+    /**
+     * Gets the name of all the libraries that are involved in the <code>Application</code> or <code>Library</code>.
+     * The <code>getLibraryNames(Report.COMPILER)</code> method returns the name of all the library files
+     * that are involved in the compilation.
+     * 
+     * <p>
+     * The <code>getLibraryNames(Report.LINKER)</code> method returns the name of all the library files
+     * that are eventually output by the linker. 
+     * 
+     * <p>
+     * The <code>getLibraryNames(Report.COMPILER)</code>
+     * and <code>getLibraryNames(Report.LINKER)</code> methods can yield different results if the linker is
+     * instructed to exclude certain definitions from the final output.
+     * 
+     * @see #COMPILER
+     * @see #LINKER
+     * 
+     * @param report The <code>COMPILER</code> or <code>LINKER</code>.
+     * 
+     * @return A list of library names.
+     */
+    String[] getLibraryNames(Object report);
+    
+    /**
+     * Gets the name of all the resource bundles that are involved in the Application/Library.
+     * The <code>getResourceBundleNames()</code> method returns a list of names that
+     * can be passed to the <code>Library.addResourceBundle()</code> method.
+     * 
+     * <p>
+     * The returned value should match the output from the <code>resource-bundle-list</code> compiler option.
+     * 
+     * @return A list of resource bundle names.
+     */
+    String[] getResourceBundleNames();
+
+    /**
+     * Gets the list of all the top-level, externally-visible definitions in the specified
+     * source file. You can get the specified source file from the <code>getSourceNames()</code> method.
+     * 
+     * <p>
+     * The output definition names are in the QName format; for example: <code>mx.controls:Button</code>.
+     * 
+     * @param sourceName Source file name.
+     * @return An array of definition names; <code>null</code> if there is no definition in the source file.
+     */
+    String[] getDefinitionNames(String sourceName);
+    
+    /**
+     * Gets the list of all the top-level, externally-visible definitions in the specified frame.
+     * The sequence represents the order in which the definitions are exported to the frame.
+     * The number of frames in the movie can be obtained by invoking <code>getFrameCount()</code>.
+     * 
+     * <p>
+     * If the compilation did not generate a movie, this method returns <code>null</code>.
+     * 
+     * @see #getFrameCount()
+     * @param frame frame number. The number is 1-based.
+     * @return an array of definition names
+     */
+    String[] getDefinitionNames(int frame);
+    
+    /**
+     * Gets the location of the specified definition.
+     * 
+     * <p>
+     * The specified definition name must be in the QName format; for example: <code>mx.controls:Button</code>.
+     * 
+     * @param definition A definition is a class, function, variable, or namespace.
+     * @return The location of the specified definition; <code>null</code> if the definition is not found.
+     */
+    String getLocation(String definition);
+    
+    /**
+     * Gets the list of definitions that the specified definition depends on during initialization.
+     *  
+     * <p>
+     * The specified definition name must be in the QName format; for example: <code>mx.controls:Button</code>.
+     * 
+     * @param definition A class.
+     * 
+     * @return An array of definition names; <code>null</code> if there is no dependency.
+     */
+    String[] getPrerequisites(String definition);
+    
+    /**
+     * Gets the list of definitions that the specified definition depends on during run time.
+     *  
+     * <p>
+     * The specified definition name must be in the QName format; for example: <code>mx.controls:Button</code>.
+     * 
+     * @param definition A definition is a class, function, variable, or namespace.
+     * 
+     * @return An array of definition names; <code>null</code> if there is no dependency.
+     */
+    String[] getDependencies(String definition);
+
+    /**
+     * Writes the linker report to the specified output. If this <code>Report</code> was generated before linking,
+     * this method returns <code>0</code>. You should provide a <code>BufferedWriter</code>, if possible. 
+     * You should be sure to close the specified <code>Writer</code>.
+     * 
+     * <p>
+     * To use this method, you must call the <code>Configuration.keepLinkReport()</code> method 
+     * before the compilation.
+     * 
+     * @param out An instance of <code>Writer</code>.
+     * 
+     * @return The number of characters written out.
+     * 
+     * @throws IOException Thrown when an I/O error occurs while the link report is being written.
+     * 
+     * @see flex2.tools.oem.Configuration#keepLinkReport(boolean)
+     */
+    long writeLinkReport(Writer out) throws IOException;
+    
+    /**
+     * Writes the linker size report to the specified output. If this <code>Report</code> was generated before linking,
+     * this method returns <code>0</code>. You should provide a <code>BufferedWriter</code>, if possible. 
+     * You should be sure to close the specified <code>Writer</code>.
+     * 
+     * <p>
+     * To use this method, you must call the <code>Configuration.keepSizeReport()</code> method 
+     * before the compilation.
+     * 
+     * @param out An instance of <code>Writer</code>.
+     * 
+     * @return The number of characters written out.
+     * 
+     * @throws IOException Thrown when an I/O error occurs while the link report is being written.
+     * 
+     * @see flex2.tools.oem.Configuration#keepSizeReport(boolean)
+     */
+    long writeSizeReport(Writer out) throws IOException;
+    
+    /**
+     * Writes the configuration report to the specified output.
+     * You should provide a <code>BufferedWriter</code>, if possible. 
+     * Be sure to close the specified <code>Writer</code>.
+     * 
+     * <p>
+     * To use this method, you must call the <code>Configuration.keepConfigurationReport()</code> method 
+     * before the compilation.
+     * 
+     * @param out An instance of <code>Writer</code>.
+     * 
+     * @return The number of characters written out.
+     * 
+     * @throws IOException Thrown when an I/O error occurs during writing the configuration report.
+     * 
+     * @see flex2.tools.oem.Configuration#keepConfigurationReport(boolean)
+     */
+    long writeConfigurationReport(Writer out) throws IOException;
+    
+    /**
+     * Gets the background color. The default value is <code>0x869CA7</code>.
+     * If the <code>Report</code> was generated before linking, this method returns <code>0</code>.
+     * 
+     * @return An RGB value.
+     */
+    int getBackgroundColor();
+    
+    /**
+     * Gets the page title.
+     * If the <code>Report</code> was generated before linking, this method returns <code>null</code>.
+     * 
+     * @return Page title; <code>null</code> if it was not specified.
+     */
+    String getPageTitle();
+    
+    /**
+     * Gets the default width of the application. The default value is <code>500</code>.
+     * 
+     * @return The default width, in pixels.
+     */
+    int getDefaultWidth();
+    
+    /**
+     * Gets the default height of the application. The default value is <code>375</code>.
+     * 
+     * @return The default height, in pixels.
+     */
+    int getDefaultHeight();
+    
+    /**
+     * Gets the user-defined width.
+     * If the <code>Report</code> was generated before linking, this method returns <code>0</code>.
+     * 
+     * @return Width of the application, in pixels; <code>0</code> if it was not specified.
+     */
+    int getWidth();
+    
+    /**
+     * Gets the user-defined height.
+     * If the <code>Report</code> was generated before linking, this method returns <code>0</code>.
+     * 
+     * @return Height, in pixels; <code>0</code> if it was not specified.
+     */
+    int getHeight();
+    
+    /**
+     * Gets the user-defined width percentage.
+     * If the <code>Report</code> was generated before linking, this method returns <code>0.0</code>.
+     * 
+     * @return Width percentage; <code>0.0</code> if it was not specified.
+     */
+    double getWidthPercent();
+    
+    /**
+     * Gets the user-defined height percentage.
+     * If the <code>Report</code> was generated before linking, this method returns <code>0.0</code>.
+     * 
+     * @return Height percentage; <code>0.0</code> if it was not specified.
+     */
+    double getHeightPercent();
+    
+    /**
+     * Outputs the compiler version.
+     * 
+     * @return A string representing the compiler version.
+     */
+    String getCompilerVersion();
+    
+    /**
+     * Reports the errors and warnings that were generated during the compilation. The returned
+     * <code>Message</code> objects are errors and warnings.
+     * 
+     * @return An array of error and warning Message objects; <code>null</code> if there were no errors or warnings.
+     */
+    Message[] getMessages();
+
+    /**
+     * Gets the number of frames in the movie. For <code>Application</code>, the returned
+     * value is the number of frames in the movie. For <code>Library</code>, the returned
+     * value is the number of frames in library.swf.
+     * 
+     * <p>
+     * If the compilation did not generate a movie, the returned value will be <code>0</code>.
+     * 
+     * @return number of frames
+     */
+    int getFrameCount();
+    
+    /**
+     * Checks whether the sources, assets and libraries have been updated since the report was created.
+     * 
+     * @since 3.0
+     * @return
+     */
+    boolean contentUpdated();
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dff3a518/flex-compiler-oem/src/flex2/tools/oem/VirtualLocalFile.java
----------------------------------------------------------------------
diff --git a/flex-compiler-oem/src/flex2/tools/oem/VirtualLocalFile.java b/flex-compiler-oem/src/flex2/tools/oem/VirtualLocalFile.java
new file mode 100644
index 0000000..d105543
--- /dev/null
+++ b/flex-compiler-oem/src/flex2/tools/oem/VirtualLocalFile.java
@@ -0,0 +1,245 @@
+/*
+ *
+ *  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;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+import flex2.compiler.io.FileUtil;
+import flex2.compiler.io.VirtualFile;
+import flex2.compiler.util.MimeMappings;
+
+/**
+ * The <code>VirtualLocalFile</code> class represents a source file in memory. Each <code>VirtualLocalFile</code> instance
+ * is given a parent that corresponds to a valid directory in the filesystem. Path
+ * resolution is done as if <code>VirtualLocalFile</code> instances represented real files in the filesystem.
+ * 
+ * <p>
+ * You can not create an instance of the <code>VirtualLocalFile</code> class directly. You must 
+ * use the <code>VirtualLocalFileSystem</code> class to create them.
+ * 
+ * @see flex2.tools.oem.VirtualLocalFileSystem 
+ * @version 2.0.1
+ * @author Clement Wong
+ */
+public class VirtualLocalFile implements VirtualFile
+{
+    /**
+     * Constructs a <code>VirtualLocalFile</code> object. You cannnot use this constructor directly. 
+     * You must use the <code>VirtualLocalFileSystem.create()</code> to create <code>VirtualLocalFile</code> instances.
+     * 
+     * @param name A canonical path.
+     * @param mimeType The MIME type.
+     * @param text Source code.
+     * @param parent The parent directory of this <code>VirtualLocalFile</code> object.
+     * @param lastModified The last modified time.
+     * @param fs An instance of the <code>VirtualLocalFileSystem</code> class.
+     */
+    VirtualLocalFile(String name, String text, File parent, long lastModified, VirtualLocalFileSystem fs)
+    {
+        this.name = name;
+        this.text = text;
+        this.parent = FileUtil.getCanonicalFile(parent);
+        this.lastModified = lastModified;
+        this.fs = fs;
+
+        assert this.parent.isDirectory();
+    }
+
+    String text;
+    private File parent;
+    private String name;
+    private String mimeType;
+    long lastModified;
+    private VirtualLocalFileSystem fs;
+
+    /**
+     * Gets the name of this <code>VirtualLocalFile</code> object. This is sually a canonical path.
+     * 
+     * @return The name of this <code>VirtualLocalFile</code> object.
+     */
+    public String getName()
+    {
+        return name;
+    }
+
+    /**
+     * Gets the name of this <code>VirtualLocalFile</code> for error reporting. This is usually a canonical path.
+     * 
+     * @return The name used when reporting warnings and errors.
+     * 
+     * @see #getName()
+     */
+    public String getNameForReporting()
+    {
+        return getName();
+    }
+
+    /**
+     * Throws an <code>UnsupportedOperationException</code> exception.
+     */
+    public String getURL()
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Gets the parent directory path of this <code>VirtualLocalFile</code> object.
+     * 
+     * @return The parent's canonical path.
+     */
+    public String getParent()
+    {
+        return FileUtil.getCanonicalPath(parent);
+    }
+    
+    /**
+     * Returns <code>true</code> if this <code>VirtualLocalFile</code> object is a directory. This method always returns <code>false</code>.
+     * 
+     * @return <code>false</code>.
+     */
+    public boolean isDirectory()
+    {
+        return false;
+    }
+
+    /**
+     * Returns the length of the text in this <code>VirtualLocalFile</code> object.
+     * 
+     * @return The length of the text.
+     */
+    public long size()
+    {
+        return text == null ? 0 : text.length();
+    }
+
+    /**
+     * Returns The MIME type of this <code>VirtualLocalFile</code> object.
+     * 
+     * @return The MIME type.
+     */
+    public String getMimeType()
+    {
+        if (mimeType == null)
+        {
+            mimeType = MimeMappings.getMimeType(name);
+        }
+        return mimeType;
+    }
+
+    /**
+     * Returns the text in this <code>VirtualLocalFile</code> object in an <code>InputStream</code>.
+     * The text is converted into a byte stream based on <code>UTF-8</code> encoding.
+     * 
+     * @return An <code>InputStream</code>.
+     * 
+     * @throws IOException Thrown when an I/O error occurs.
+     */
+    public InputStream getInputStream() throws IOException
+    {
+        return new ByteArrayInputStream(text == null ? new byte[0] : text.getBytes("UTF-8"));
+    }
+
+    /**
+     * Returns the text in this <code>VirtualLocalFile</code> object in an <code>byte[]</code>.
+     */
+    public byte[] toByteArray() throws IOException
+    {
+        return text == null ? new byte[0] : text.getBytes("UTF-8");
+    }
+
+    /**
+     * Gets the last modified time of this <code>VirtualLocalFile</code> object.
+     * 
+     * @return The last modified time.
+     */
+    public long getLastModified()
+    {
+        return lastModified;
+    }
+
+    /**
+     * Resolves the specified relative path to a <code>VirtualFile</code> instance.
+     * 
+     * @param relativeStr The relative path to be resolved.
+     * 
+     * @return If successful, a <code>VirtualFile</code> for <code>relativeStr</code>.
+     */
+    public VirtualFile resolve(String relativeStr)
+    {
+        return fs.resolve(this, relativeStr);
+    }
+
+    /**
+     * Closes this <code>VirtualLocalFile</code> object. This method does nothing.
+     */
+    public void close()
+    {
+    }
+
+    /**
+     * Compares this object with the specified object.
+     * 
+     * @param obj An Object.
+     * 
+     * @return <code>true</code> if <code>obj == this</code>.
+     */
+    public boolean equals(Object obj)
+    {
+        if (obj instanceof VirtualLocalFile)
+        {
+            return (this == obj) || getName().equals(((VirtualLocalFile) obj).getName());
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    /**
+     * Returns the hash code of this <code>VirtualLocalFile</code> object.
+     * 
+     * @return The hashCode.
+     */
+    public int hashCode()
+    {
+        return getName().hashCode();
+    }
+
+    /**
+     * Returns <code>true</code> if the content of this <code>VirtualLocalFile</code> object is text based.
+     * This method always returns <code>true</code>.
+     * 
+     * @return <code>true</code>.
+     */
+    public boolean isTextBased()
+    {
+        return true;
+    }
+    
+    public String toString()
+    {
+        return text;
+    }
+}
+
+

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dff3a518/flex-compiler-oem/src/flex2/tools/oem/VirtualLocalFileSystem.java
----------------------------------------------------------------------
diff --git a/flex-compiler-oem/src/flex2/tools/oem/VirtualLocalFileSystem.java b/flex-compiler-oem/src/flex2/tools/oem/VirtualLocalFileSystem.java
new file mode 100644
index 0000000..7ed2bf3
--- /dev/null
+++ b/flex-compiler-oem/src/flex2/tools/oem/VirtualLocalFileSystem.java
@@ -0,0 +1,130 @@
+/*
+ *
+ *  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;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+import flex2.compiler.io.FileUtil;
+import flex2.compiler.io.LocalFile;
+import flex2.compiler.io.VirtualFile;
+
+/**
+ * The <code>VirtualLocalFileSystem</code> class serves as a factory for creating <code>VirtualLocalFile</code> instances.
+ * It also helps <code>VirtualLocalFile</code> instances resolve relative paths that might point to other
+ * <code>VirtualLocalFile</code> instances or "real" files in the file system.
+ * 
+ * @see flex2.tools.oem.VirtualLocalFile
+ * @version 2.0.1
+ * @author Clement Wong
+ */
+public class VirtualLocalFileSystem
+{
+    /**
+     * Constructor.
+     */
+    public VirtualLocalFileSystem()
+    {
+        files = new HashMap<String, VirtualLocalFile>();
+    }
+    
+    private final Map<String, VirtualLocalFile> files;
+
+    /**
+     * Creates a <code>VirtualLocalFile</code> instance.
+     *
+     * @param name A canonical path. The name must end with a file extension; for example: <code>.mxml</code> or <code>.as</code>.
+     * @param text Source code.
+     * @param parent The parent directory of this <code>VirtualLocalFile</code> object.
+     * @param lastModified The last modified time for the virtual local file.
+     * @return A <code>VirtualLocalFile</code>.
+     */
+    public final VirtualLocalFile create(String name, String text, File parent, long lastModified)
+    {
+        VirtualLocalFile f = new VirtualLocalFile(name, text, parent, lastModified, this);
+        files.put(name, f);
+        return f;
+    }
+    
+    /**
+     * Updates a <code>VirtualLocalFile</code> with the specified text and timestamp.
+     * 
+     * @param name A canonical path. The name must end with a file extension; for example: <code>.mxml</code> or <code>.as</code>.
+     * @param text Source code.
+     * @param lastModified The last modified time.
+     * @return <code>true</code> if the <code>VirtualLocalFile</code> was successfully updated; <code>false</code> if a 
+     * <code>VirtualLocalFile</code> was not found.
+     */
+    public final boolean update(String name, String text, long lastModified)
+    {
+        VirtualLocalFile f = files.get(name);
+        if (f != null)
+        {
+            f.text = text;
+            f.lastModified = lastModified;
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+    
+    final VirtualFile resolve(VirtualLocalFile base, String name)
+    {
+        // if 'name' is a full name and the VirtualFile instance exists, return it.
+        VirtualLocalFile f = files.get(name);
+        if (f != null)
+        {
+            return f;
+        }
+        
+        // if 'name' is relative to 'base', resolve 'name' into a full name.
+        String fullName = constructName(base, name);
+        
+        // try to lookup again.
+        f = files.get(fullName);
+        if (f != null)
+        {
+            return f;
+        }
+
+        // it's not in the HashMap. let's locate it in the file system.
+        File absolute = FileUtil.openFile(name);
+        if (absolute != null && absolute.exists())
+        {
+            return new LocalFile(absolute);
+        }
+        
+        File relative = FileUtil.openFile(fullName);
+        if (relative != null && relative.exists())
+        {
+            return new LocalFile(relative);
+        }
+        
+        return null;
+    }
+    
+    private String constructName(VirtualLocalFile base, String relativeName)
+    {
+        return FileUtil.getCanonicalPath(FileUtil.openFile(base.getParent() + File.separator + relativeName));
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dff3a518/flex-compiler-oem/src/flex2/tools/oem/internal/ApplicationCompilerConfiguration.java
----------------------------------------------------------------------
diff --git a/flex-compiler-oem/src/flex2/tools/oem/internal/ApplicationCompilerConfiguration.java b/flex-compiler-oem/src/flex2/tools/oem/internal/ApplicationCompilerConfiguration.java
new file mode 100644
index 0000000..604d7ef
--- /dev/null
+++ b/flex-compiler-oem/src/flex2/tools/oem/internal/ApplicationCompilerConfiguration.java
@@ -0,0 +1,254 @@
+/*
+ *
+ *  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.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import flex2.compiler.common.Configuration;
+import flex2.compiler.common.ConfigurationPathResolver;
+import flex2.compiler.config.ConfigurationBuffer;
+import flex2.compiler.config.ConfigurationException;
+import flex2.compiler.config.ConfigurationInfo;
+import flex2.compiler.config.ConfigurationValue;
+import flex2.compiler.io.VirtualFile;
+import flex2.tools.ToolsConfiguration;
+
+/**
+ * A configuration that extends ToolsConfiguration by adding options
+ * for -file-specs, -include-resource-bundles, -load-config, and
+ * -projector.
+ *
+ * @version 2.0.1
+ * @author Clement Wong
+ */
+public class ApplicationCompilerConfiguration extends ToolsConfiguration
+{
+	public static Map<String, String> getAliases()
+    {
+        Map<String, String> map = new HashMap<String, String>();
+	    map.putAll(Configuration.getAliases());
+	    map.remove("o");
+		return map;
+    }
+	
+	public void validate(ConfigurationBuffer cfgbuf) throws ConfigurationException
+	{
+        super.validate( cfgbuf );
+
+        String targetFile = getTargetFile();
+
+		if (targetFile == null)
+		{
+		    throw new ConfigurationException.MustSpecifyTarget( null, null, -1);
+		}
+	}
+
+    private VirtualFile getVirtualFile(String file, ConfigurationValue cfgval)
+    {
+    	try
+    	{
+    		return ConfigurationPathResolver.getVirtualFile( file, configResolver, cfgval );
+    	}
+    	catch (ConfigurationException ex)
+    	{
+    		return null;
+    	}
+    }
+
+	//
+	// 'file-specs' option
+	//
+
+	// list of filespecs, default var for command line
+	private List<String> fileSpecs = new ArrayList<String>();
+
+	public List<String> getFileSpecs()
+	{
+		return fileSpecs;
+	}
+
+	public void cfgFileSpecs(ConfigurationValue cv, List<String> args) throws ConfigurationException
+	{
+		this.fileSpecs.addAll( args );
+	}
+
+    public static ConfigurationInfo getFileSpecsInfo()
+    {
+        return new ConfigurationInfo( -1, new String[] { "path-element" } )
+        {
+            public boolean allowMultiple()
+            {
+                return true;
+            }
+
+            public boolean isHidden()
+            {
+            	return true;
+            }
+        };
+    }
+
+    private String resourceModulePath;
+
+    public String getOutput()
+    {
+        return getTargetFile();
+    }
+
+	public String getTargetFile()
+	{
+        // If there are no target files but there are included resource bundles then
+        // this is a resource module so generate a target file name.
+        if (fileSpecs.size() == 0 && getIncludeResourceBundles().size() > 0)
+        {
+            if (resourceModulePath == null)
+            {
+//                resourceModulePath = I18nUtils.getGeneratedResourceModule(this).getPath();
+            }
+            
+            return resourceModulePath;
+        }
+        
+        return (fileSpecs.size() > 0) ? (String) fileSpecs.get( fileSpecs.size() - 1 ) : null;
+	}
+
+    //
+	// 'generate-link-report' option
+	//
+	
+	private boolean generateLinkReport;
+	
+	public boolean generateLinkReport()
+	{
+		return generateLinkReport || super.generateLinkReport();
+	}
+	
+	public void keepLinkReport(boolean b)
+	{
+		generateLinkReport = b;
+	}
+
+    //
+	// 'generate-size-report' option
+	//
+	
+	private boolean generateSizeReport;
+	
+	public boolean generateSizeReport()
+	{
+		return generateSizeReport || super.generateSizeReport();
+	}
+	
+	public void keepSizeReport(boolean b)
+	{
+		generateSizeReport = b;
+	}
+	
+    //
+    // 'include-resource-bundles' option
+    //
+    
+    private List resourceBundles = new LinkedList();
+
+    public List getIncludeResourceBundles()
+    {
+        return resourceBundles;
+    }
+
+    public void cfgIncludeResourceBundles(ConfigurationValue val, List includeResourceBundles)
+    {
+        resourceBundles.addAll(toQNameString(includeResourceBundles));
+    }
+
+    public static ConfigurationInfo getIncludeResourceBundlesInfo()
+    {
+        return new ConfigurationInfo( -1, new String[] { "bundle" } )
+        {
+            public boolean allowMultiple()
+            {
+                return true;
+            }
+        };
+    }
+    
+	//
+	// 'load-config' option
+	//
+
+	private VirtualFile configFile;
+
+	public VirtualFile getLoadConfig()
+	{
+		return configFile;
+	}
+
+	// dummy, ignored - pulled out of the buffer
+	public void cfgLoadConfig(ConfigurationValue cv, String filename) throws ConfigurationException
+	{
+		// C: resolve the flex-config.xml path to a VirtualFile so incremental compilation can detect timestamp change.
+		configFile = ConfigurationPathResolver.getVirtualFile(filename,
+		                                                      configResolver,
+		                                                      cv);
+	}
+
+	public static ConfigurationInfo getLoadConfigInfo()
+    {
+        return new ConfigurationInfo( 1, "filename" )
+        {
+            public boolean allowMultiple()
+            {
+                return true;
+            }
+        };
+    }
+
+    //
+	// 'projector' option
+	//
+	
+    private VirtualFile projector;
+
+    public VirtualFile getProjector()
+    {
+        return projector;
+    }
+
+	public void cfgProjector( ConfigurationValue cfgval, String path )
+	{
+		projector = getVirtualFile(path, cfgval);
+	}
+
+    public static ConfigurationInfo getProjectorInfo()
+    {
+        return new ConfigurationInfo()
+        {
+            public boolean isHidden()
+            {
+                return true;
+            }
+        };
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dff3a518/flex-compiler-oem/src/flex2/tools/oem/internal/BuilderLogger.java
----------------------------------------------------------------------
diff --git a/flex-compiler-oem/src/flex2/tools/oem/internal/BuilderLogger.java b/flex-compiler-oem/src/flex2/tools/oem/internal/BuilderLogger.java
new file mode 100644
index 0000000..ac64c27
--- /dev/null
+++ b/flex-compiler-oem/src/flex2/tools/oem/internal/BuilderLogger.java
@@ -0,0 +1,54 @@
+/*
+ *
+ *  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.util.List;
+
+import flex2.tools.oem.Logger;
+import flex2.tools.oem.Message;
+
+/**
+ * A Logger implementation, which adds messages to a passed in List
+ * and delegates to a passed in Logger if not null.
+ */
+public class BuilderLogger implements Logger
+{
+	public BuilderLogger(Logger logger, List<Message> messages)
+	{
+		this.messages = messages;
+		userLogger = logger;
+	}
+	
+	private List<Message> messages;
+	private Logger userLogger;
+	
+	public void log(Message message, int errorCode, String source)
+	{
+		if (messages != null)
+		{
+			messages.add(message);
+		}
+		
+		if (userLogger != null)
+		{
+			userLogger.log(message, errorCode, source);
+		}
+	}
+}