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

[14/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/compiler/config/FileConfigurator.java
----------------------------------------------------------------------
diff --git a/flex-compiler-oem/src/flex2/compiler/config/FileConfigurator.java b/flex-compiler-oem/src/flex2/compiler/config/FileConfigurator.java
new file mode 100644
index 0000000..bf11dce
--- /dev/null
+++ b/flex-compiler-oem/src/flex2/compiler/config/FileConfigurator.java
@@ -0,0 +1,755 @@
+/*
+ *
+ *  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.compiler.config;
+
+import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.Locator;
+import org.xml.sax.InputSource;
+
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.parsers.SAXParser;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Stack;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+
+import flex2.compiler.util.CompilerMessage;
+import flex2.compiler.util.ThreadLocalToolkit;
+//import flash.util.FileUtils;
+//import flash.localization.LocalizationManager;
+
+/**
+ * A utility class, which is used to parse an XML file of
+ * configuration options and populate a ConfigurationBuffer.  A
+ * counterpart of CommandLineConfigurator and
+ * SystemPropertyConfigurator.
+ *
+ * @author Roger Gonzalez
+ */
+public class FileConfigurator
+{
+    public static class SAXConfigurationException extends SAXParseException
+    {
+        private static final long serialVersionUID = -3388781933743434302L;
+        SAXConfigurationException( ConfigurationException e, Locator locator )
+        {
+            super( null, locator ); // ?
+            this.innerException = e;
+        }
+        public ConfigurationException innerException;
+    }
+
+    /**
+     * @deprecated
+     */
+    public static void load( final ConfigurationBuffer buffer, final Reader r, final String path, String rootElement ) throws ConfigurationException
+    {
+        load( buffer, r, path, null, rootElement );
+    }
+
+    /**
+     * @deprecated
+     */
+    public static void load( final ConfigurationBuffer buffer, final Reader r, final String path, final String context, String rootElement ) throws ConfigurationException
+    {
+        ThreadLocalToolkit.log( new LoadingConfiguration(path) );
+        Handler h = new Handler( buffer, path, context, rootElement, false );
+
+        SAXParserFactory factory = SAXParserFactory.newInstance();
+
+        try
+        {
+            SAXParser parser = factory.newSAXParser();
+            InputSource source = new InputSource( r );
+            parser.parse( source, h );
+        }
+        catch (SAXConfigurationException e)
+        {
+            throw e.innerException;
+        }
+        catch (SAXParseException e)
+        {
+            throw new ConfigurationException.OtherThrowable( e, null, path, e.getLineNumber() );
+        }
+        catch (Exception e)
+        {
+            throw new ConfigurationException.OtherThrowable( e, null, path, -1 );
+        }
+    }
+
+    public static void load( final ConfigurationBuffer buffer, final InputStream r, final String path, String rootElement ) throws ConfigurationException
+    {
+        load( buffer, r, path, null, rootElement, false );
+    }
+
+    public static void load( final ConfigurationBuffer buffer, final InputStream r, final String path, 
+    						 final String context, String rootElement, boolean ignoreUnknownItems ) throws ConfigurationException
+    {
+        ThreadLocalToolkit.log( new LoadingConfiguration(path) );
+        Handler h = new Handler( buffer, path, context, rootElement, ignoreUnknownItems );
+
+        SAXParserFactory factory = SAXParserFactory.newInstance();
+
+        try
+        {
+            SAXParser parser = factory.newSAXParser();
+            InputSource source = new InputSource( r );
+            parser.parse( source, h );
+        }
+        catch (SAXConfigurationException e)
+        {
+            throw e.innerException;
+        }
+        catch (SAXParseException e)
+        {
+            throw new ConfigurationException.OtherThrowable( e, null, path, e.getLineNumber() );
+        }
+        catch (Exception e)
+        {
+            throw new ConfigurationException.OtherThrowable( e, null, path, -1 );
+        }
+    }
+
+    public static void load( ConfigurationBuffer buffer, String path, String rootElement ) throws ConfigurationException
+    {
+        load( buffer, path, null, -1, rootElement );
+    }
+
+    public static void load( ConfigurationBuffer buffer, String path, String contextPath, int line, String rootElement ) throws ConfigurationException
+    {
+        try
+        {
+            File f = new File( getFilePath( path, contextPath ) );
+            InputStream r = new BufferedInputStream( new FileInputStream( f ) );
+
+            load( buffer, r, f.getAbsolutePath(), f.getParent(), rootElement, false );
+
+            try
+            {
+                r.close();
+            }
+            catch(IOException e)
+            {
+                //
+            }
+        }
+        catch (FileNotFoundException e)
+        {
+            throw new ConfigurationException.ConfigurationIOError( path, null, contextPath, line );
+        }
+    }
+
+    // file to load should either be an absolute path or else relative to this config file
+    private static String getFilePath( String path, String contextPath )
+    {
+        File f = new File( path );
+        // file to load should either be an absolute path or else relative to this config file
+        if ( (contextPath != null) && ( !f.exists() || !f.isAbsolute() ) )
+        {
+            f = new File( contextPath + File.separator + path );
+        }
+
+        return f.getAbsolutePath();
+    }
+
+    private static class Handler extends DefaultHandler
+    {
+        public Handler( ConfigurationBuffer buffer, String source, String contextPath, String rootElement, 
+        				boolean ignoreUnknownItems )
+        {
+            this.cfgbuf = buffer;
+            this.source = source;
+            this.contextPath = contextPath;
+            this.rootElement = rootElement;
+            this.ignoreUnknownItems = ignoreUnknownItems;
+        }
+        public void startElement( String uri, String localName, String qName, Attributes attributes ) throws SAXException
+        {
+            String element = qName;
+            if (contextStack.size() == 0)
+            {
+                if (!element.equals( rootElement ))
+                {
+                    throw new SAXConfigurationException(
+                            new ConfigurationException.IncorrectElement( rootElement, qName, this.source, locator.getLineNumber() ),
+                            locator );
+                }
+                ParseContext ctx = new ParseContext();
+                contextStack.push( ctx );
+                return;
+            }
+
+            ParseContext ctx = contextStack.peek();
+
+            if (ctx.ignore)
+            {
+            	// ignore starting new elements
+            	return;
+            }
+            
+            if (text.length() > 0)
+            {
+                throw new SAXConfigurationException(
+                        new ConfigurationException.UnexpectedCDATA( this.source, locator.getLineNumber() ),
+                        locator );
+            }
+
+            String fullname = name( element, ctx.base );
+
+            if (ctx.item != null)
+            {
+                throw new SAXConfigurationException(
+                        new ConfigurationException.UnexpectedElement( element, contextPath, locator.getLineNumber() ),
+                        locator );
+            }
+            else if (ctx.var != null)
+            {
+                // we're setting values for a variable
+
+                if (ctx.varArgCount == 1)
+                {
+                    // oops, we weren't expecting more than one value!
+
+                    throw new SAXConfigurationException(
+                            new ConfigurationException.UnexpectedElement( element, source, locator.getLineNumber() ),
+                            locator );
+                }
+                ctx.item = element;
+            }
+            else if (cfgbuf.isValidVar( fullname ))
+            {
+                ctx.var = fullname;
+                ctx.varArgCount = cfgbuf.getVarArgCount( ctx.var );
+                ctx.append = false;
+                
+                String a = attributes.getValue( "", "append" );
+                if (a != null)
+                {
+                    try
+                    {
+                        if (a.equalsIgnoreCase( "true" ) || a.equalsIgnoreCase( "false" ))
+                            ctx.append = Boolean.valueOf( a ).booleanValue();
+                        else
+                            throw new SAXConfigurationException( new ConfigurationException.BadAppendValue( ctx.var, source, locator.getLineNumber() ),
+                                                                 locator );
+
+                    }
+                    catch (Exception e)
+                    {
+                        throw new SAXConfigurationException( new ConfigurationException.BadAppendValue( ctx.var, source, locator.getLineNumber() ),
+                                                             locator );
+                    }
+                }
+            }
+            else if (cfgbuf.isChildConfig( fullname ))
+            {
+                String src = attributes.getValue( "", "file-path" );
+                if (src != null)
+                {
+                    try
+                    {
+                        Class childClass = cfgbuf.getChildConfigClass( fullname );
+                        ConfigurationBuffer childBuf = new ConfigurationBuffer( childClass );
+                        // keep track of the file-path name
+                        cfgbuf.setVar( element + "-file-path", getFilePath( src, contextPath ), contextPath, locator.getLineNumber() );
+                        FileConfigurator.load( childBuf, src, contextPath, locator.getLineNumber(), element );
+                        cfgbuf.mergeChild( element, childBuf );
+                    }
+                    catch (final ConfigurationException e)
+                    {
+                        throw new SAXConfigurationException( e, locator );
+                    }
+                }
+
+
+                ParseContext newctx = new ParseContext();
+                newctx.base = fullname;
+                contextStack.push( newctx );
+            }
+            else
+            {
+            	if (ignoreUnknownItems)
+            	{
+            		// push a new context and ignore everything until we get the end 
+            		// of this element.
+                    ParseContext newctx = new ParseContext();
+                    newctx.item = element;
+                    newctx.ignore = true;
+                    contextStack.push( newctx );
+            		return;
+            	}
+                throw new SAXConfigurationException(
+                        new ConfigurationException.UnknownVariable(
+                                                    fullname, source, locator.getLineNumber() ),
+                        locator );
+            }
+        }
+
+        public void endElement( String uri, String localName, String qName ) throws SAXException
+        {
+            String element = qName;
+
+            ParseContext ctx = contextStack.peek();
+
+            if (ctx.ignore)
+            {
+            	// if found the matching end element, then pop the context and stop ignoring input
+            	if (ctx.item.equals(element))
+            	{
+            		contextStack.pop();
+            		text = new StringBuilder();	// ignore any text read
+            	}
+            	
+            	return;
+            }
+            
+            // There are four possible states here;
+            // 1. localname==rootElement -> end of file, pop, we're done
+            // 2. localname==itemElement -> finished gathering text, push onto arglist
+            // 2. var is set -> set the var to the argList, pop
+            // 3. var is null -> we're finishing a child config, pop
+
+            if (element.equals( rootElement ))
+            {
+                // Finished with the file!
+            }
+            else if (ctx.item != null)
+            {
+                // Finished with the current item.
+
+                ParseValue v = new ParseValue();
+                v.name = element;
+                v.value = text.toString();
+                v.line = locator.getLineNumber();
+                ctx.argList.add( v );
+                text = new StringBuilder();
+                ctx.item = null;
+            }
+            else if (ctx.var != null)
+            {
+                if ((ctx.varArgCount > 1) && (ctx.argList.size() == 0))
+                {
+                    throw new SAXConfigurationException(
+                            new ConfigurationException.IncorrectArgumentCount( ctx.varArgCount, 0,
+                                                                               ctx.var, source, locator.getLineNumber() ),
+                            locator );
+                }
+                if (ctx.varArgCount == 1)
+                {
+                    ParseValue v = new ParseValue();
+                    v.name = null;
+                    v.value = text.toString();
+                    v.line = locator.getLineNumber();
+                    ctx.argList.add( v );
+                    text = new StringBuilder();
+                }
+                else
+                {
+                    if (text.length() > 0)
+                    {
+                        // "unexpected CDATA encountered, " + ctx.var + " requires named arguments.", locator );
+                        throw new SAXConfigurationException(
+                                new ConfigurationException.UnexpectedCDATA( source, locator.getLineNumber() ),
+                                locator );
+
+                    }
+                }
+                // Finished with the current var, save the current list
+                try
+                {
+                    setVar( ctx.var, ctx.argList, locator.getLineNumber(), ctx.append );
+                    ctx.var = null;
+                    ctx.argList.clear();
+                    ctx.item = null;
+                    ctx.append = false;
+                }
+                catch (ConfigurationException e)
+                {
+                    throw new SAXConfigurationException( e, locator );
+                }
+            }
+            else
+            {
+                // done with a child config
+                contextStack.pop();
+            }
+        }
+
+        public void setVar( String var, List<ParseValue> argList, int line, boolean append ) throws ConfigurationException
+        {
+            int varArgCount = cfgbuf.getVarArgCount( var );
+
+            Map<String, String> items = new HashMap<String, String>();
+
+            boolean byName = (varArgCount > 1);
+
+            if (byName)
+            {
+                for (Iterator<ParseValue> it = argList.iterator(); it.hasNext();)
+                {
+                    ParseValue v = it.next();
+
+                    if (items.containsKey( v.name ))
+                    {
+                        byName = false;     // can't support byName, duplicate item name!
+                        break;
+                    }
+                    else
+                    {
+                        items.put( v.name, v.value );
+                    }
+                }
+            }
+            List<String> args = new LinkedList<String>();
+
+            if (byName)
+            {
+                int argc = 0;
+
+                while (args.size() < items.size())
+                {
+                    String name = cfgbuf.getVarArgName( var, argc++ );
+                    String val = items.get( name );
+                    if (val == null)
+                    {
+                        throw new ConfigurationException.MissingArgument( name, var, source, line );
+                    }
+                    args.add( val );
+                }
+            }
+            else
+            {
+                Iterator<ParseValue> it = argList.iterator();
+                int argc = 0;
+                while (it.hasNext())
+                {
+                    ParseValue v = it.next();
+                    String name = cfgbuf.getVarArgName( var, argc++ );
+                    if ((v.name != null) && !name.equals( v.name ))
+                    {
+                        throw new ConfigurationException.UnexpectedArgument( name, v.name, var, source, v.line );
+                    }
+                    args.add( v.value );
+                }
+            }
+            cfgbuf.setVar( var, args, source, line, contextPath, append );
+        }
+
+        public void characters( char ch[], int start, int length )
+        {
+            String chars = new String( ch, start, length ).trim();
+            text.append( chars );
+        }
+        public void setDocumentLocator( Locator locator )
+        {
+            this.locator = locator;
+        }
+
+        private Stack<ParseContext> contextStack = new Stack<ParseContext>();
+        private final ConfigurationBuffer cfgbuf;
+        private final String source;
+        private final String contextPath;
+        private final String rootElement;
+        
+        /**
+         * 	if true, do not throw an error if a config var is found that is not defined in the config buffer.
+         */
+        private final boolean ignoreUnknownItems;
+        
+        private Locator locator;
+        StringBuilder text = new StringBuilder();
+    }
+
+    private static String name( String var, String base )
+    {
+        return (base == null)? var : (base + "." + var);
+    }
+
+    private static class ParseContext
+    {
+        ParseContext()
+        {
+            this.base = null;
+            this.var = null;
+            this.varArgCount = -2;
+            this.argList = new LinkedList<ParseValue>();
+            this.append = false;
+            this.ignore = false;
+        }
+
+        public String localVar;
+        public String var;
+        public String base;
+        public String item;
+        public int varArgCount;
+        public boolean append;
+        public List<ParseValue> argList;
+        public boolean ignore;	// ignore this variable, do not put in config buffer
+    }
+    
+    private static class ParseValue
+    {
+        public String name;
+        public String value;
+        public int line;
+    }
+
+    private static class FormatNode
+    {
+        public String fullname;
+        public String shortname;
+        public ConfigurationInfo info;
+        public List values;
+
+        public TreeMap<String, FormatNode> children;   // only for configs
+    }
+
+    static final String pad = "   ";
+    private static String classToArgName( Class c )
+    {
+        // we only support builtin classnames!
+
+        String className = c.getName();
+        if (className.startsWith( "java.lang." ))
+            className = className.substring( "java.lang.".length() );
+
+        return className.toLowerCase();
+    }
+
+    private static String formatBuffer1( ConfigurationBuffer cfgbuf,
+                                         FormatNode node,
+                                         String indent,
+//                                         LocalizationManager lmgr,
+                                         String prefix )
+    {
+        StringBuilder buf = new StringBuilder( 1024 );
+
+        buf.append( indent + "<" + node.shortname + ">\n" );
+        if (node.children != null) {
+        for (Iterator it = node.children.entrySet().iterator(); it.hasNext(); )
+        {
+            Map.Entry e = (Map.Entry) it.next();
+            FormatNode child = (FormatNode) e.getValue();
+
+            if (child.children != null) // its a config
+            {
+                buf.append( formatBuffer1( cfgbuf, child, indent + pad, /*lmgr, */ prefix ) );
+            }
+            else
+            {
+                String description = /*lmgr.getLocalizedTextString(*/ prefix + "." + child.fullname /*)*/;
+
+                if (description != null)
+                    buf.append( indent + pad + "<!-- " + child.fullname + ": " + description + "-->\n" );
+
+                if ((child.values == null) || !child.info.isDisplayed())
+                {
+                    boolean newline = false;
+                    buf.append( indent + pad + "<!-- " + child.fullname + " usage:\n" );
+                    buf.append( indent + pad + "<" + child.shortname + ">");
+
+                    int i = 0;
+                    while (true)
+                    {
+                        if (child.info.getArgCount() == 1)
+                        {
+                            buf.append( child.info.getArgName( i ) );
+                            break;
+                        }
+                        else
+                        {
+                            buf.append( "\n" + indent + pad + pad + "<" + child.info.getArgName( i ) + ">" + classToArgName( child.info.getArgType( i ) ) + "</" + child.info.getArgName( i ) + ">");
+                            newline = true;
+                        }
+                        if (child.info.getArgCount() == -1)
+                        {
+                            if (i > 0) 
+                            {
+                            	// stop iterating thru arguments when an arg name
+                            	// matches a previously used arg name.
+                            	boolean found = false;	// true if found argName in the arg list
+                            	String argName = child.info.getArgName(i + 1);
+                            	for (int j = i; j >= 0; j--)
+                            	{
+                            		if (child.info.getArgName(j).equals( argName ))
+                            		{
+                            			found = true;
+                            			break;
+                            		}
+                            	}
+                            	if (found)
+                            	{
+                            		break;
+                            	}
+                            }
+                        }
+                        else if (i >= child.info.getArgCount())
+                        {
+                            break;
+                        }
+                        ++i;
+                    }
+                    if (newline)
+                        buf.append( "\n" + indent + pad);
+
+                    buf.append( "</" + child.shortname + ">\n");
+                    buf.append( indent + pad + "-->\n" );
+                }
+                else
+                {
+                    // var may be set multiple times...
+                    boolean newline = false;
+                    for (Iterator valit = child.values.iterator(); valit.hasNext();)
+                    {
+                        ConfigurationValue cv = (ConfigurationValue) valit.next();
+
+                        buf.append( indent + pad + "<" + child.shortname + ">" );
+
+                        int argCount = child.info.getArgCount();
+                        // var may have multiple values...
+                        int argc = 0;
+                        for (Iterator argit = cv.getArgs().iterator(); argit.hasNext();)
+                        {
+                            String arg = (String) argit.next();
+
+                            if (argCount == 1)
+                            {
+                                buf.append( arg );
+                                break;
+                            }
+                            else
+                            {
+                                String argname = child.info.getArgName( argc++ );
+                                newline = true;
+                                buf.append( "\n" + indent + pad + pad + "<" + argname + ">" + arg + "</" + argname + ">" );
+                            }
+                        }
+                        if (newline)
+                            buf.append( "\n" + indent + pad);
+                        buf.append( "</" + child.shortname + ">\n" );
+                    }
+                }
+            }
+        }
+        }
+        buf.append( indent + "</" + node.shortname + ">\n" );
+
+        return buf.toString();
+    }
+    private static void addNode( ConfigurationBuffer cfgbuf, String var, FormatNode root )
+    {
+        String name = null;
+        StringTokenizer t = new StringTokenizer( var, "." );
+
+        FormatNode current = root;
+
+        while (t.hasMoreTokens())
+        {
+            String token = t.nextToken();
+
+            if (name == null)
+                name = token;
+            else
+                name += "." + token;
+
+            if (current.children == null)
+                current.children = new TreeMap<String, FormatNode>();
+
+            if (cfgbuf.isChildConfig( name ))
+            {
+                if (!current.children.containsKey( token ))
+                {
+                    FormatNode node = new FormatNode();
+                    node.fullname = name;
+                    node.shortname = token;
+                    node.children = new TreeMap<String, FormatNode>();
+                    current.children.put( token, node );
+                    current = node;
+                }
+                else
+                {
+                    current = current.children.get( token );
+                }
+            }
+            else if (cfgbuf.isValidVar( name ))
+            {
+                FormatNode node = new FormatNode();
+                node.fullname = name;
+                node.shortname = token;
+                node.info = cfgbuf.getInfo( name );
+                node.values = cfgbuf.getVar( name );
+                current.children.put( token, node );
+            }
+        }
+    }
+
+    public static String formatBuffer( ConfigurationBuffer cfgbuf,
+                                       String rootElement,
+//                                       LocalizationManager lmgr,
+                                       String prefix )
+    {
+        FormatNode root = new FormatNode();
+        root.shortname = rootElement;
+        for (Iterator it = cfgbuf.getVarIterator(); it.hasNext(); )
+        {
+            String var = (String) it.next();
+            // if var is a 'hidden' parameter, don't dump.
+            ConfigurationInfo info = cfgbuf.getInfo(var);
+            if (info != null && (info.isHidden() || !info.isDisplayed()))
+            {
+            	continue;
+            }
+            addNode( cfgbuf, var, root );
+        }
+
+        return formatBuffer1( cfgbuf, root, "", /*lmgr, */ prefix );
+    }
+
+    public static String formatBuffer( ConfigurationBuffer cfgbuf, String rootElement)
+    {
+        return formatBuffer( cfgbuf, rootElement, /*null, */ null );
+    }
+
+	public static class LoadingConfiguration extends CompilerMessage.CompilerInfo
+	{
+        private static final long serialVersionUID = 7288323144791549482L;
+        public String file;
+
+		public LoadingConfiguration(String file)
+		{
+            this.file = file;
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dff3a518/flex-compiler-oem/src/flex2/compiler/config/ServicesDependenciesWrapper.java
----------------------------------------------------------------------
diff --git a/flex-compiler-oem/src/flex2/compiler/config/ServicesDependenciesWrapper.java b/flex-compiler-oem/src/flex2/compiler/config/ServicesDependenciesWrapper.java
new file mode 100644
index 0000000..15d85d1
--- /dev/null
+++ b/flex-compiler-oem/src/flex2/compiler/config/ServicesDependenciesWrapper.java
@@ -0,0 +1,418 @@
+/*
+ *
+ *  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.compiler.config;
+
+import java.io.File;
+import java.lang.reflect.*;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Flex MXMLC compiler uses the result of the client configuration parser
+ * to generate mixin initialization source code to be added to the SWF by
+ * PreLink. It also requires a list of channel classes to be added as
+ * dependencies.
+ *
+ * @exclude
+ */
+public class ServicesDependenciesWrapper
+{
+	private Object servicesDependenciesInstance;
+	private Class servicesDependenciesClass;
+	
+    public ServicesDependenciesWrapper(String path, String parserClass, String contextRoot)
+    {
+    	try 
+    	{
+    		servicesDependenciesClass = Class.forName("flex.messaging.config.ServicesDependencies");
+    	}
+    	catch (ClassNotFoundException e)
+    	{
+    		return;
+    	}
+		Class partypes[] = new Class[3];
+        partypes[0] = String.class;
+        partypes[1] = String.class;
+        partypes[2] = String.class;
+        try
+        {
+            Constructor ct = servicesDependenciesClass.getConstructor(partypes);        	
+            Object arglist[] = new Object[3];
+            arglist[0] = path;
+            arglist[1] = parserClass;
+            arglist[2] = contextRoot;
+            try 
+            {
+                servicesDependenciesInstance = ct.newInstance(arglist);            	
+            }
+            catch (Throwable e3)
+            {
+            	if (e3 instanceof InvocationTargetException)
+            		System.err.println(((InvocationTargetException)e3).getCause());
+            	else
+            		System.err.println(e3);
+            }
+        }
+        catch (NoSuchMethodException e2)
+        {
+        	
+        }
+    }
+
+    public Set getLazyAssociations(String destination)
+    {
+    	if (servicesDependenciesClass != null)
+    	{
+    		try
+    		{
+    			Method method = servicesDependenciesClass.getMethod("getLazyAssociations", new Class[] {String.class});
+    			Object arglist[] = new Object[1];
+                arglist[0] = destination;
+                return (Set)method.invoke(servicesDependenciesInstance, arglist);   			
+    		}
+    		catch (Throwable e)
+    		{
+    			
+    		}
+    	}
+    	
+    	return null;
+    }
+
+    public void addLazyAssociation(String destination, String associationProp)
+    {
+    	if (servicesDependenciesClass != null)
+    	{
+    		try
+    		{
+    			Method method = servicesDependenciesClass.getMethod("getLazyAssociations", new Class[] {String.class});
+    			Object arglist[] = new Object[2];
+                arglist[0] = destination;
+                arglist[1] = associationProp;
+                method.invoke(servicesDependenciesInstance, arglist);   			
+    		}
+    		catch (Throwable e)
+    		{
+    			
+    		}
+    	}
+    }
+
+    public String getServerConfigXmlInit()
+    {
+    	if (servicesDependenciesClass != null)
+    	{
+    		try
+    		{
+    			Method method = servicesDependenciesClass.getMethod("getServerConfigXmlInit", new Class[] {} );
+    			Object arglist[] = new Object[0];
+                return (String)method.invoke(servicesDependenciesInstance, arglist);   			
+    		}
+    		catch (Throwable e)
+    		{
+    			
+    		}
+    	}
+    	
+    	return null;
+    }
+
+    public String getImports()
+    {
+    	if (servicesDependenciesClass != null)
+    	{
+    		try
+    		{
+    			Method method = servicesDependenciesClass.getMethod("getImports", new Class[] {} );
+    			Object arglist[] = new Object[0];
+                return (String)method.invoke(servicesDependenciesInstance, arglist);   			
+    		}
+    		catch (Throwable e)
+    		{
+    			
+    		}
+    	}
+    	
+    	return null;
+    }
+
+    public String getReferences()
+    {
+    	if (servicesDependenciesClass != null)
+    	{
+    		try
+    		{
+    			Method method = servicesDependenciesClass.getMethod("getReferences", new Class[] {} );
+    			Object arglist[] = new Object[0];
+                return (String)method.invoke(servicesDependenciesInstance, arglist);   			
+    		}
+    		catch (Throwable e)
+    		{
+    			
+    		}
+    	}
+    	
+    	return null;
+    }
+
+    public List getChannelClasses()
+    {
+    	if (servicesDependenciesClass != null)
+    	{
+    		try
+    		{
+    			Method method = servicesDependenciesClass.getMethod("getChannelClasses", new Class[] {} );
+    			Object arglist[] = new Object[0];
+                return (List)method.invoke(servicesDependenciesInstance, arglist);   			
+    		}
+    		catch (Throwable e)
+    		{
+    			
+    		}
+    	}
+    	
+    	return null;
+    }
+
+    public void addChannelClass(String className)
+    {
+    	if (servicesDependenciesClass != null)
+    	{
+    		try
+    		{
+    			Method method = servicesDependenciesClass.getMethod("addChannelClass", new Class[] {} );
+    			Object arglist[] = new Object[0];
+                method.invoke(servicesDependenciesInstance, arglist);   			
+    		}
+    		catch (Throwable e)
+    		{
+    			
+    		}
+    	}
+    }
+
+    public void addConfigPath(String path, long modified)
+    {
+    	if (servicesDependenciesClass != null)
+    	{
+    		try
+    		{
+    			Method method = servicesDependenciesClass.getMethod("addConfigPath", new Class[] { String.class, Long.TYPE } );
+    			Object arglist[] = new Object[2];
+    			arglist[0] = path;
+    			arglist[1] = modified;
+                method.invoke(servicesDependenciesInstance, arglist);   			
+    		}
+    		catch (Throwable e)
+    		{
+    			
+    		}
+    	}
+    }
+
+    public Map getConfigPaths()
+    {
+    	if (servicesDependenciesClass != null)
+    	{
+    		try
+    		{
+    			Method method = servicesDependenciesClass.getMethod("getConfigPaths", new Class[] {} );
+    			Object arglist[] = new Object[0];
+                return (Map)method.invoke(servicesDependenciesInstance, arglist);   			
+    		}
+    		catch (Throwable e)
+    		{
+    			
+    		}
+    	}
+    	
+    	return null;
+    }
+
+    /*
+    public static ClientConfiguration getClientConfiguration(String path, String parserClass)
+    {
+        ClientConfiguration config = new ClientConfiguration();
+
+        ConfigurationParser parser = getConfigurationParser(parserClass);
+
+        if (parser == null)
+        {
+            // "Unable to create a parser to load messaging configuration."
+            LocalizedException lme = new LocalizedException();
+            lme.setMessage(10138);
+            throw lme;
+        }
+
+        LocalFileResolver local = new LocalFileResolver();
+        parser.parse(path, local, config);
+
+        config.addConfigPath(path, new File(path).lastModified());
+
+        return config;
+    }
+
+    static ConfigurationParser getConfigurationParser(String className)
+    {
+        ConfigurationParser parser = null;
+        Class parserClass = null;
+
+        // Check for Custom Parser Specification
+        if (className != null)
+        {
+            try
+            {
+                parserClass = Class.forName(className);
+                parser = (ConfigurationParser)parserClass.newInstance();
+            }
+            catch (Throwable t)
+            {
+                if (traceConfig)
+                {
+                    System.out.println("Could not load services configuration parser as: " + className);
+                }
+            }
+        }
+
+        // Try Sun JRE 1.4 / Apache Xalan Based Implementation
+        if (parser == null)
+        {
+            try
+            {
+                Class.forName("org.apache.xpath.CachedXPathAPI");
+                className = "flex.messaging.config.ApacheXPathClientConfigurationParser";
+                parserClass = Class.forName(className);
+                parser = (ConfigurationParser)parserClass.newInstance();
+            }
+            catch (Throwable t)
+            {
+                if (traceConfig)
+                {
+                    System.out.println("Could not load configuration parser as: " + className);
+                }
+            }
+        }
+
+        // Try Sun JRE 1.5 Based Implementation
+        if (parser == null)
+        {
+            try
+            {
+                className = "flex.messaging.config.XPathClientConfigurationParser";
+                parserClass = Class.forName(className);
+                // double-check, on some systems the above loads but the import classes don't
+                Class.forName("javax.xml.xpath.XPathExpressionException");
+
+                parser = (ConfigurationParser)parserClass.newInstance();
+            }
+            catch (Throwable t)
+            {
+                if (traceConfig)
+                {
+                    System.out.println("Could not load configuration parser as: " + className);
+                }
+            }
+        }
+
+        if (traceConfig && parser != null)
+        {
+            System.out.println("Services Configuration Parser: " + parser.getClass().getName());
+        }
+
+        return parser;
+    }
+
+    private static List listChannelClasses(ServicesConfiguration config)
+    {
+        List channelList = new ArrayList();
+        Iterator it = config.getAllChannelSettings().values().iterator();
+        while (it.hasNext())
+        {
+            ChannelSettings settings = (ChannelSettings)it.next();
+            if (!settings.serverOnly)
+            {
+                String clientType = settings.getClientType();
+                channelList.add(clientType);
+            }
+        }
+
+        return channelList;
+    }
+
+	 */
+    
+
+    /**
+     *
+    public void codegenServiceAssociations(ConfigMap metadata, StringBuffer e4x, String destination, String relation)
+    {
+    	if (servicesDependenciesClass != null)
+    	{
+    		try
+    		{
+    			Method method = servicesDependenciesClass.getMethod("getConfigPaths", new Class[] { ConfigMap.class, StringBuffer.class, String.class, String.class } );
+    			Object arglist[] = new Object[4];
+    			arglist[0] = metadata;
+    			arglist[1] = e4x;
+    			arglist[2] = destination;
+    			arglist[3] = relation;
+                method.invoke(servicesDependenciesInstance, arglist);   			
+    		}
+    		catch (Throwable e)
+    		{
+    			
+    		}
+    	}
+    }
+     */
+
+    /**
+     * This method will return an import and variable reference for channels specified in the map.
+     * @param map HashMap containing the client side channel type to be used, typically of the form
+     * "mx.messaging.channels.XXXXChannel", where the key and value are equal.
+     * @param imports StringBuffer of the imports needed for the given channel definitions
+     * @param references StringBuffer of the required references so that these classes will be linked in.
+    public static void codegenServiceImportsAndReferences(Map map, StringBuffer imports, StringBuffer references)
+    {
+        String channelSetImplType = (String)map.remove("ChannelSetImpl");
+        String type;
+        imports.append("import mx.messaging.config.ServerConfig;\n");
+        references.append("   // static references for configured channels\n");
+        for (Iterator chanIter = map.values().iterator(); chanIter.hasNext();)
+        {
+            type = (String)chanIter.next();
+            imports.append("import ");
+            imports.append(type);
+            imports.append(";\n");
+            references.append("   private static var ");
+            references.append(type.replace('.', '_'));
+            references.append("_ref:");
+            references.append(type.substring(type.lastIndexOf(".") +1) +";\n");
+        }
+        if (channelSetImplType != null)
+            imports.append("import mx.messaging.AdvancedChannelSet;\nimport mx.messaging.messages.ReliabilityMessage;\n");
+    }
+     */
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dff3a518/flex-compiler-oem/src/flex2/compiler/config/SystemPropertyConfigurator.java
----------------------------------------------------------------------
diff --git a/flex-compiler-oem/src/flex2/compiler/config/SystemPropertyConfigurator.java b/flex-compiler-oem/src/flex2/compiler/config/SystemPropertyConfigurator.java
new file mode 100644
index 0000000..23eece7
--- /dev/null
+++ b/flex-compiler-oem/src/flex2/compiler/config/SystemPropertyConfigurator.java
@@ -0,0 +1,83 @@
+/*
+ *
+ *  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.compiler.config;
+
+import java.util.Properties;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.StringTokenizer;
+
+/**
+ * A utility class, which is used to load configuration options via
+ * system properties and populate a ConfigurationBuffer.  A
+ * counterpart of CommandLineConfigurator and FileConfigurator.
+ *
+ * @author Roger Gonzalez
+ */
+public class SystemPropertyConfigurator
+{
+    /**
+     * Opportunistically find some configuration settings in system properties.
+     * @param buffer the intermediate config buffer
+     * @param prefix an optional prefix to add to the variable, pass null if no prefix
+     * @throws ConfigurationException
+     */
+    public static void load( final ConfigurationBuffer buffer, String prefix ) throws ConfigurationException
+    {
+        try
+        {
+            Properties props = System.getProperties();
+
+            for (Enumeration e = props.propertyNames(); e.hasMoreElements();)
+            {
+                String propname = (String) e.nextElement();
+
+                if (!propname.startsWith( prefix + "."))
+                {
+                    String value = System.getProperty( propname );
+                    buffer.setToken( propname, value );
+                    continue;
+                }
+
+                String varname = propname.substring( prefix.length() + 1 );
+
+                if (!buffer.isValidVar( varname ))
+                    continue;
+
+                String value = System.getProperty( propname );
+
+                List<String> args = new LinkedList<String>();
+                StringTokenizer t = new StringTokenizer( value, "," );
+
+                while (t.hasMoreTokens())
+                {
+                    String token = t.nextToken();
+                    args.add( token );
+                }
+                buffer.setVar( varname, args, "system properties", -1 );
+            }
+        }
+        catch (SecurityException se)
+        {
+            // just ignore, this is an optional for loading configuration   
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dff3a518/flex-compiler-oem/src/flex2/compiler/extensions/ExtensionsConfiguration.java
----------------------------------------------------------------------
diff --git a/flex-compiler-oem/src/flex2/compiler/extensions/ExtensionsConfiguration.java b/flex-compiler-oem/src/flex2/compiler/extensions/ExtensionsConfiguration.java
new file mode 100644
index 0000000..13f5296
--- /dev/null
+++ b/flex-compiler-oem/src/flex2/compiler/extensions/ExtensionsConfiguration.java
@@ -0,0 +1,134 @@
+/*
+ *
+ *  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.compiler.extensions;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import flex2.compiler.common.ConfigurationPathResolver;
+import flex2.compiler.common.PathResolver;
+import flex2.compiler.config.ConfigurationException;
+import flex2.compiler.config.ConfigurationInfo;
+import flex2.compiler.config.ConfigurationValue;
+
+/**
+ * This class handles extension specific configuration options.
+ * Currently, there is only one, -compiler.extensions.extension.
+ *
+ * @author Andrew Westberg
+ */
+public class ExtensionsConfiguration
+{
+    private ConfigurationPathResolver configResolver;
+
+    public void setConfigPathResolver( ConfigurationPathResolver resolver )
+    {
+        this.configResolver = resolver;
+    }
+
+    private Map<String, List<String>> extensionMappings;
+
+    public Map<String, List<String>> getExtensionMappings()
+    {
+        if ( extensionMappings == null )
+        {
+            extensionMappings = new LinkedHashMap<String, List<String>>();
+        }
+        return extensionMappings;
+    }
+
+    public void setExtensionMappings( Map<String, List<String>> extensionMappings )
+    {
+        this.extensionMappings = extensionMappings;
+    }
+
+    //
+    // 'compiler.extensions.extension' option
+    //
+
+    public File[] getExtension()
+    {
+        if ( extensionMappings != null )
+        {
+            return extensionMappings.keySet().toArray( new File[0] );
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+    /**
+     * Configures a list of many extensions mapped to a single Extension URI. <extension>
+     * <extension>something-extension.jar</extension> <parameters>version=1.1,content=1.2</parameters> </extension>
+     * 
+     * @param cfgval The configuration value context.
+     * @param args A List of values for the Extension element, with the first item expected to be the uri and the
+     *            remaining are extension paths.
+     * @throws ConfigurationException When no arg is provided or when the jar does not exist.
+     */
+    public void cfgExtension( ConfigurationValue cfgval, List<String> args )
+        throws ConfigurationException
+    {
+        if ( args == null )
+        {
+            throw new ConfigurationException.CannotOpen( null, cfgval.getVar(), cfgval.getSource(), cfgval.getLine() );
+        }
+
+        PathResolver resolver = new PathResolver();
+
+        if ( resolver == null || configResolver == null )
+        {
+            throw new ConfigurationException.CannotOpen( null, cfgval.getVar(), cfgval.getSource(), cfgval.getLine() );
+        }
+
+        Iterator<String> iterator = args.iterator();
+        String extension = iterator.next();
+
+        File file = new File( extension );
+        if ( !file.exists() )
+        {
+            throw new ConfigurationException.NotAFile( extension, cfgval.getVar(), cfgval.getSource(), cfgval.getLine() );
+        }
+
+        List<String> parameters = new ArrayList<String>();
+        while ( iterator.hasNext() )
+        {
+            parameters.add( iterator.next() );
+        }
+
+        getExtensionMappings().put( file.getAbsolutePath(), parameters );
+    }
+
+    public static ConfigurationInfo getExtensionInfo()
+    {
+        return new ConfigurationInfo( -1, new String[] { "extension", "parameters" } )
+        {
+            public boolean allowMultiple()
+            {
+                return true;
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dff3a518/flex-compiler-oem/src/flex2/compiler/io/FileUtil.java
----------------------------------------------------------------------
diff --git a/flex-compiler-oem/src/flex2/compiler/io/FileUtil.java b/flex-compiler-oem/src/flex2/compiler/io/FileUtil.java
new file mode 100644
index 0000000..36729fd
--- /dev/null
+++ b/flex-compiler-oem/src/flex2/compiler/io/FileUtil.java
@@ -0,0 +1,590 @@
+/*
+ *
+ *  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.compiler.io;
+
+import java.io.*;
+import java.util.List;
+
+/**
+ * A helper class used by classes doing file operations.  Part of it's
+ * original purpose was to consolidate J# handling, but J# support was
+ * dropped many years ago.
+ *
+ * @author Clement Wong
+ */
+public final class FileUtil
+{
+	public static final boolean caseInsensitive = (System.getProperty("os.name").toLowerCase().startsWith("windows") ||
+												   System.getProperty("os.name").toLowerCase().startsWith("mac"));
+
+	/**
+	 * Return an instance of File...
+	 *
+	 * @param path
+	 * @return File
+	 */
+	public static File openFile(String path)
+	{
+		try
+		{
+			return new File(path);
+		}
+		catch (Error e) // J#.NET throws an error if the file is not found...
+		{
+			return null;
+		}
+	}
+
+	public static File openFile(String path, boolean mkdir)
+	{
+		File f = new File(path).getAbsoluteFile();
+
+		if (mkdir)
+		{
+			new File(f.getParent()).mkdirs();
+		}
+
+		return f;
+	}
+
+	/**
+	 * Return an instance of File...
+	 *
+	 * @param parentPath
+	 * @param fileName
+	 * @return File
+	 */
+	public static File openFile(File parentPath, String fileName)
+	{
+		try
+		{
+			return new File(parentPath, fileName);
+		}
+		catch (Error e) // J#.NET throws an error if the file is not found...
+		{
+			return null;
+		}
+	}
+
+	/**
+	 * Create a temp file. Write the input stream to the file...
+	 *
+	 * @param in
+	 * @return
+	 * @throws IOException
+	 */
+	public static File createTempFile(InputStream in) throws IOException
+	{
+		File temp = File.createTempFile("Flex2_", "");
+		writeBinaryFile(temp, in);
+		return temp;
+	}
+
+	/**
+	 * Return an input stream with BOM consumed...
+	 *
+	 * @param file
+	 * @return
+	 * @throws FileNotFoundException
+	 * @throws IOException
+	 */
+	public static InputStream openStream(File file) throws FileNotFoundException, IOException
+	{
+		return openStream(file.getAbsolutePath());
+	}
+
+	/**
+	 * Return an input stream with BOM consumed...
+	 *
+	 * @param path
+	 * @return
+	 * @throws FileNotFoundException
+	 * @throws IOException
+	 */
+	public static InputStream openStream(String path) throws FileNotFoundException, IOException
+	{
+		return openStream(new FileInputStream(path));
+	}
+
+	/**
+	 * Return an input stream with BOM consumed...
+	 *
+	 * @param in
+	 * @return
+	 * @throws IOException
+	 */
+	public static InputStream openStream(InputStream in) throws IOException
+	{
+		byte[] bom = new byte[3];
+
+		in.read(bom, 0, 3);
+
+		if (bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf)
+		{
+			return in;
+		}
+		// else if (bom[0] == 0xff && bom[1] == 0xfe || bom[0] == 0xfe && bom[1] == 0xff)
+		else
+		{
+			return new BOMInputStream(bom, in);
+		}
+	}
+
+	/**
+	 * It's a normal input stream but it serves BOM before bytes in the stream...
+	 */
+    //TODO make a reader version of this class so calls like
+    //         > new BufferedReader(new InputStreamReader(FileUtil.openStream(f)))
+    //     don't have so many levels of indirection to get to the stream
+	private static final class BOMInputStream extends InputStream
+	{
+		private BOMInputStream(byte[] bom, InputStream in)
+		{
+			this.bom = bom;
+			bomSize = bom.length;
+			this.in = in;
+			index = 0;
+		}
+
+		private byte[] bom;
+		private final int bomSize;
+		private final InputStream in;
+		private int index;
+
+		public int read() throws IOException
+		{
+			if (bom == null)
+			{
+				return in.read();
+			}
+			else
+			{
+				int c = bom[index];
+				if (index == bomSize - 1)
+				{
+					bom = null;
+				}
+				index += 1;
+				return c;
+			}
+		}
+
+		public int read(byte b[], int off, int len) throws IOException
+		{
+			if (bom == null)
+			{
+				return in.read(b, off, len);
+			}
+
+            int count = 0;
+            while ((index < 3) && (count < len))
+            {
+                b[off+count] = bom[index++];
+                ++count;
+            }
+            if (index == 3)
+            {
+                bom = null;
+            }
+            if (len <= count)
+                return count;
+            int r = in.read(b, off+count, len-count);
+            return (r == -1)? -1 : r + count;
+		}
+
+		public long skip(long n) throws IOException
+		{
+			throw new UnsupportedOperationException("supports read() and close() only...");
+		}
+
+		public int available() throws IOException
+		{
+			int num = in.available();
+			if (bom == null)
+			{
+				return num;
+			}
+			else
+			{
+				return (bomSize - index) + num;
+			}
+		}
+
+		public void close() throws IOException
+		{
+			in.close();
+		}
+
+		public synchronized void mark(int readlimit)
+		{
+			throw new UnsupportedOperationException("supports read() and close() only...");
+		}
+
+		public synchronized void reset() throws IOException
+		{
+			throw new UnsupportedOperationException("supports read() and close() only...");
+		}
+
+		public boolean markSupported()
+		{
+			return false;
+		}
+	}
+
+	/**
+	 * Write a stream of binary data to a file.
+	 * @param file
+	 * @param in
+	 * @throws IOException
+	 */
+	public static void writeBinaryFile(File file, InputStream in) throws IOException
+	{
+		OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
+		in = new BufferedInputStream(in);
+        try
+        {
+            streamOutput(in, out);
+        }
+        finally
+        {
+            out.close();
+        }
+    }
+
+    public static void streamOutput(InputStream in, OutputStream out)
+            throws IOException
+    {
+        int len = 8192;
+        byte[] bytes = new byte[len];
+        while ((len = in.read(bytes, 0, len)) != -1)
+        {
+            out.write(bytes, 0, len);
+        }
+        // C: caller is responsible for closing the streams.
+        out.flush();
+    }
+
+    /**
+	 * Write a String to a file
+	 * @param fileName
+	 * @param output
+	 * @throws java.io.IOException
+	 */
+	public static void writeFile(String fileName, String output) throws FileNotFoundException, IOException
+	{
+		File file = openFile(fileName);
+		if (file == null)
+		{
+			throw new FileNotFoundException(fileName);
+		}
+
+		Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF8"));
+		try
+		{
+			out.write(output);
+			out.flush();
+		}
+		finally
+		{
+			out.close();
+		}
+	}
+
+	public static void writeBinaryFile(String fileName, byte[] output) throws FileNotFoundException, IOException
+	{
+		File file = openFile(fileName);
+		if (file == null)
+		{
+			throw new FileNotFoundException(fileName);
+		}
+
+		OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
+		try
+		{
+			out.write(output);
+			out.flush();
+		}
+		finally
+		{
+			out.close();
+		}
+	}
+
+	public static String getCanonicalPath(String path)
+	{
+		File f = openFile(path);
+		return (f == null) ? null : getCanonicalPath(f);
+	}
+	
+	public static String getCanonicalPath(File f)
+	{
+		try
+		{
+			return f.getCanonicalPath();
+		}
+		catch (IOException ex)
+		{
+			return f.getAbsolutePath();
+		}
+	}
+
+	public static File getCanonicalFile(File f)
+	{
+		try
+		{
+			return f.getCanonicalFile();
+		}
+		catch (IOException ex)
+		{
+			return f.getAbsoluteFile();
+		}
+	}
+
+	public static String readFile(File f)
+	{
+		BufferedReader file = null;
+		StringBuilder buffer = new StringBuilder((int) f.length());
+		String lineSep = System.getProperty("line.separator");
+
+		try
+		{
+            /* TODO
+             * Do we need a BufferedReader layered on a BufferedInputStream?
+             * There are so many levels of indirection here that it would be a good idea
+             * to have an InputBufferReader (like InputBufferStream) and openReader()
+             */
+			file = new BufferedReader(new InputStreamReader(FileUtil.openStream(f)));
+			String s = null;
+			while ((s = file.readLine()) != null)
+			{
+				buffer.append(s);
+				buffer.append(lineSep);
+			}
+			return buffer.toString();
+		}
+		catch (FileNotFoundException ex)
+		{
+			return null;
+		}
+		catch (IOException ex)
+		{
+			return null;
+		}
+		finally
+		{
+			if (file != null)
+			{
+				try
+				{
+					file.close();
+				}
+				catch (IOException ex)
+				{
+				}
+			}
+		}
+	}
+
+	public static String readLine(String f, int line)
+	{
+		BufferedReader file = null;
+		try
+		{
+			file = new BufferedReader(new InputStreamReader(FileUtil.openStream(f), "UTF8"));
+			for (int i = 0; i < line - 1 && file.readLine() != null; i++);
+			return file.readLine();
+		}
+		catch (FileNotFoundException ex)
+		{
+			return null;
+		}
+		catch (IOException ex)
+		{
+			return null;
+		}
+		finally
+		{
+			if (file != null)
+			{
+				try
+				{
+					file.close();
+				}
+				catch (IOException ex)
+				{
+				}
+			}
+		}
+	}
+
+	public static byte[] readBytes(String f, int line)
+	{
+		BufferedInputStream in = null;
+		ByteArrayOutputStream baos = new ByteArrayOutputStream();
+		boolean lastIsCR = false;
+		int pos = 0, ch = 0, count = 0;
+		try
+		{
+			in = new BufferedInputStream(FileUtil.openStream(f));
+			while ((ch = in.read()) != -1)
+			{
+				if (lastIsCR)
+				{
+					count++;
+					if (line == count)
+					{
+						return baos.toByteArray();
+					}
+					else
+					{
+						baos.reset();
+					}
+
+					if (ch == '\n')
+					{
+						lastIsCR = false;
+					}
+					else if (ch == '\r')
+					{
+						lastIsCR = true;
+					}
+					else
+					{
+						baos.write(ch);
+						lastIsCR = false;
+					}
+				}
+				else
+				{
+					if (ch == '\n')
+					{
+						count++;
+						if (line == count)
+						{
+							return baos.toByteArray();
+						}
+						else
+						{
+							baos.reset();
+						}
+						lastIsCR = false;
+					}
+					else if (ch == '\r')
+					{
+						lastIsCR = true;
+					}
+					else
+					{
+						baos.write(ch);
+						lastIsCR = false;
+					}
+				}
+				pos++;
+			}
+			return null;
+		}
+		catch (FileNotFoundException ex)
+		{
+			return null;
+		}
+		catch (IOException ex)
+		{
+			return null;
+		}
+		finally
+		{
+			if (in != null) { try { in.close(); } catch (IOException ex) {} }
+		}
+	}
+	
+	/**
+	 * check whether the provided path is a subdirectory of the list of directories and vice versa.
+	 * @param path
+	 * @param directories
+	 * @return -1 if not
+	 */
+	public static int isSubdirectoryOf(File pathFile, List directories)
+	{
+		String path = pathFile.toString();
+		for (int j = 0, size = directories.size(); j < size; j++)
+		{
+			File dirFile = FileUtil.getCanonicalFile((File) directories.get(j));
+			String dir = dirFile.toString();
+			if (! pathFile.getParent().equals(dirFile.getParent()) &&
+			    (path.length() > dir.length() && path.startsWith(dir) ||
+			     dir.length() > path.length() && dir.startsWith(path)))
+			{
+				return j;
+			}
+		}
+		return -1;
+	}
+	
+	/**
+	 * check whether the provided directory is a subdirectory of the list of directories.
+	 * @param directory
+	 * @param directories
+	 * @return -1 if not
+	 */
+	public static int isSubdirectoryOf(String directory, VirtualFile[] directories)
+	{
+		File pathFile = FileUtil.openFile(directory);
+		String path = pathFile.toString();
+		for (int j = 0, size = directories == null ? 0 : directories.length; j < size; j++)
+		{
+			File dirFile = FileUtil.openFile(directories[j].getName());
+			String dir = dirFile.toString();
+			if (!pathFile.getParent().equals(dirFile.getParent()) && path.length() > dir.length() && path.startsWith(dir))
+			{
+				return j;
+			}
+		}
+		return -1;
+	}
+	
+	public static String getExceptionMessage(Exception ex)
+	{
+		return getExceptionMessage(ex, true);
+	}
+
+	public static String getExceptionMessage(Exception ex, boolean stackDump)
+	{
+		String m = ex.getMessage();
+		
+		if (m == null)
+		{
+			m = ex.getLocalizedMessage();
+		}
+		
+		if (m == null)
+		{
+			m = "(" + ex.getClass().getName() + ")";
+			if (stackDump)
+			{
+				StringWriter s = new StringWriter();
+				PrintWriter p = new PrintWriter(s, true);
+				ex.printStackTrace(p);
+				m += s.getBuffer().toString();
+			}
+		}
+		
+		return m;
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dff3a518/flex-compiler-oem/src/flex2/compiler/io/LocalFile.java
----------------------------------------------------------------------
diff --git a/flex-compiler-oem/src/flex2/compiler/io/LocalFile.java b/flex-compiler-oem/src/flex2/compiler/io/LocalFile.java
new file mode 100644
index 0000000..1980267
--- /dev/null
+++ b/flex-compiler-oem/src/flex2/compiler/io/LocalFile.java
@@ -0,0 +1,204 @@
+/*
+ *
+ *  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.compiler.io;
+
+//import flash.util.FileUtils;
+//import flash.util.Trace;
+import flex2.compiler.util.MimeMappings;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+
+/**
+ * A VirtualFile implemenation, which is backed by a file on a local
+ * disk.
+ *
+ * @author Clement Wong
+ */
+public class LocalFile implements VirtualFile
+{
+
+	public LocalFile(File f)
+	{
+		this.f = f;
+	}
+
+	private File f;
+	private String name;
+	private String mimeType;
+
+	/**
+	 * Return name... It could be canonical path name, URL, etc. But it must be unique among all the files
+	 * processed by the compiler...
+	 *
+	 * The compiler should not use this to get... e.g. parent path... There is no guarantee that this returns
+	 * a pathname even though the underlying implementation deals with files...
+	 */
+	public String getName()
+	{
+		if (name == null)
+		{
+			name = FileUtil.getCanonicalPath(f);
+			f = FileUtil.openFile(name);
+		}
+
+		return name;
+	}
+
+	public String getNameForReporting()
+	{
+		return getName();
+	}
+
+	public String getURL()
+	{
+		try
+		{
+			return f.toURL().toExternalForm();
+		}
+		catch (MalformedURLException ex)
+		{
+			return null;
+		}
+	}
+
+	// This is temporary...
+	public String getParent()
+	{
+		return f.getParentFile().getAbsolutePath();
+	}
+
+	public boolean isDirectory()
+	{
+		return f.isDirectory();
+	}
+
+	/**
+	 * Return file size...
+	 */
+	public long size()
+	{
+		return f.length();
+	}
+
+	/**
+	 * Return mime type
+	 */
+	public String getMimeType()
+	{
+		if (mimeType == null)
+		{
+			mimeType = MimeMappings.getMimeType(getName());
+		}
+		return mimeType;
+	}
+
+	/**
+	 * Return input stream...
+	 */
+	public InputStream getInputStream() throws IOException
+	{
+		return FileUtil.openStream(f);
+	}
+
+	public byte[] toByteArray() throws IOException
+	{
+		return null;
+	}
+
+	/**
+	 * Return last time the underlying source is modified.
+	 */
+	public long getLastModified()
+	{
+		return f.lastModified();
+	}
+
+	/**
+	 * Return an instance of this interface which represents the specified relative path.
+	 */
+	public VirtualFile resolve(String relativeStr)
+	{
+		File relativeFile = null;
+
+		if (f.isDirectory())
+		{
+			relativeFile = FileUtil.openFile(f, relativeStr);
+		}
+		else if (f.isFile())
+		{
+			relativeFile = FileUtil.openFile(f.getParentFile(), relativeStr);
+		}
+
+		VirtualFile result = null;
+
+		if (relativeFile != null && relativeFile.exists())
+		{
+			result = new LocalFile(relativeFile);
+		}
+
+		/* AJH later
+		if ((result != null) && Trace.pathResolver)
+		{
+			Trace.trace("LocalFile.resolve: resolved " + relativeStr + " to " + result.getName());
+		}
+        (*/
+    
+		return result;
+	}
+
+	/**
+	 * Signal the hosting environment that this instance is no longer used.
+	 */
+	public void close()
+	{
+	}
+
+	public boolean equals(Object obj)
+	{
+		boolean result = false;
+
+		if (obj instanceof LocalFile)
+		{
+			result = (this == obj) || getName().equals(((LocalFile) obj).getName());
+		}
+
+		return result;
+	}
+
+	public int hashCode()
+	{
+		return getName().hashCode();
+	}
+
+	public boolean isTextBased()
+	{
+		return false;
+	}
+
+	public String toString()
+	{
+		return getName();
+	}
+}
+
+

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dff3a518/flex-compiler-oem/src/flex2/compiler/io/VirtualFile.java
----------------------------------------------------------------------
diff --git a/flex-compiler-oem/src/flex2/compiler/io/VirtualFile.java b/flex-compiler-oem/src/flex2/compiler/io/VirtualFile.java
new file mode 100644
index 0000000..9f9acef
--- /dev/null
+++ b/flex-compiler-oem/src/flex2/compiler/io/VirtualFile.java
@@ -0,0 +1,102 @@
+/*
+ *
+ *  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.compiler.io;
+
+import flex2.compiler.common.SinglePathResolver;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Defines the API to by used by all virtual files.
+ *
+ * @author Clement Wong
+ */
+public interface VirtualFile extends SinglePathResolver
+{
+	/**
+	 * Return name... It could be canonical path name, URL, etc. But it must be unique among all the files
+	 * processed by the compiler...
+	 *
+	 * The compiler should not use this to get... e.g. parent path... There is no guarantee that this returns
+	 * a pathname even though the underlying implementation deals with files...
+	 */
+	String getName();
+
+	/**
+	 * Return the name to be used when reporting errors or warnings.
+	 */ 
+	String getNameForReporting();
+
+	/**
+	 * Return an URL string of this file
+	 */ 
+	String getURL();
+
+	// This is only temporary for asc...
+	String getParent();
+
+    boolean isDirectory();
+
+    /**
+	 * Return file size...
+	 */
+	long size();
+
+	/**
+	 * Return mime type
+	 */
+	String getMimeType();
+
+	/**
+	 * Return input stream...
+	 */
+	InputStream getInputStream() throws IOException;
+
+	/**
+	 * Return the entire content in byte[]
+	 */
+	byte[] toByteArray() throws IOException;
+
+	/**
+	 * Return true if it's text-based. toString() returns the text
+	 */
+	boolean isTextBased();
+
+	/**
+	 * Return last time the underlying source is modified.
+	 */
+	long getLastModified();
+
+	/**
+	 * Signal the hosting environment that this instance is no longer used.
+	 */
+	void close();
+
+	/**
+	 * Override equals(). Instances of VirtualFile can be used as keys.
+	 */
+	boolean equals(Object object);
+
+	/**
+	 * Override hashCode(). Instances of VirtualFile can be used as keys.
+	 */
+	int hashCode();
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dff3a518/flex-compiler-oem/src/flex2/compiler/mxml/MxmlConfiguration.java
----------------------------------------------------------------------
diff --git a/flex-compiler-oem/src/flex2/compiler/mxml/MxmlConfiguration.java b/flex-compiler-oem/src/flex2/compiler/mxml/MxmlConfiguration.java
new file mode 100644
index 0000000..64869fd
--- /dev/null
+++ b/flex-compiler-oem/src/flex2/compiler/mxml/MxmlConfiguration.java
@@ -0,0 +1,182 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package flex2.compiler.mxml;
+
+import flex2.compiler.config.ServicesDependenciesWrapper;
+import flex2.compiler.common.FontsConfiguration;
+import flex2.compiler.io.VirtualFile;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This interface is used to restrict consumers of
+ * CompilerConfiguration to mxml compiler specific options.
+ *
+ * @author Clement Wong
+ */
+public interface MxmlConfiguration
+{
+	/**
+	 * Generate SWFs for debugging.
+	 */
+	boolean debug();
+
+	/**
+	 * Generate accessible SWFs.
+	 */
+	boolean accessible();
+
+	/**
+	 * Write xxx-generated.as to disk.
+	 */
+	boolean keepGeneratedActionScript();
+
+	/**
+	 * Enable runtime DesignLayer support.
+	 */
+	boolean enableRuntimeDesignLayers();
+	
+	/**
+	 * Enable swc version filtering (filer out swcs with 
+	 * minimumSupportedVersion > compatibility-version)
+	 */
+	boolean enableSwcVersionFiltering();
+	
+    /**
+     * Controls whether unused type selectors are processed.
+     */
+    boolean keepAllTypeSelectors();
+
+    String getGeneratedDirectory();
+
+    /**
+     * Controls whether invalid styles are report as errors or
+     * warnings.
+     */
+    boolean reportInvalidStylesAsWarnings();
+
+	/**
+	 * Controls whether warnings are displayed when a deprecated API is used.
+	 */
+	boolean showDeprecationWarnings();
+
+    /**
+     * Controls whether warnings are displayed when a deprecated API is used.
+     */
+    boolean showBindingWarnings();
+
+    /**
+     * Controls whether warnings are displayed when styles, which
+     * don't apply to the current theme(s), are used in CSS.
+     */
+    boolean showInvalidCssPropertyWarnings();
+
+    /**
+     * Controls whether warnings are displayed when an embedded font name
+     * shadows a device font name.
+     */
+    boolean showShadowedDeviceFontWarnings();
+
+    /**
+     * Toggles whether warnings generated from unused type selectors are displayed.
+     */
+    boolean showUnusedTypeSelectorWarnings();
+    
+    /**
+     * Context path used to resolve {context.root} tokens in flex-enterprise-services.xml config file
+     */
+    String getContextRoot();
+
+    /**
+     * Compiler-specific representation of flex-enterprise-services.xml config file
+     */
+    ServicesDependenciesWrapper getServicesDependencies();
+
+	/**
+	 * The compatibility version as a String.
+	 */
+	String getCompatibilityVersionString();
+
+	/**
+	 * The compatibility version as a uint.
+	 */
+	int getCompatibilityVersion();
+
+	/**
+	 * Determines whether CSS type selectors need to be qualified.
+	 */
+	boolean getQualifiedTypeSelectors();
+
+	/**
+	 * Location of defaults.css stylesheet.
+	 */
+	VirtualFile getDefaultsCssUrl();
+
+	/**
+	 * Location of SWC defaults.css stylesheets.
+	 */
+	List<VirtualFile> getDefaultsCssFiles();
+
+	/**
+	 * Location of theme stylesheets.
+	 */
+	List<VirtualFile> getThemeCssFiles();
+
+	/**
+	 * Path locations of source files.
+	 */
+	VirtualFile[] getSourcePath();
+
+	/**
+	 * Path locations of component libraries, including swcs, mxml, and as components.
+	 * Note: all SWCs found in the lib-path are merged together and resolved via priority and version.
+	 * The order is ignored.
+	 */
+	VirtualFile[] getLibraryPath();
+
+	/**
+	 * True if we are compiling against airglobal.swc.
+	 */
+	boolean getCompilingForAIR();
+
+	/**
+	 * Provides settings for the Font Managers, their caches, and aliases for character
+	 * ranges to embed for font face.
+	 */
+	FontsConfiguration getFontsConfiguration();
+    void setFontsConfiguration(FontsConfiguration fc);
+
+	boolean getGenerateAbstractSyntaxTree();
+
+    Set<String> getThemeNames();
+	
+    /**
+     * Allow a style manager to have the same style declarations as
+     * their parent.
+     */
+	boolean getAllowDuplicateDefaultStyleDeclarations();
+
+    /**
+     * Whether a missing required skin part should be considered an error or
+     * just be a warning.
+     */
+	boolean reportMissingRequiredSkinPartsAsWarnings();
+}