You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by cd...@apache.org on 2016/04/13 20:56:19 UTC

[27/51] [partial] git commit: [flex-falcon] [refs/heads/feature/maven-migration-test] - - Check-In of the migrated project to make error analysis easier

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/as/TestStatements.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/as/TestStatements.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/as/TestStatements.java
new file mode 100644
index 0000000..00bfece
--- /dev/null
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/as/TestStatements.java
@@ -0,0 +1,469 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.as;
+
+import org.apache.flex.compiler.internal.test.ASTestBase;
+import org.apache.flex.compiler.internal.tree.as.LabeledStatementNode;
+import org.apache.flex.compiler.tree.as.IFileNode;
+import org.apache.flex.compiler.tree.as.IForLoopNode;
+import org.apache.flex.compiler.tree.as.IIfNode;
+import org.apache.flex.compiler.tree.as.ISwitchNode;
+import org.apache.flex.compiler.tree.as.IThrowNode;
+import org.apache.flex.compiler.tree.as.ITryNode;
+import org.apache.flex.compiler.tree.as.IVariableNode;
+import org.apache.flex.compiler.tree.as.IWhileLoopNode;
+import org.apache.flex.compiler.tree.as.IWithNode;
+import org.junit.Test;
+
+/**
+ * @author Michael Schmalle
+ */
+public class TestStatements extends ASTestBase
+{
+    //--------------------------------------------------------------------------
+    // if
+    //--------------------------------------------------------------------------
+
+    //----------------------------------
+    // var declaration
+    //----------------------------------
+
+    @Test
+    public void testVarDeclaration()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var a:*");
+    }
+
+    @Test
+    public void testVarDeclaration_withType()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:int;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var a:int");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeAssignedValue()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:int = 42;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var a:int = 42");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeAssignedValueComplex()
+    {
+        IVariableNode node = (IVariableNode) getNode(
+                "var a:Foo = new Foo(42, 'goo');", IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var a:Foo = new Foo(42, 'goo')");
+    }
+
+    @Test
+    public void testVarDeclaration_withList()
+    {
+        IVariableNode node = (IVariableNode) getNode(
+                "var a:int = 4, b:int = 11, c:int = 42;", IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var a:int = 4, b:int = 11, c:int = 42");
+    }
+
+    //----------------------------------
+    // const declaration
+    //----------------------------------
+
+    @Test
+    public void testConstDeclaration()
+    {
+        IVariableNode node = (IVariableNode) getNode("const a = 42;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("const a:* = 42");
+    }
+
+    @Test
+    public void testConstDeclaration_withType()
+    {
+        IVariableNode node = (IVariableNode) getNode("const a:int = 42;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("const a:int = 42");
+    }
+
+    @Test
+    public void testConstDeclaration_withList()
+    {
+        IVariableNode node = (IVariableNode) getNode(
+                "const a:int = 4, b:int = 11, c:int = 42;", IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("const a:int = 4, b:int = 11, c:int = 42");
+    }
+
+    //----------------------------------
+    // if ()
+    //----------------------------------
+
+    @Test
+    public void testVisitIf_1()
+    {
+        IIfNode node = (IIfNode) getNode("if (a) b++;", IIfNode.class);
+        asBlockWalker.visitIf(node);
+        assertOut("if (a)\n\tb++;");
+    }
+
+    @Test
+    public void testVisitIf_2()
+    {
+        IIfNode node = (IIfNode) getNode("if (a) b++; else c++;", IIfNode.class);
+        asBlockWalker.visitIf(node);
+        assertOut("if (a)\n\tb++;\nelse\n\tc++;");
+    }
+
+    @Test
+    public void testVisitIf_4()
+    {
+        IIfNode node = (IIfNode) getNode(
+                "if (a) b++; else if (c) d++; else if(e) --f;", IIfNode.class);
+        asBlockWalker.visitIf(node);
+        assertOut("if (a)\n\tb++;\nelse if (c)\n\td++;\nelse if (e)\n\t--f;");
+    }
+
+    //----------------------------------
+    // if () { }
+    //----------------------------------
+
+    @Test
+    public void testVisitIf_1a()
+    {
+        IIfNode node = (IIfNode) getNode("if (a) { b++; }", IIfNode.class);
+        asBlockWalker.visitIf(node);
+        assertOut("if (a) {\n\tb++;\n}");
+    }
+
+    @Test
+    public void testVisitIf_1b()
+    {
+        IIfNode node = (IIfNode) getNode("if (a) { b++; } else { c++; }",
+                IIfNode.class);
+        asBlockWalker.visitIf(node);
+        assertOut("if (a) {\n\tb++;\n} else {\n\tc++;\n}");
+    }
+
+    @Test
+    public void testVisitIf_1c()
+    {
+        IIfNode node = (IIfNode) getNode(
+                "if (a) { b++; } else if (b) { c++; } else { d++; }",
+                IIfNode.class);
+        asBlockWalker.visitIf(node);
+        assertOut("if (a) {\n\tb++;\n} else if (b) {\n\tc++;\n} else {\n\td++;\n}");
+    }
+
+    @Test
+    public void testVisitIf_3()
+    {
+        IIfNode node = (IIfNode) getNode(
+                "if (a) b++; else if (c) d++; else --e;", IIfNode.class);
+        asBlockWalker.visitIf(node);
+        assertOut("if (a)\n\tb++;\nelse if (c)\n\td++;\nelse\n\t--e;");
+    }
+
+    //----------------------------------
+    // for () { }
+    //----------------------------------
+
+    @Test
+    public void testVisitFor_1a()
+    {
+        IForLoopNode node = (IForLoopNode) getNode(
+                "for (var i:int = 0; i < len; i++) { break; }",
+                IForLoopNode.class);
+        asBlockWalker.visitForLoop(node);
+        assertOut("for (var i:int = 0; i < len; i++) {\n\tbreak;\n}");
+    }
+
+    @Test
+    public void testVisitFor_1b()
+    {
+        IForLoopNode node = (IForLoopNode) getNode(
+                "for (var i:int = 0; i < len; i++) break;", IForLoopNode.class);
+        asBlockWalker.visitForLoop(node);
+        assertOut("for (var i:int = 0; i < len; i++)\n\tbreak;");
+    }
+
+    @Test
+    public void testVisitFor_2()
+    {
+        IForLoopNode node = (IForLoopNode) getNode("for (;;) { break; }",
+                IForLoopNode.class);
+        asBlockWalker.visitForLoop(node);
+        assertOut("for (;;) {\n\tbreak;\n}");
+    }
+
+    @Test
+    public void testVisitForIn_1()
+    {
+        IForLoopNode node = (IForLoopNode) getNode(
+                "for (var i:int in obj) { break; }", IForLoopNode.class);
+        asBlockWalker.visitForLoop(node);
+        assertOut("for (var i:int in obj) {\n\tbreak;\n}");
+    }
+
+    @Test
+    public void testVisitForIn_1a()
+    {
+        IForLoopNode node = (IForLoopNode) getNode(
+                "for (var i:int in obj)  break; ", IForLoopNode.class);
+        asBlockWalker.visitForLoop(node);
+        assertOut("for (var i:int in obj)\n\tbreak;");
+    }
+
+    @Test
+    public void testVisitForEach_1()
+    {
+        IForLoopNode node = (IForLoopNode) getNode(
+                "for each(var i:int in obj) { break; }", IForLoopNode.class);
+        asBlockWalker.visitForLoop(node);
+        assertOut("for each (var i:int in obj) {\n\tbreak;\n}");
+    }
+
+    @Test
+    public void testVisitForEach_1a()
+    {
+        IForLoopNode node = (IForLoopNode) getNode(
+                "for each(var i:int in obj)  break; ", IForLoopNode.class);
+        asBlockWalker.visitForLoop(node);
+        assertOut("for each (var i:int in obj)\n\tbreak;");
+    }
+
+    //----------------------------------
+    // while () { }
+    //----------------------------------
+
+    @Test
+    public void testVisitWhileLoop_1()
+    {
+        IWhileLoopNode node = (IWhileLoopNode) getNode(
+                "while(a > b){a++;--b;}", IWhileLoopNode.class);
+        asBlockWalker.visitWhileLoop(node);
+        assertOut("while (a > b) {\n\ta++;\n\t--b;\n}");
+    }
+
+    @Test
+    public void testVisitWhileLoop_1a()
+    {
+        IWhileLoopNode node = (IWhileLoopNode) getNode("while(a > b) a++;",
+                IWhileLoopNode.class);
+        asBlockWalker.visitWhileLoop(node);
+        assertOut("while (a > b)\n\ta++;");
+    }
+
+    //----------------------------------
+    // do {} while ()
+    //----------------------------------
+
+    @Test
+    public void testVisitWhileLoop_Do_1()
+    {
+        IWhileLoopNode node = (IWhileLoopNode) getNode(
+                "do {a++;--b;} while(a > b);", IWhileLoopNode.class);
+        asBlockWalker.visitWhileLoop(node);
+        assertOut("do {\n\ta++;\n\t--b;\n} while (a > b);");
+    }
+
+    @Test
+    public void testVisitWhileLoop_Do_1a()
+    {
+        IWhileLoopNode node = (IWhileLoopNode) getNode("do a++; while(a > b);",
+                IWhileLoopNode.class);
+        asBlockWalker.visitWhileLoop(node);
+        assertOut("do\n\ta++;\nwhile (a > b);");
+    }
+
+    //----------------------------------
+    // throw ()
+    //----------------------------------
+
+    @Test
+    public void testVisitThrow()
+    {
+        IThrowNode node = (IThrowNode) getNode("throw new Error('foo');",
+                IThrowNode.class);
+        asBlockWalker.visitThrow(node);
+        assertOut("throw new Error('foo')");
+    }
+
+    //----------------------------------
+    // try {} catch () {} finally {}
+    //----------------------------------
+
+    @Test
+    public void testVisitTry_Catch()
+    {
+        ITryNode node = (ITryNode) getNode("try { a; } catch (e:Error) { b; }",
+                ITryNode.class);
+        asBlockWalker.visitTry(node);
+        assertOut("try {\n\ta;\n} catch (e:Error) {\n\tb;\n}");
+    }
+
+    @Test
+    public void testVisitTry_Catch_Finally()
+    {
+        ITryNode node = (ITryNode) getNode(
+                "try { a; } catch (e:Error) { b; } finally { c; }",
+                ITryNode.class);
+        asBlockWalker.visitTry(node);
+        assertOut("try {\n\ta;\n} catch (e:Error) {\n\tb;\n} finally {\n\tc;\n}");
+    }
+
+    @Test
+    public void testVisitTry_Catch_Catch_Finally()
+    {
+        ITryNode node = (ITryNode) getNode(
+                "try { a; } catch (e:Error) { b; } catch (f:Error) { c; } finally { d; }",
+                ITryNode.class);
+        asBlockWalker.visitTry(node);
+        assertOut("try {\n\ta;\n} catch (e:Error) {\n\tb;\n} catch (f:Error) {\n\tc;\n} finally {\n\td;\n}");
+    }
+
+    @Test
+    public void testVisitTry_CatchEmpty_FinallyEmpty_()
+    {
+        ITryNode node = (ITryNode) getNode(
+                "try { a; } catch (e:Error) {  } finally {  }", ITryNode.class);
+        asBlockWalker.visitTry(node);
+        assertOut("try {\n\ta;\n} catch (e:Error) {\n} finally {\n}");
+    }
+
+    //----------------------------------
+    // switch {}
+    //----------------------------------
+
+    @Test
+    public void testVisitSwitch_1()
+    {
+        ISwitchNode node = (ISwitchNode) getNode("switch(i){case 1: break;}",
+                ISwitchNode.class);
+        asBlockWalker.visitSwitch(node);
+        assertOut("switch (i) {\n\tcase 1:\n\t\tbreak;\n}");
+    }
+
+    @Test
+    public void testVisitSwitch_1a()
+    {
+        ISwitchNode node = (ISwitchNode) getNode(
+                "switch(i){case 1: { break; }}", ISwitchNode.class);
+        asBlockWalker.visitSwitch(node);
+        // (erikdebruin) the code is valid without the extra braces, 
+        //               i.e. we're good, we "don't care"
+        assertOut("switch (i) {\n\tcase 1:\n\t\tbreak;\n}");
+    }
+
+    @Test
+    public void testVisitSwitch_2()
+    {
+        ISwitchNode node = (ISwitchNode) getNode(
+                "switch(i){case 1: break; default: return;}", ISwitchNode.class);
+        asBlockWalker.visitSwitch(node);
+        assertOut("switch (i) {\n\tcase 1:\n\t\tbreak;\n\tdefault:\n\t\treturn;\n}");
+    }
+
+    @Test
+    public void testVisitSwitch_3()
+    {
+        ISwitchNode node = (ISwitchNode) getNode(
+                "switch(i){case 1: { var x:int = 42; break; }; case 2: { var y:int = 66; break; }}", ISwitchNode.class);
+        asBlockWalker.visitSwitch(node);
+        assertOut("switch (i) {\n\tcase 1:\n\t\tvar x:int = 42;\n\t\tbreak;\n\tcase 2:\n\t\tvar y:int = 66;\n\t\tbreak;\n}");
+    }
+
+    //----------------------------------
+    // label : for () {}
+    //----------------------------------
+
+    @Test
+    public void testVisitLabel_1()
+    {
+        LabeledStatementNode node = (LabeledStatementNode) getNode(
+                "foo: for each(var i:int in obj) { break foo; }",
+                LabeledStatementNode.class);
+        asBlockWalker.visitLabeledStatement(node);
+        assertOut("foo : for each (var i:int in obj) {\n\tbreak foo;\n}");
+    }
+
+    @Test
+    public void testVisitLabel_1a()
+    {
+        // ([unknown]) LabelStatement messes up in finally{} block, something is wrong there
+        
+        // (erikdebruin) I don't see a finally block in the test code and the 
+        //               test passes... What's wrong?
+        
+        LabeledStatementNode node = (LabeledStatementNode) getNode(
+                "foo: for each(var i:int in obj) break foo;",
+                LabeledStatementNode.class);
+        asBlockWalker.visitLabeledStatement(node);
+        assertOut("foo : for each (var i:int in obj)\n\tbreak foo;");
+    }
+
+    //----------------------------------
+    // with () {}
+    //----------------------------------
+
+    @Test
+    public void testVisitWith()
+    {
+        IWithNode node = (IWithNode) getNode("with (a) { b; }", IWithNode.class);
+        asBlockWalker.visitWith(node);
+        assertOut("with (a) {\n\tb;\n}");
+    }
+
+    @Test
+    public void testVisitWith_1a()
+    {
+        IWithNode node = (IWithNode) getNode("with (a) b;", IWithNode.class);
+        asBlockWalker.visitWith(node);
+        assertOut("with (a)\n\tb;");
+    }
+
+    @Test
+    public void testVisit()
+    {
+        IFileNode node = (IFileNode) getNode(
+                "try { a; } catch (e:Error) { if (a) { if (b) { if (c) b; else if (f) a; else e; }} } finally {  }"
+                        + "if (d) for (var i:int = 0; i < len; i++) break;"
+                        + "if (a) { with (ab) { c(); } "
+                        + "do {a++;do a++; while(a > b);} while(c > d); }"
+                        + "if (b) { try { a; throw new Error('foo'); } catch (e:Error) { "
+                        + " switch(i){case 1: break; default: return;}"
+                        + " } catch (f:Error) { c; eee.dd; } finally { "
+                        + "  d;  var a:Object = function(foo:int, bar:String = 'goo'):int{return -1;};"
+                        + "  eee.dd; eee.dd; eee.dd; eee.dd;} }"
+                        + "foo: for each(var i:int in obj) break foo;",
+                IFileNode.class);
+        asBlockWalker.visitFile(node);
+        assertOut("package {\n\tpublic class FalconTest_A {\n\t\tfunction falconTest_a():void {\n\t\t\ttry {\n\t\t\t\ta;\n\t\t\t} catch (e:Error) {\n\t\t\t\tif (a) {\n\t\t\t\t\tif (b) {\n\t\t\t\t\t\tif (c)\n\t\t\t\t\t\t\tb;\n\t\t\t\t\t\telse if (f)\n\t\t\t\t\t\t\ta;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\te;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t}\n\t\t\tif (d)\n\t\t\t\tfor (var i:int = 0; i < len; i++)\n\t\t\t\t\tbreak;\n\t\t\tif (a) {\n\t\t\t\twith (ab) {\n\t\t\t\t\tc();\n\t\t\t\t}\n\t\t\t\tdo {\n\t\t\t\t\ta++;\n\t\t\t\t\tdo\n\t\t\t\t\t\ta++;\n\t\t\t\t\twhile (a > b);\n\t\t\t\t} while (c > d);\n\t\t\t}\n\t\t\tif (b) {\n\t\t\t\ttry {\n\t\t\t\t\ta;\n\t\t\t\t\tthrow new Error('foo');\n\t\t\t\t} catch (e:Error) {\n\t\t\t\t\tswitch (i) {\n\t\t\t\t\t\tcase 1:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t} catch (f:Error) {\n\t\t\t\t\tc;\n\t\t\t\t\teee.dd;\n\t\t\t\t} finally {\n\t\t\t\t\td;\n\t\t\t\t\tvar a:Object = function(foo:int, bar:S
 tring = 'goo'):int {\n\t\t\t\t\t\treturn -1;\n\t\t\t\t\t};\n\t\t\t\t\teee.dd;\n\t\t\t\t\teee.dd;\n\t\t\t\t\teee.dd;\n\t\t\t\t\teee.dd;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfoo : for each (var i:int in obj)\n\t\t\t\tbreak foo;;\n\t}\n}\n}");
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/CompilerArguments.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/CompilerArguments.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/CompilerArguments.java
new file mode 100644
index 0000000..fa7ef1d
--- /dev/null
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/CompilerArguments.java
@@ -0,0 +1,408 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.externals;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Michael Schmalle
+ */
+public class CompilerArguments
+{
+    private List<String> bundles = new ArrayList<String>();
+
+    private List<String> libraries = new ArrayList<String>();
+
+    private List<String> sources = new ArrayList<String>();
+
+    private List<String> includes = new ArrayList<String>();
+
+    private String sdkPath = "";
+
+    private String appName = "";
+
+    private String output;
+
+    private String jsLibraryPath = "";
+
+    private String jsBasePath = "";
+
+    private Boolean jsOutputAsFiles = null;
+
+    //    private List<MergedFileSettings> jsMergedFiles = new ArrayList<MergedFileSettings>();
+
+    public void addBundlePath(String path)
+    {
+        if (bundles.contains(path))
+            return;
+        bundles.add(path);
+    }
+
+    public void addLibraryPath(String path)
+    {
+        if (libraries.contains(path))
+            return;
+        libraries.add(path);
+    }
+
+    public void addSourcepath(String path)
+    {
+        if (sources.contains(path))
+            return;
+        sources.add(path);
+    }
+
+    public void addIncludedSources(String path)
+    {
+        if (includes.contains(path))
+            return;
+        includes.add(path);
+    }
+
+    public List<String> getBundles()
+    {
+        return bundles;
+    }
+
+    public List<String> getLibraries()
+    {
+        return libraries;
+    }
+
+    public List<String> getSources()
+    {
+        return sources;
+    }
+
+    public List<String> getIncludes()
+    {
+        return includes;
+    }
+
+    public String getSDKPath()
+    {
+        return sdkPath;
+    }
+
+    public void setSDKPath(String value)
+    {
+        sdkPath = value;
+    }
+
+    public String getAppName()
+    {
+        return appName;
+    }
+
+    public void setAppName(String value)
+    {
+        appName = value;
+    }
+
+    public String getOutput()
+    {
+        return output;
+    }
+
+    public void setOutput(String path)
+    {
+        output = path;
+    }
+
+    public String getJsLibraryPath()
+    {
+        return jsLibraryPath;
+    }
+
+    public void setJsLibraryPath(String jsLibraryPath)
+    {
+        this.jsLibraryPath = jsLibraryPath;
+    }
+
+    public String getJsBasePath()
+    {
+        return jsBasePath;
+    }
+
+    public void setJsBasePath(String jsBasePath)
+    {
+        this.jsBasePath = jsBasePath;
+    }
+
+    public Boolean isJsOutputAsFiles()
+    {
+        return jsOutputAsFiles;
+    }
+
+    public void setJsOutputAsFiles(Boolean jsOutputAsFiles)
+    {
+        this.jsOutputAsFiles = jsOutputAsFiles;
+    }
+
+    //    public void addJsMergedFiles(MergedFileSettings setting)
+    //    {
+    //        jsMergedFiles.add(setting);
+    //    }
+
+    //--------------------------------------------------------------------------
+    // SWC
+    //--------------------------------------------------------------------------
+
+    private List<String> metadatas = new ArrayList<String>();
+
+    // -keep-as3-metadata
+    public List<String> getKeepMetadata()
+    {
+        return metadatas;
+    }
+
+    public void addKeepMetadata(String metadata)
+    {
+        if (metadatas.contains(metadata))
+            return;
+        metadatas.add(metadata);
+    }
+
+    //--------------------------------------------------------------------------
+    // Doc
+    //--------------------------------------------------------------------------
+
+    private List<String> docMembers = new ArrayList<String>();
+
+    private List<String> docNamespace = new ArrayList<String>();
+
+    private String mainTitle;
+
+    public String getMainTitle()
+    {
+        return mainTitle;
+    }
+
+    public void setMainTitle(String value)
+    {
+        mainTitle = value;
+    }
+
+    private String footer;
+
+    public String getFooter()
+    {
+        return footer;
+    }
+
+    public void setFooter(String value)
+    {
+        footer = value;
+    }
+
+    public void addDocMember(String member)
+    {
+        if (docMembers.contains(member))
+            return;
+        docMembers.add(member);
+    }
+
+    public void addDocNamespace(String namespace)
+    {
+        if (docNamespace.contains(namespace))
+            return;
+        docNamespace.add(namespace);
+    }
+
+    public void clear()
+    {
+        jsBasePath = "";
+        jsLibraryPath = "";
+        jsOutputAsFiles = false;
+        output = "";
+        clearLibraries();
+        clearSourcePaths();
+        includes.clear();
+        //        jsMergedFiles.clear();
+    }
+
+    public void clearSourcePaths()
+    {
+        sources = new ArrayList<String>();
+    }
+
+    public void clearBundles()
+    {
+        bundles = new ArrayList<String>();
+    }
+
+    public void clearLibraries()
+    {
+        libraries = new ArrayList<String>();
+    }
+
+    public List<String> toArguments()
+    {
+        List<String> result = new ArrayList<String>();
+
+        for (String arg : bundles)
+        {
+            result.add("-bundle-path=" + arg);
+        }
+
+        for (String arg : libraries)
+        {
+            result.add("-library-path=" + arg);
+        }
+
+        for (String arg : sources)
+        {
+            result.add("-source-path=" + arg);
+        }
+
+        if (includes.size() > 0)
+        {
+            result.add("-include-sources=" + join(includes, ","));
+        }
+        if (metadatas.size() > 0)
+        {
+            result.add("-keep-as3-metadata=" + join(metadatas, ","));
+        }
+
+        //        if (jsMergedFiles.size() > 0)
+        //        {
+        //            final StringBuilder sb = new StringBuilder();
+        //            for (MergedFileSettings setting : jsMergedFiles)
+        //            {
+        //                sb.append("-js-merged-file=");
+        //                sb.append(setting.getFileName());
+        //                sb.append(",");
+        //                sb.append(StringUtils.join(
+        //                        setting.getQualifiedNames().toArray(new String[] {}),
+        //                        ","));
+        //                result.add(sb.toString());
+        //                sb.setLength(0);
+        //            }
+        //        }
+
+        String sdk = getSDKPath();
+        if (sdk != null && !sdk.equals(""))
+            result.add("-sdk-path=" + sdk);
+
+        String name = getAppName();
+        if (name != null && !name.equals(""))
+            result.add("-app-name=" + name);
+
+        String base = getJsBasePath();
+        if (!base.equals(""))
+            result.add("-js-base-path=" + base);
+
+        String library = getJsLibraryPath();
+        if (!library.equals(""))
+            result.add("-js-library-path=" + library);
+
+        if (isJsOutputAsFiles() != null)
+        {
+            result.add("-js-classes-as-files="
+                    + (isJsOutputAsFiles() ? "true" : "false"));
+        }
+
+        result.add("-output=" + getOutput());
+
+        addArguments(result);
+
+        return result;
+    }
+
+    protected void addArguments(List<String> arguments)
+    {
+        String mainTitle = getMainTitle();
+        if (mainTitle != null && !mainTitle.equals(""))
+            arguments.add("-main-title=" + mainTitle);
+
+        if (footer != null && !footer.equals(""))
+            arguments.add("-footer=" + footer);
+
+        if (docMembers.size() > 0)
+        {
+            arguments.add("-doc-member=" + join(docMembers, ","));
+        }
+
+        if (docNamespace.size() > 0)
+        {
+            arguments.add("-doc-namespace=" + join(docNamespace, ","));
+        }
+    }
+
+    private String join(List<String> items, String separator)
+    {
+        StringBuilder sb = new StringBuilder();
+        int len = items.size();
+        int index = 0;
+        for (String item : items)
+        {
+            sb.append(item);
+            if (index < len)
+                sb.append(separator);
+            index++;
+        }
+        return sb.toString();
+    }
+
+    public static class CompilerArgument
+    {
+        private String name;
+
+        private String value;
+
+        CompilerArgument(String name, String value)
+        {
+            this.name = name;
+            this.value = value;
+        }
+
+        public String getValue()
+        {
+            return value;
+        }
+
+        public void setValue(String value)
+        {
+            this.value = value;
+        }
+
+        public String getName()
+        {
+            return name;
+        }
+
+        public void setName(String name)
+        {
+            this.name = name;
+        }
+
+        public static CompilerArgument create(String name, String value)
+        {
+            return new CompilerArgument(name, value);
+        }
+    }
+
+    @Override
+    public String toString()
+    {
+        return join(toArguments(), " ");
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/ExternalsTestBase.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/ExternalsTestBase.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/ExternalsTestBase.java
new file mode 100644
index 0000000..c1526c0
--- /dev/null
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/ExternalsTestBase.java
@@ -0,0 +1,108 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.externals;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.flex.compiler.clients.EXTERNC;
+import org.apache.flex.compiler.clients.ExternCConfiguration;
+import org.apache.flex.compiler.internal.codegen.externals.reference.MethodReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel;
+import org.apache.flex.utils.TestAdapterFactory;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+
+import com.google.javascript.jscomp.Result;
+import com.google.javascript.rhino.jstype.JSType;
+
+public abstract class ExternalsTestBase
+{
+    private static File unitTestBaseDir =
+            new File(TestAdapterFactory.getTestAdapter().getUnitTestBaseDir(), "externals_unit_tests");
+
+    // Only used for testing, all configuration must happen in configure()
+    protected ExternCConfiguration config;
+    protected EXTERNC client;
+    protected ReferenceModel model;
+
+    @Before
+    public void setUp() throws IOException
+    {
+        config = new ExternCConfiguration();
+        configure(config);
+        client = new EXTERNC(config);
+        model = client.getModel();
+    }
+
+    protected abstract void configure(ExternCConfiguration config) throws IOException;
+
+    @After
+    public void tearDown()
+    {
+        model = null;
+    }
+
+    protected Result compile(String fileName) throws IOException
+    {
+        return compile(new File(unitTestBaseDir, fileName));
+    }
+
+    protected Result compile(File file) throws IOException
+    {
+        config.addExternal(file);
+        return compile();
+    }
+
+    protected Result compile() throws IOException
+    {
+        Result result = client.compile();
+        Assert.assertTrue(result.success);
+        return result;
+    }
+
+    protected JSType evaluateParam(MethodReference method, String paramName)
+    {
+        JSType jsType = method.getComment().getParameterType(paramName).evaluate(null,
+                client.getCompiler().getJSCompiler().getTypeRegistry());
+        return jsType;
+    }
+
+    /**
+     * Clean, compile a js file based on the test method name.
+     * 
+     * @param relativeTestDir unitTestBaseDir relative base test directory.
+     * @throws IOException
+     */
+    protected void assertCompileTestFileSuccess(String relativeTestDir) throws IOException
+    {
+        if (config.getAsRoot() != null)
+        {
+            client.cleanOutput();
+        }
+        final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
+        final String methodName = ste[2].getMethodName();
+        Result result = compile(relativeTestDir + methodName + ".js");
+        assertTrue(result.success);
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/ExternalsTestUtils.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/ExternalsTestUtils.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/ExternalsTestUtils.java
new file mode 100644
index 0000000..7956e25
--- /dev/null
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/ExternalsTestUtils.java
@@ -0,0 +1,173 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.externals;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.flex.compiler.clients.ExternCConfiguration;
+import org.apache.flex.utils.FilenameNormalization;
+
+public class ExternalsTestUtils
+{
+    public static File TEMP_DIR = new File(
+            FilenameNormalization.normalize("temp"));
+
+    // XXX missing.js is a temp location until we can figure out where it should placed in the build
+    public static File MISSING_JS_FILE = FilenameNormalization.normalize(new File(
+            "../externs/js/missing.js"));
+
+    // XXX AS3.as is a namespace needed to override toString in some classes
+    public static File AS3_NAMESPACE_FILE = FilenameNormalization.normalize(new File(
+            "../externs/js/src/AS3.as"));
+
+    public static File EXTERNAL_JS_DIR = FilenameNormalization.normalize(new File(
+            "../externs/js/externs"));
+
+    public static File EXTERNAL_JQUERY_DIR = FilenameNormalization.normalize(new File(
+            "../externs/jquery/externs"));
+
+    public static File EXTERNAL_JASMINE_DIR = FilenameNormalization.normalize(new File(
+            "../externs/jasmine/externs"));
+
+    public static File AS_ROOT_DIR = new File(TEMP_DIR, "externals/as");
+
+    public static void addTestExcludesFull(ExternCConfiguration config)
+    {
+        config.addFieldExclude("Window", "focus");
+        config.addClassExclude("controlRange");
+
+        config.addExclude("Array", "toSource");
+        config.addExclude("Date", "valueOf");
+        config.addExclude("String", "valueOf");
+
+        config.addExclude("FontFaceSet", "delete");
+
+        config.addExclude("CSSStyleDeclaration", "cssText");
+        config.addExclude("CSSStyleRule", "style");
+        config.addExclude("CSSFontFaceRule", "style");
+        config.addExclude("CSSPageRule", "style");
+
+        config.addExclude("Generator", "throw");
+        config.addExclude("Generator", "return");
+        config.addExclude("HTMLMenuItemElement", "default");
+        config.addExclude("MessageEvent", "data"); // TODO returns T
+        config.addExclude("MessageEvent", "initMessageEventNS"); // TODO param T
+        config.addExclude("MessageEvent", "initMessageEvent"); // TODO param T
+        config.addExclude("MessageEvent", "default");
+        config.addExclude("Object", "is");
+        config.addExclude("Promise", "catch");
+
+        config.addExclude("IDBCursor", "continue");
+        config.addExclude("IDBCursor", "delete");
+        config.addExclude("IDBObjectStore", "delete");
+
+        // TODO method treated like field
+        config.addFieldExclude("Iterator", "next");
+        config.addExclude("Generator", "next");
+        config.addExclude("LinkStyle", "sheet");
+
+        // SVG
+        config.addExclude("SVGStylable", "className");
+        config.addExclude("SVGStylable", "style");
+        config.addExclude("SVGLocatable", "farthestViewportElement");
+        config.addExclude("SVGLocatable", "nearestViewportElement");
+
+        // jQuery XXX (these will need to be defined in some config when we get external libs
+        // working correctly with EXTERNC)
+        config.addClassToFunction("$");
+
+        config.addExclude("jQuery", "is");
+        config.addExclude("jQuery", "promise");
+        config.addExclude("jQuery", "getJSON");
+        config.addExclude("jQuery", "ajax");
+        config.addExclude("jQuery", "when");
+        config.addExclude("jQuery", "post");
+        config.addExclude("jQuery", "getScript");
+        config.addExclude("jQuery", "Callbacks");
+
+        config.addClassExclude("Deferred");
+        config.addClassExclude("jQuery.deferred");
+        config.addClassExclude("jQuery.Event");
+        config.addClassExclude("jQuery.Deferred");
+        config.addClassExclude("$.Event");
+        config.addClassExclude("$.Deferred");
+        config.addClassExclude("$.deferred");
+    }
+
+    public static void addTestExternalsFull(ExternCConfiguration config)
+            throws IOException
+    {
+        String coreRoot = ExternalsTestUtils.EXTERNAL_JS_DIR.getAbsolutePath();
+
+        config.addExternal(ExternalsTestUtils.MISSING_JS_FILE);
+        config.addExternal(coreRoot + "/es3.js");
+        config.addExternal(coreRoot + "/es5.js");
+        config.addExternal(coreRoot + "/es6.js");
+
+        config.addExternal(coreRoot + "/browser/w3c_anim_timing.js");
+        config.addExternal(coreRoot + "/browser/w3c_audio.js");
+        config.addExternal(coreRoot + "/browser/w3c_batterystatus.js");
+        config.addExternal(coreRoot + "/browser/w3c_css.js");
+        config.addExternal(coreRoot + "/browser/w3c_css3d.js");
+        config.addExternal(coreRoot + "/browser/w3c_device_sensor_event.js");
+        config.addExternal(coreRoot + "/browser/w3c_dom1.js");
+        config.addExternal(coreRoot + "/browser/w3c_dom2.js");
+        config.addExternal(coreRoot + "/browser/w3c_dom3.js");
+        config.addExternal(coreRoot + "/browser/w3c_elementtraversal.js");
+        config.addExternal(coreRoot + "/browser/w3c_encoding.js");
+        config.addExternal(coreRoot + "/browser/w3c_event.js");
+        config.addExternal(coreRoot + "/browser/w3c_event3.js");
+        config.addExternal(coreRoot + "/browser/w3c_geolocation.js");
+        config.addExternal(coreRoot + "/browser/w3c_indexeddb.js");
+        config.addExternal(coreRoot + "/browser/w3c_navigation_timing.js");
+        config.addExternal(coreRoot + "/browser/w3c_range.js");
+        config.addExternal(coreRoot + "/browser/w3c_rtc.js");
+        config.addExternal(coreRoot + "/browser/w3c_selectors.js");
+        //model.addExternal(coreRoot + "/w3c_serviceworker.js");
+        //model.addExternal(coreRoot + "/w3c_webcrypto.js");
+        config.addExternal(coreRoot + "/browser/w3c_xml.js");
+
+        //model.addExternal(coreRoot + "/fetchapi");
+
+        config.addExternal(coreRoot + "/browser/window.js");
+
+        config.addExternal(coreRoot + "/browser/ie_dom.js");
+        config.addExternal(coreRoot + "/browser/gecko_dom.js");
+
+        config.addExternal(coreRoot + "/browser/webkit_css.js");
+        config.addExternal(coreRoot + "/browser/webkit_dom.js");
+        config.addExternal(coreRoot + "/browser/webkit_event.js");
+        //model.addExternal(coreRoot + "/webkit_notifications.js");
+
+        config.addExternal(coreRoot + "/browser/iphone.js");
+        config.addExternal(coreRoot + "/browser/chrome.js");
+        config.addExternal(coreRoot + "/browser/flash.js");
+
+        config.addExternal(coreRoot + "/browser/page_visibility.js");
+        config.addExternal(coreRoot + "/browser/fileapi.js");
+        config.addExternal(coreRoot + "/browser/html5.js");
+
+        config.addExternal(coreRoot + "/browser/webgl.js");
+        config.addExternal(coreRoot + "/browser/webstorage.js");
+
+        config.addExternal(coreRoot + "/svg.js");
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestAnnotationEnum.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestAnnotationEnum.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestAnnotationEnum.java
new file mode 100644
index 0000000..124e3ff
--- /dev/null
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestAnnotationEnum.java
@@ -0,0 +1,82 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.externals;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import org.apache.flex.compiler.clients.ExternCConfiguration;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ClassReference;
+import org.junit.Test;
+
+public class TestAnnotationEnum extends ExternalsTestBase
+{
+    @Test
+    public void test_class_creation() throws IOException
+    {
+        compile("annotation_enum.js");
+
+        ClassReference FontFaceLoadStatus = model.getClassReference("FontFaceLoadStatus");
+        ClassReference FontFaceSetLoadStatus = model.getClassReference("FontFaceSetLoadStatus");
+        assertNotNull(FontFaceLoadStatus);
+        assertNotNull(FontFaceSetLoadStatus);
+
+        assertTrue(FontFaceLoadStatus.hasStaticField("ERROR"));
+        assertTrue(FontFaceLoadStatus.hasStaticField("LOADED"));
+        assertTrue(FontFaceLoadStatus.hasStaticField("LOADING"));
+        assertTrue(FontFaceLoadStatus.hasStaticField("UNLOADED"));
+
+        assertTrue(FontFaceSetLoadStatus.hasStaticField("FOO_LOADED"));
+        assertTrue(FontFaceSetLoadStatus.hasStaticField("FOO_LOADING"));
+
+        assertTrue(FontFaceLoadStatus.getStaticField("ERROR").isConst());
+
+        // TODO check values and value type IE String, Number
+
+        //String emit1 = client.getEmitter().emit(FontFaceLoadStatus);
+        //String emit2 = client.getEmitter().emit(FontFaceSetLoadStatus);
+    }
+
+    @Test
+    public void test_qualified_enum() throws IOException
+    {
+        compile("annotation_enum.js");
+
+        ClassReference QualifiedEnum = model.getClassReference("foo.bar.baz.QualifiedEnum");
+        assertNotNull(QualifiedEnum);
+        assertEquals("foo.bar.baz.QualifiedEnum",
+                QualifiedEnum.getQualifiedName());
+        assertEquals("foo.bar.baz", QualifiedEnum.getPackageName());
+        assertEquals("QualifiedEnum", QualifiedEnum.getBaseName());
+
+        assertTrue(QualifiedEnum.hasStaticField("One"));
+        assertTrue(QualifiedEnum.hasStaticField("Two"));
+
+        //String emit1 = client.getEmitter().emit(QualifiedEnum);
+    }
+
+    @Override
+    protected void configure(ExternCConfiguration config) throws IOException
+    {
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestCollectImports.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestCollectImports.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestCollectImports.java
new file mode 100644
index 0000000..a7ab2b8
--- /dev/null
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestCollectImports.java
@@ -0,0 +1,221 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.externals;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.apache.flex.compiler.clients.ExternCConfiguration;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ClassReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.FunctionReference;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class TestCollectImports extends ExternalsTestBase
+{
+    private static final String IMPORTS_TEST_DIR = "imports/";
+
+    private Boolean excludeClass;
+
+    @Parameterized.Parameters
+    public static Collection<Object[]> excludeClassYesNo()
+    {
+        return Arrays.asList(new Object[][] { { true }, { false } });
+    }
+
+    public TestCollectImports(final Boolean excludeClass)
+    {
+        this.excludeClass = excludeClass;
+    }
+
+    @Test
+    public void import_constructor_signatures() throws Exception
+    {
+        if (excludeClass)
+        {
+            config.addClassExclude("foo.Baz");
+        }
+
+        assertCompileTestFileSuccess(IMPORTS_TEST_DIR);
+
+        //client.emit();
+
+        ClassReference importConstructorSignature = model.getClassReference("ImportConstructorSignature");
+        assertNotNull(importConstructorSignature);
+
+        assertFalse(importConstructorSignature.hasImport("Number"));
+        assertFalse(importConstructorSignature.hasImport("foo.Qux"));
+
+        assertTrue(importConstructorSignature.hasImport("foo.Bar"));
+
+        if (excludeClass)
+        {
+            assertFalse(importConstructorSignature.hasImport("foo.Baz"));
+        }
+        else
+        {
+            assertTrue(importConstructorSignature.hasImport("foo.Baz"));
+        }
+    }
+
+    @Test
+    public void import_method_signatures() throws Exception
+    {
+        if (excludeClass)
+        {
+            config.addClassExclude("foo.Qux");
+        }
+
+        assertCompileTestFileSuccess(IMPORTS_TEST_DIR);
+
+        //client.emit();
+
+        ClassReference importMethodSignature = model.getClassReference("ImportMethodSignature");
+        assertNotNull(importMethodSignature);
+
+        assertFalse(importMethodSignature.hasImport("Number"));
+        assertFalse(importMethodSignature.hasImport("foo.Quux"));
+        assertFalse(importMethodSignature.hasImport("foo.Quuux"));
+
+        assertTrue(importMethodSignature.hasImport("foo.Bar"));
+        assertTrue(importMethodSignature.hasImport("foo.Baz"));
+
+        if (excludeClass)
+        {
+            assertFalse(importMethodSignature.hasImport("foo.Qux"));
+        }
+        else
+        {
+            assertTrue(importMethodSignature.hasImport("foo.Qux"));
+        }
+    }
+
+    @Test
+    public void import_interfaces() throws Exception
+    {
+        if (excludeClass)
+        {
+            config.addClassExclude("API.foo.Baz");
+        }
+
+        assertCompileTestFileSuccess(IMPORTS_TEST_DIR);
+
+        //client.emit();
+
+        ClassReference importInterfaces = model.getClassReference("ImportInterfaces");
+        assertNotNull(importInterfaces);
+
+        assertFalse(importInterfaces.hasImport("qux"));
+        assertTrue(importInterfaces.hasImport("API.Foo"));
+
+        ClassReference apiFoo = model.getClassReference("API.Foo");
+        assertNotNull(apiFoo);
+
+        assertFalse(apiFoo.hasImport("qux"));
+        assertFalse(apiFoo.hasImport("API.Bar"));
+
+        if (excludeClass)
+        {
+            assertFalse(apiFoo.hasImport("API.foo.Baz"));
+        }
+        else
+        {
+            assertTrue(apiFoo.hasImport("API.foo.Baz"));
+        }
+    }
+
+    @Test
+    public void import_superclasses() throws Exception
+    {
+        if (excludeClass)
+        {
+            config.addClassExclude("BASE.Foo");
+        }
+
+        assertCompileTestFileSuccess(IMPORTS_TEST_DIR);
+
+        //client.emit();
+
+        ClassReference importSuperClass1 = model.getClassReference("ImportSuperClass1");
+        assertNotNull(importSuperClass1);
+
+        assertFalse(importSuperClass1.hasImport("qux"));
+
+        ClassReference importSuperClass2 = model.getClassReference("ImportSuperClass2");
+        assertNotNull(importSuperClass2);
+
+        if (excludeClass)
+        {
+            assertFalse(importSuperClass2.hasImport("BASE.Foo"));
+        }
+        else
+        {
+            assertTrue(importSuperClass2.hasImport("BASE.Foo"));
+        }
+
+        ClassReference foo = model.getClassReference("BASE.Foo");
+        assertNotNull(foo);
+
+        assertFalse(foo.hasImport("BASE.Bar"));
+    }
+
+    @Test
+    public void import_functions() throws Exception
+    {
+        if (excludeClass)
+        {
+            config.addClassExclude("foo.Qux");
+        }
+
+        assertCompileTestFileSuccess(IMPORTS_TEST_DIR);
+
+        //client.emit();
+
+        FunctionReference importFunction = (FunctionReference) model.getFunctions().toArray()[0];
+        assertNotNull(importFunction);
+        assertTrue(importFunction.getQualifiedName().equals("ImportFunction"));
+
+        assertFalse(importFunction.hasImport("Quux"));
+
+        assertTrue(importFunction.hasImport("foo.Bar"));
+        assertTrue(importFunction.hasImport("foo.Baz"));
+
+        if (excludeClass)
+        {
+            assertFalse(importFunction.hasImport("foo.Qux"));
+        }
+        else
+        {
+            assertTrue(importFunction.hasImport("foo.Qux"));
+        }
+    }
+
+    @Override
+    protected void configure(ExternCConfiguration config) throws IOException
+    {
+        //config.setASRoot(ExternalsTestUtils.AS_ROOT_DIR);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestConstructor.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestConstructor.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestConstructor.java
new file mode 100644
index 0000000..a766576
--- /dev/null
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestConstructor.java
@@ -0,0 +1,119 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.externals;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import org.apache.flex.compiler.clients.ExternCConfiguration;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ClassReference;
+import org.junit.Test;
+
+public class TestConstructor extends ExternalsTestBase
+{
+
+    @Test
+    public void test_const_object_literal() throws IOException
+    {
+        compile("constructor_params.js");
+
+        assertTrue(model.hasClass("FinalClass"));
+        //assertTrue(model.getClassReference("FinalClass").isFinal());
+        assertTrue(model.getClassReference("FinalClass").hasStaticMethod("bar"));
+        assertTrue(model.getClassReference("FinalClass").getStaticMethod("bar").isStatic());
+    }
+
+    @Test
+    public void test_constructor_args() throws IOException
+    {
+        compile("constructor_params.js");
+
+        ClassReference FooNoArgs = model.getClassReference("FooNoArgs");
+        ClassReference FooOptArgs = model.getClassReference("FooOptArgs");
+        ClassReference FooVarArgs = model.getClassReference("FooVarArgs");
+        ClassReference FooOptVarArgs = model.getClassReference("FooOptVarArgs");
+
+        assertNotNull(FooNoArgs.getConstructor());
+        assertNotNull(FooOptArgs.getConstructor());
+        assertNotNull(FooVarArgs.getConstructor());
+        assertNotNull(FooOptVarArgs.getConstructor());
+
+        assertEquals(0, FooNoArgs.getConstructor().getParameterNames().size());
+        assertEquals(2, FooOptArgs.getConstructor().getParameterNames().size());
+        assertEquals(2, FooVarArgs.getConstructor().getParameterNames().size());
+        assertEquals(3,
+                FooOptVarArgs.getConstructor().getParameterNames().size());
+
+        assertFalse(FooOptArgs.getConstructor().getComment().getParameterType(
+                "arg1").isOptionalArg());
+        assertTrue(FooOptArgs.getConstructor().getComment().getParameterType(
+                "opt_arg2").isOptionalArg());
+
+        assertFalse(FooVarArgs.getConstructor().getComment().getParameterType(
+                "arg1").isVarArgs());
+        assertTrue(FooVarArgs.getConstructor().getComment().getParameterType(
+                "var_args").isVarArgs());
+
+        assertTrue(FooOptVarArgs.getConstructor().getComment().getParameterType(
+                "opt_arg2").isOptionalArg());
+        assertTrue(FooOptVarArgs.getConstructor().getComment().getParameterType(
+                "var_args").isVarArgs());
+
+        assertEquals(
+                "number",
+                evaluateParam(FooOptVarArgs.getConstructor(), "arg1").toAnnotationString());
+        assertEquals(
+                "*",
+                evaluateParam(FooOptVarArgs.getConstructor(), "opt_arg2").toAnnotationString());
+        assertEquals(
+                "*",
+                evaluateParam(FooOptVarArgs.getConstructor(), "var_args").toAnnotationString());
+    }
+
+    @Test
+    public void test_constructor_comment() throws IOException
+    {
+        compile("constructor_params.js");
+
+        StringBuilder sb = new StringBuilder();
+
+        ClassReference FooOptVarArgs = model.getClassReference("FooOptVarArgs");
+        FooOptVarArgs.getConstructor().emit(sb);
+        String string = sb.toString();
+        assertEquals(
+                "    /**\n     * A constructor with arg, opt arg and var args.\n     *\n     "
+                        + "* @param arg1 [number] The arg 1.\n     * @param opt_arg2 [*] The arg  "
+                        + "that is wrapped by another line in the comment.\n     * @param var_args "
+                        + "[*] A var agr param.\n     * @see http://foo.bar.com \n     * @see "
+                        + "[constructor_params]\n     * @returns {(FooVarArgs|null)} Another instance.\n"
+                        + "     */\n    public function FooOptVarArgs(arg1:Number, opt_arg2:* = null, ...var_args) "
+                        + "{\n        super();\n    }\n", string);
+    }
+
+    @Override
+    protected void configure(ExternCConfiguration config) throws IOException
+    {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestExternChrome.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestExternChrome.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestExternChrome.java
new file mode 100644
index 0000000..51afce9
--- /dev/null
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestExternChrome.java
@@ -0,0 +1,153 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.externals;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import org.apache.flex.compiler.clients.ExternCConfiguration;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ClassReference;
+import org.junit.Test;
+
+import com.google.javascript.jscomp.Result;
+
+public class TestExternChrome extends ExternalsTestBase
+{
+    @Test
+    public void test_classes() throws IOException
+    {
+        client.cleanOutput();
+        Result result = compile();
+        assertTrue(result.success);
+
+        String[] classes = {
+                "chrome",
+                "chrome.app",
+                "chrome.webstore",
+                "chrome.runtime",
+                "chrome.runtime.lastError",
+
+                "Port",
+                "ChromeEvent",
+                "ChromeStringEvent",
+                "ChromeBooleanEvent",
+                "ChromeNumberEvent",
+                "ChromeObjectEvent",
+                "ChromeStringArrayEvent",
+                "ChromeStringStringEvent",
+                "MessageSender",
+                "Tab",
+                "ChromeLoadTimes",
+                "ChromeCsiInfo" };
+
+        assertEquals(17, model.getClasses().size());
+        for (String className : classes)
+        {
+            assertTrue(model.hasClass(className));
+        }
+
+        client.emit();
+    }
+
+    @Test
+    public void test_members() throws IOException
+    {
+        client.cleanOutput();
+        Result result = compile();
+        assertTrue(result.success);
+
+        // Port
+        ClassReference Port = model.getClassReference("Port");
+        assertNotNull(Port);
+        assertTrue(Port.hasInstanceField("name"));
+        assertTrue(Port.hasInstanceField("onDisconnect"));
+        assertTrue(Port.hasInstanceField("onMessage"));
+        assertTrue(Port.hasInstanceField("sender"));
+
+        assertTrue(Port.hasInstanceMethod("postMessage"));
+        assertTrue(Port.hasInstanceMethod("disconnect"));
+
+        assertEquals("string", Port.getInstanceField("name").toTypeAnnotationString());
+        assertEquals("ChromeEvent",
+                Port.getInstanceField("onDisconnect").toTypeAnnotationString());
+        assertEquals("ChromeEvent",
+                Port.getInstanceField("onMessage").toTypeAnnotationString());
+        assertEquals("(MessageSender|undefined)",
+                Port.getInstanceField("sender").toTypeAnnotationString());
+
+        // chrome
+        ClassReference chrome = model.getClassReference("chrome");
+        assertNotNull(chrome);
+        assertTrue(chrome.hasStaticMethod("loadTimes"));
+        assertTrue(chrome.hasStaticMethod("csi"));
+        assertEquals("ChromeLoadTimes",
+                chrome.getStaticMethod("loadTimes").toReturnTypeAnnotationString());
+        assertEquals("ChromeCsiInfo",
+                chrome.getStaticMethod("csi").toReturnTypeAnnotationString());
+
+        // chrome.app
+        ClassReference chrome_app = model.getClassReference("chrome.app");
+        assertNotNull(chrome_app);
+        assertTrue(chrome_app.hasStaticField("isInstalled"));
+        assertEquals("boolean",
+                chrome_app.getStaticField("isInstalled").toTypeAnnotationString());
+
+        // chrome.runtime
+        ClassReference chrome_runtime = model.getClassReference("chrome.runtime");
+        assertNotNull(chrome_runtime);
+        assertTrue(chrome_runtime.hasStaticMethod("connect"));
+        assertTrue(chrome_runtime.hasStaticMethod("sendMessage"));
+
+        // chrome.runtime.lastError
+        ClassReference chrome_runtime_lastError = model.getClassReference("chrome.runtime.lastError");
+        assertNotNull(chrome_runtime_lastError);
+        assertTrue(chrome_runtime_lastError.hasStaticField("message"));
+        assertEquals(
+                "(string|undefined)",
+                chrome_runtime_lastError.getStaticField("message").toTypeAnnotationString());
+
+        // chrome.webstore
+        ClassReference chrome_webstore = model.getClassReference("chrome.webstore");
+        assertNotNull(chrome_webstore);
+        assertTrue(chrome_webstore.hasStaticField("onInstallStageChanged"));
+        assertTrue(chrome_webstore.hasStaticField("onDownloadProgress"));
+        assertTrue(chrome_webstore.hasStaticMethod("install"));
+
+        // Code generated
+        assertTrue(chrome.hasStaticField("app"));
+        assertTrue(chrome.hasStaticField("runtime"));
+        assertTrue(chrome.hasStaticField("webstore"));
+
+        assertTrue(chrome_runtime.hasInstanceField("lastError"));
+    }
+
+    @Override
+    protected void configure(ExternCConfiguration install) throws IOException
+    {
+        config.setASRoot(ExternalsTestUtils.AS_ROOT_DIR);
+
+        String coreRoot = ExternalsTestUtils.EXTERNAL_JS_DIR.getAbsolutePath();
+        config.addExternal(coreRoot + "/browser/chrome.js");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestExternES3.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestExternES3.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestExternES3.java
new file mode 100644
index 0000000..29ac6fb
--- /dev/null
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestExternES3.java
@@ -0,0 +1,122 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.externals;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import org.apache.flex.compiler.clients.ExternCConfiguration;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ClassReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.MethodReference;
+import org.junit.Test;
+
+import com.google.javascript.jscomp.Result;
+
+public class TestExternES3 extends ExternalsTestBase
+{
+    @Test
+    public void test_classes() throws IOException
+    {
+        Result result = compile();
+        assertTrue(result.success);
+
+        String[] classes = {
+                "Arguments",
+                "Object",
+                "Function",
+                "Array",
+                "Boolean",
+                "Number",
+                "Date",
+                "String",
+                "RegExp",
+                "Error",
+                "EvalError",
+                "RangeError",
+                "ReferenceError",
+                "SyntaxError",
+                "TypeError",
+                "URIError",
+                "Math" };
+
+        // IObject and IArrayLike are two extras
+        assertEquals(19, model.getClasses().size());
+        for (String className : classes)
+        {
+            assertTrue(model.hasClass(className));
+        }
+    }
+
+    @Test
+    public void test_Object() throws IOException
+    {
+        Result result = compile();
+        assertTrue(result.success);
+
+        ClassReference Object = model.getClassReference("Object");
+        assertNotNull(Object);
+        assertTrue(Object.isDynamic());
+    }
+
+    @Test
+    public void test_Array() throws IOException
+    {
+        Result result = compile();
+        assertTrue(result.success);
+
+        ClassReference Array = model.getClassReference("Array");
+        assertNotNull(Array);
+
+        MethodReference constructor = Array.getConstructor();
+        StringBuilder sb = new StringBuilder();
+        constructor.emitCode(sb);
+        String emit = sb.toString();
+        assertEquals("    public function Array(...var_args):Array {  return null; }\n", emit);
+    }
+
+    @Test
+    public void test_Array_indexOf() throws IOException
+    {
+        Result result = compile();
+        assertTrue(result.success);
+
+        ClassReference Array = model.getClassReference("Array");
+        assertNotNull(Array);
+
+        MethodReference indexOf = Array.getInstanceMethod("indexOf");
+        StringBuilder sb = new StringBuilder();
+        indexOf.emitCode(sb);
+        String emit = sb.toString();
+        assertEquals("    public function indexOf(obj:Object, opt_fromIndex:Number = 0):Number { return 0; }\n", emit);
+    }
+
+    @Override
+    protected void configure(ExternCConfiguration config) throws IOException
+    {
+        config.setASRoot(ExternalsTestUtils.AS_ROOT_DIR);
+
+        String coreRoot = ExternalsTestUtils.EXTERNAL_JS_DIR.getAbsolutePath();
+        config.addExternal(coreRoot + "/es3.js");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestExternJQuery.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestExternJQuery.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestExternJQuery.java
new file mode 100644
index 0000000..7a2c1d0
--- /dev/null
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestExternJQuery.java
@@ -0,0 +1,67 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.externals;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import org.apache.flex.compiler.clients.ExternCConfiguration;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ClassReference;
+import org.junit.Test;
+
+import com.google.javascript.jscomp.Result;
+
+public class TestExternJQuery extends ExternalsTestBase
+{
+    @SuppressWarnings("unused")
+    @Test
+    public void test_classes() throws IOException
+    {
+        Result result = compile();
+        assertTrue(result.success);
+
+        //        String[] classes = {};
+        //
+        //        assertEquals(17, model.getClasses().size());
+        //        for (String className : classes)
+        //        {
+        //            assertTrue(model.hasClass(className));
+        //        }
+
+        ClassReference jQuery_Promise = model.getInterfaceReference("jQuery.Promise");
+        assertNotNull(jQuery_Promise);
+
+        StringBuilder sb = new StringBuilder();
+        jQuery_Promise.emit(sb);
+        String r = sb.toString();
+    }
+
+    @Override
+    protected void configure(ExternCConfiguration config) throws IOException
+    {
+        config.setASRoot(ExternalsTestUtils.AS_ROOT_DIR);
+
+        String coreRoot = ExternalsTestUtils.EXTERNAL_JQUERY_DIR.getAbsolutePath();
+        config.addExternal(coreRoot + "/jquery-1.9.js");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestExternJasmine.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestExternJasmine.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestExternJasmine.java
new file mode 100644
index 0000000..9e2c805
--- /dev/null
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestExternJasmine.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 org.apache.flex.compiler.internal.codegen.externals;
+
+import com.google.javascript.jscomp.Result;
+import org.apache.flex.compiler.clients.ExternCConfiguration;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ClassReference;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.*;
+
+public class TestExternJasmine extends ExternalsTestBase
+{
+    @Test
+    public void test_classes() throws IOException
+    {
+        client.cleanOutput();
+        Result result = compile();
+        assertTrue(result.success);
+
+        String[] classes = {
+                "jasmine",
+                "jasmine.Clock"};
+
+        assertEquals(9, model.getClasses().size());
+        for (String className : classes)
+        {
+            assertTrue(model.hasClass(className));
+        }
+
+        client.emit();
+    }
+
+    @Test
+    public void test_members() throws IOException
+    {
+        client.cleanOutput();
+        Result result = compile();
+        assertTrue(result.success);
+
+        // jasmine
+        ClassReference jasmine = model.getClassReference("jasmine");
+        assertNotNull(jasmine);
+
+        assertTrue(jasmine.hasStaticMethod("clock"));
+        assertEquals("jasmine.Clock", jasmine.getStaticMethod("clock").toReturnTypeAnnotationString());
+
+        assertTrue(jasmine.hasImport("jasmine.Clock"));
+
+        //Clock
+        ClassReference Clock = model.getClassReference("jasmine.Clock");
+        assertNotNull(Clock);
+    }
+
+    @Override
+    protected void configure(ExternCConfiguration install) throws IOException
+    {
+        config.setASRoot(ExternalsTestUtils.AS_ROOT_DIR);
+
+        String coreRoot = ExternalsTestUtils.EXTERNAL_JASMINE_DIR.getAbsolutePath();
+        config.addExternal(coreRoot + "/jasmine-2.0.js");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestExternalsJSCompile.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestExternalsJSCompile.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestExternalsJSCompile.java
new file mode 100644
index 0000000..feff678
--- /dev/null
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestExternalsJSCompile.java
@@ -0,0 +1,287 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.externals;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.flex.compiler.clients.COMPC;
+import org.apache.flex.compiler.clients.EXTERNC;
+import org.apache.flex.compiler.clients.ExternCConfiguration;
+import org.apache.flex.compiler.codegen.as.IASEmitter;
+import org.apache.flex.compiler.config.Configurator;
+import org.apache.flex.compiler.internal.codegen.as.ASFilterWriter;
+import org.apache.flex.compiler.internal.driver.js.flexjs.FlexJSBackend;
+import org.apache.flex.compiler.internal.projects.FlexJSProject;
+import org.apache.flex.compiler.internal.projects.FlexProjectConfigurator;
+import org.apache.flex.compiler.internal.targets.JSTarget;
+import org.apache.flex.compiler.internal.workspaces.Workspace;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.units.ICompilationUnit;
+import org.apache.flex.compiler.visitor.as.IASBlockWalker;
+import org.apache.flex.utils.FilenameNormalization;
+import org.apache.flex.utils.ITestAdapter;
+import org.apache.flex.utils.TestAdapterFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
+public class TestExternalsJSCompile
+{
+    private static ITestAdapter testAdapter = TestAdapterFactory.getTestAdapter();
+
+    private static File tempDir = new File(testAdapter.getTempDir());
+
+    private static File app1ASSrcDir = new File(testAdapter.getUnitTestBaseDir(), "externals/app1/as_src");
+
+    private static File app1AJSSrcDir = new File(testAdapter.getTempDir(), "externals/app1/js_src");
+
+    private static File jsSWCFile = new File(testAdapter.getTempDir(), "externals/bin/JS.swc");
+
+    protected static Workspace workspace = new Workspace();
+    protected FlexJSProject project;
+    private ArrayList<ICompilerProblem> errors;
+
+    private FlexJSBackend backend;
+    //private IJSEmitter emitter;
+    //private IASBlockWalker walker;
+    //private JSFilterWriter writer;
+
+    private ArrayList<File> sourcePaths;
+    private ArrayList<File> libraries;
+
+    private EXTERNC client;
+
+    private ExternCConfiguration config;
+
+    @Before
+    public void setUp() throws IOException
+    {
+        backend = new FlexJSBackend();
+
+        config = new ExternCConfiguration();
+        config.setASRoot(ExternalsTestUtils.AS_ROOT_DIR);
+        ExternalsTestUtils.addTestExcludesFull(config);
+        ExternalsTestUtils.addTestExternalsFull(config);
+
+        client = new EXTERNC(config);
+
+        if (project == null)
+            project = new FlexJSProject(workspace);
+        FlexProjectConfigurator.configure(project);
+
+        backend = new FlexJSBackend();
+        //writer = backend.createWriterBuffer(project);
+        //emitter = backend.createEmitter(writer);
+        //walker = backend.createWalker(project, errors, emitter);
+
+        sourcePaths = new ArrayList<File>();
+        libraries = new ArrayList<File>();
+
+        FileUtils.deleteQuietly(jsSWCFile);
+        FileUtils.deleteQuietly(app1AJSSrcDir);
+    }
+
+    @After
+    public void tearDown()
+    {
+        client = null;
+    }
+
+    @Test
+    public void test_full_compile() throws IOException
+    {
+        client.cleanOutput();
+        client.compile();
+        client.emit();
+
+        compileSWC();
+        assertTrue(jsSWCFile.exists());
+
+        compileProject("Main", app1ASSrcDir.getAbsolutePath());
+
+        assertTrue(new File(app1AJSSrcDir, "Main_output.js").exists());
+    }
+
+    private boolean compileSWC()
+    {
+        CompilerArguments arguments = new CompilerArguments();
+        configureCOMPCCompiler(arguments);
+
+        File destAS3File = new File(config.getAsClassRoot().getAbsolutePath() + File.separator + "AS3.as");
+        try {
+			FileUtils.copyFile(ExternalsTestUtils.AS3_NAMESPACE_FILE, destAS3File);
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+        COMPC compc = new COMPC();
+
+        final String[] args = arguments.toArguments().toArray(new String[] {});
+        @SuppressWarnings("unused")
+        int code = compc.mainNoExit(args);
+
+        @SuppressWarnings("unused")
+        List<ICompilerProblem> problems = compc.getProblems().getProblems();
+        //getProblemQuery().addAll(problems);
+        if (compc.getProblems().hasErrors())
+            return false;
+
+        return true;
+    }
+
+    protected List<String> compileProject(String inputFileName,
+            String inputDirName)
+    {
+        List<String> compiledFileNames = new ArrayList<String>();
+
+        String mainFileName = inputDirName + File.separator + inputFileName
+                + ".as";
+
+        addDependencies();
+
+        ICompilationUnit mainCU = Iterables.getOnlyElement(workspace.getCompilationUnits(
+                FilenameNormalization.normalize(mainFileName), project));
+
+        if (project instanceof FlexJSProject)
+            project.mainCU = mainCU;
+
+        Configurator projectConfigurator = backend.createConfigurator();
+
+        JSTarget target = backend.createTarget(project,
+                projectConfigurator.getTargetSettings(null), null);
+
+        target.build(mainCU, new ArrayList<ICompilerProblem>());
+
+        List<ICompilationUnit> reachableCompilationUnits = project.getReachableCompilationUnitsInSWFOrder(ImmutableSet.of(mainCU));
+        for (final ICompilationUnit cu : reachableCompilationUnits)
+        {
+            try
+            {
+                ICompilationUnit.UnitType cuType = cu.getCompilationUnitType();
+
+                if (cuType == ICompilationUnit.UnitType.AS_UNIT
+                        || cuType == ICompilationUnit.UnitType.MXML_UNIT)
+                {
+                    File outputRootDir = new File(
+                            FilenameNormalization.normalize(tempDir
+                                    + File.separator + inputDirName));
+
+                    String qname = cu.getQualifiedNames().get(0);
+
+                    compiledFileNames.add(qname.replace(".", "/"));
+
+                    final File outputClassFile = getOutputClassFile(qname
+                            + "_output", outputRootDir);
+
+                    System.out.println(outputClassFile);
+
+                    ASFilterWriter writer = backend.createWriterBuffer(project);
+                    IASEmitter emitter = backend.createEmitter(writer);
+                    IASBlockWalker walker = backend.createWalker(project,
+                            errors, emitter);
+
+                    walker.visitCompilationUnit(cu);
+
+                    System.out.println(writer.toString());
+
+                    BufferedOutputStream out = new BufferedOutputStream(
+                            new FileOutputStream(outputClassFile));
+
+                    out.write(writer.toString().getBytes());
+                    out.flush();
+                    out.close();
+                }
+            }
+            catch (Exception e)
+            {
+                //System.out.println(e.getMessage());
+                e.printStackTrace();
+            }
+        }
+
+        return compiledFileNames;
+    }
+
+    private void configureCOMPCCompiler(CompilerArguments arguments)
+    {
+        arguments.setOutput(jsSWCFile.getAbsolutePath());
+
+        File classes = config.getAsClassRoot();
+        File interfaces = config.getAsInterfaceRoot();
+        File constants = config.getAsConstantRoot();
+        File functions = config.getAsFunctionRoot();
+        File typedefs = config.getAsTypeDefRoot();
+
+        arguments.addSourcepath(classes.getAbsolutePath());
+        arguments.addSourcepath(interfaces.getAbsolutePath());
+        arguments.addSourcepath(constants.getAbsolutePath());
+        arguments.addSourcepath(functions.getAbsolutePath());
+        arguments.addSourcepath(typedefs.getAbsolutePath());
+
+        arguments.addIncludedSources(classes.getAbsolutePath());
+        arguments.addIncludedSources(interfaces.getAbsolutePath());
+        arguments.addIncludedSources(constants.getAbsolutePath());
+        arguments.addIncludedSources(functions.getAbsolutePath());
+        arguments.addIncludedSources(typedefs.getAbsolutePath());
+    }
+
+    protected File getOutputClassFile(String qname, File outputFolder)
+    {
+        File baseDir = app1AJSSrcDir;
+
+        String[] cname = qname.split("\\.");
+        String sdirPath = baseDir.getAbsolutePath() + File.separator;
+        if (cname.length > 0)
+        {
+            for (int i = 0, n = cname.length - 1; i < n; i++)
+            {
+                sdirPath += cname[i] + File.separator;
+            }
+
+            File sdir = new File(sdirPath);
+            if (!sdir.exists())
+                sdir.mkdirs();
+
+            qname = cname[cname.length - 1];
+        }
+
+        return new File(sdirPath + qname + "." + backend.getOutputExtension());
+    }
+
+    private void addDependencies()
+    {
+        libraries.add(jsSWCFile);
+        sourcePaths.add(app1ASSrcDir);
+
+        project.setSourcePath(sourcePaths);
+        project.setLibraries(libraries);
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestPackageNamespace.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestPackageNamespace.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestPackageNamespace.java
new file mode 100644
index 0000000..c00d00b
--- /dev/null
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/TestPackageNamespace.java
@@ -0,0 +1,63 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.flex.compiler.internal.codegen.externals;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import org.apache.flex.compiler.clients.ExternCConfiguration;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ClassReference;
+import org.junit.Test;
+
+public class TestPackageNamespace extends ExternalsTestBase
+{
+    @Test
+    public void test_pacakge1() throws IOException
+    {
+        compile("package_namespace.js");
+
+        ClassReference reference1 = model.getClassReference("Foo");
+        ClassReference reference2 = model.getClassReference("foo.bar.Baz");
+        ClassReference reference3 = model.getClassReference("Goo");
+
+        assertFalse(reference1.isQualifiedName());
+        assertEquals("Foo", reference1.getBaseName());
+        assertEquals("", reference1.getPackageName());
+        assertEquals("Foo", reference1.getQualifiedName());
+
+        assertTrue(reference2.isQualifiedName());
+        assertEquals("Baz", reference2.getBaseName());
+        assertEquals("foo.bar", reference2.getPackageName());
+        assertEquals("foo.bar.Baz", reference2.getQualifiedName());
+
+        assertFalse(reference3.isQualifiedName());
+        assertEquals("Goo", reference3.getBaseName());
+        assertEquals("", reference3.getPackageName());
+        assertEquals("Goo", reference3.getQualifiedName());
+    }
+
+    @Override
+    protected void configure(ExternCConfiguration config)
+    {
+    }
+
+}